Как применить фильтр Гаусса к выходу DFT в OpenCV - PullRequest
2 голосов
/ 06 марта 2012

Я хочу создать фильтр верхних частот Гаусса после определения правильного размера заполнения (например, если ширина и высота изображения равна 10X10, то должно быть 20X20).

У меня есть код Matlab, который я пытаюсь перенести в OpenCV, но у меня возникают трудности с его корректным переносом. Мой код Matlab показан ниже:

f1_seg = imread('thumb1-small-test.jpg');

Iori = f1_seg;


% Iori = imresize(Iori, 0.2);

%Convert to grayscale
I = Iori;
if length(size(I)) == 3
    I = rgb2gray(Iori);
end
% 

%Determine good padding for Fourier transform

PQ = paddedsize(size(I));

I = double(I);

%Create a Gaussian Highpass filter 5% the width of the Fourier transform

D0 = 0.05*PQ(1);

H = hpfilter('gaussian', PQ(1), PQ(2), D0);

% Calculate the discrete Fourier transform of the image.

F=fft2(double(I),size(H,1),size(H,2));

% Apply the highpass filter to the Fourier spectrum of the image

HPFS_I = H.*F;

Я знаю, как использовать DFT в OpenCV, и я могу сгенерировать его изображение, но я не уверен, как создать фильтр Гаусса. Пожалуйста, объясните мне, как я могу создать фильтр высоких частот Гаусса, как показано выше?

1 Ответ

8 голосов
/ 06 марта 2012

Я полагаю, что вы застряли в том, что фильтр Гаусса, предоставленный OpenCV, создается в пространственной (временной) области, но вы хотите фильтр в частотной области. Здесь - хорошая статья о разнице между фильтрацией верхних и нижних частот в частотной области.

Как только вы хорошо поймете, как работает фильтрация в частотной области, вы готовы попытаться создать фильтр Гаусса в частотной области. Здесь - хорошая лекция о создании нескольких различных (в том числе гауссовых) фильтров в частотной области.

Если у вас все еще проблемы, я постараюсь обновить мой пост с примером чуть позже!

РЕДАКТИРОВАТЬ: Вот короткий пример, который я написал о реализации фильтра высоких частот Гаусса (на основе лекции, на которую я вам указал):

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

#include <iostream>

using namespace cv;
using namespace std;

double pixelDistance(double u, double v)
{
    return cv::sqrt(u*u + v*v);
}

double gaussianCoeff(double u, double v, double d0)
{
    double d = pixelDistance(u, v);
    return 1.0 - cv::exp((-d*d) / (2*d0*d0));
}

cv::Mat createGaussianHighPassFilter(cv::Size size, double cutoffInPixels)
{
    Mat ghpf(size, CV_64F);

    cv::Point center(size.width / 2, size.height / 2);

    for(int u = 0; u < ghpf.rows; u++)
    {
        for(int v = 0; v < ghpf.cols; v++)
        {
            ghpf.at<double>(u, v) = gaussianCoeff(u - center.y, v - center.x, cutoffInPixels);
        }
    }

    return ghpf;
}


int main(int /*argc*/, char** /*argv*/)
{
    Mat ghpf = createGaussianHighPassFilter(Size(128, 128), 16.0);

    imshow("ghpf", ghpf);
    waitKey();

    return 0;
}

Это определенно не оптимизированный генератор фильтров, но я постарался сделать его простым и понятным, чтобы облегчить понимание :) В любом случае, этот код отображает следующий фильтр:

enter image description here

ПРИМЕЧАНИЕ: Этот фильтр не смещен по БПФ (т. Е. Этот фильтр работает, когда постоянный ток расположен в центре, а не в верхнем левом углу). См. Пример OpenCV dft.cpp (в частности, строки 62 - 74) о том, как выполнить БПФ-сдвиг в OpenCV.

Наслаждайтесь!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...