ДПФ к пространственной области в OpenCV не работает - PullRequest
4 голосов
/ 10 марта 2012

Я создал dft изображения, и после некоторой корректировки с помощью фильтров я хочу преобразовать его обратно в реальное изображение, но каждый раз, когда я делаю это, он дает мне неправильный результат .. похоже, что он не конвертирует его обратно.ForierTransform и createGaussianHighPassFilter - мои собственные функции, остальной код, который я использую, как показано ниже для инверсии обратно в реальное изображение.

Mat fft = ForierTransform(HeightPadded,WidthPadded);
Mat ghpf = createGaussianHighPassFilter(Size(WidthPadded, HeightPadded), db);
Mat res;
cv::multiply(fft,ghpf,res);
imshow("fftXhighpass1", res);
idft(res,res,DFT_INVERSE,res.rows);
cv::Mat croped = res(cv::Rect(0, 0, img.cols,img.rows));

//res.convertTo(res,CV_32S);
imshow("fftXhighpass", res);

, даже если я не применяю фильтр, я не могу вернуться назадрезультат dft ... вот мой код dft, я не смог найти ни одного образца, чтобы вернуть dft обратно к нормальному изображению ..

Mat ForierTransform(int M,int N)
{
    Mat img = imread("thumb1-small-test.jpg", CV_LOAD_IMAGE_GRAYSCALE);
    Mat padded;
    copyMakeBorder(img, padded, 0, M - img.rows, 0, N - img.cols, BORDER_CONSTANT, Scalar::all(0));

    Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
    Mat complexImg;
    merge(planes, 2, complexImg);

    dft(complexImg, complexImg);


    split(complexImg, planes);
    magnitude(planes[0], planes[1], planes[0]);
    Mat mag = planes[0];
    mag += Scalar::all(1);
    log(mag, mag);

        // crop the spectrum, if it has an odd number of rows or columns
    mag = mag(Rect(0, 0, mag.cols & -2, mag.rows & -2));


    normalize(mag, mag, 0, 1, CV_MINMAX);
    return mag;
}

любезно помогите

[РЕДАКТИРОВАТЬ: После того как я нашелрешение с помощью меватрона] (ниже приведен правильный код)

 Mat ForierTransform(int M,int N)
{
    Mat img = imread("thumb1-small-test.jpg", CV_LOAD_IMAGE_GRAYSCALE);
    Mat padded;
    copyMakeBorder(img, padded, 0, M - img.rows, 0, N - img.cols, BORDER_CONSTANT, Scalar::all(0));

    Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
    Mat complexImg;
    merge(planes, 2, complexImg);

    dft(complexImg, complexImg);

    return complexImg;
}

Mat img = imread("thumb1-small-test.jpg",CV_LOAD_IMAGE_GRAYSCALE);
int WidthPadded=0,HeightPadded=0;
WidthPadded=img.cols*2;
HeightPadded=img.rows*2;
int M = getOptimalDFTSize( img.rows );
//Create a Gaussian Highpass filter 5% the height of the Fourier transform
double db  = 0.05 * HeightPadded;


Mat fft = ForierTransform(HeightPadded,WidthPadded);
Mat ghpf = createGaussianHighPassFilter(Size(WidthPadded, HeightPadded), db);
Mat res;

cv::mulSpectrums(fft,ghpf,res,DFT_COMPLEX_OUTPUT);


idft(res,res,DFT_COMPLEX_OUTPUT,img.rows);

Mat padded;
copyMakeBorder(img, padded, 0, img.rows, 0, img.cols, BORDER_CONSTANT, Scalar::all(0));
Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
split(res, planes);
magnitude(planes[0], planes[1], planes[0]);
Mat mag = planes[0];
mag += Scalar::all(1);
log(mag, mag);

// crop the spectrum, if it has an odd number of rows or columns
mag = mag(Rect(0, 0, mag.cols & -2, mag.rows & -2));

int cx = mag.cols/2;
int cy = mag.rows/2;

normalize(mag, mag, 1, 0, CV_MINMAX);

cv::Mat croped = mag(cv::Rect(cx, cy, img.cols,img.rows));
cv::threshold(croped , croped , 0.56, 1, cv::THRESH_BINARY);

imshow("fftPLUShpf", mag);
imshow("cropedBinary", croped);

Теперь он может отображать гребни долины пальца, а также может быть более оптимизирован по порогу

1 Ответ

3 голосов
/ 12 марта 2012

Я вижу, что здесь происходит несколько проблем.

Во-первых, вам нужно использовать функцию mulSpectrums для свертки двух БПФ, а не , умножить .

Во-вторых,createGaussianHighPassFilter выводит только одноканальный несложный фильтр.Вам, вероятно, нужно будет просто установить сложный канал на Mat::zeros, как вы сделали для входного изображения.

В-третьих, не конвертируйте выходные данные БПФ в спектр логарифмической величины.Он не будет правильно совмещаться с фильтром, и вы не получите то же самое при выполнении инверсии.Итак, просто верните complexImg сразу после выполнения DFT.Логарифмический спектр полезен для человека, чтобы посмотреть на данные, но не для того, что вы пытаетесь сделать.

Наконец, убедитесь, что вы обращаете внимание на разницу между полным комплексным выводом dft и комплексный сопряженный симметричный (CCS) упакованный вывод.У Intel есть хорошая страница о том, как эти данные отформатированы здесь .В вашем случае, для простоты, я бы держал все в полностью сложном режиме, чтобы облегчить вашу жизнь.

Надеюсь, это поможет!

...