DFT в пространственный домен в OpenCV не работает

Я создал 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, я не смог найти какой-либо образец для обратного возврата обратно к нормальному изображению.

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;
}
</float>

любезная помощь

[EDIT: после того, как я нашел решение с помощью мегатрона] (ниже правильный код)

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
****** 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);
</float></float>

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

1 ответ

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

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

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

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

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

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

licensed under cc by-sa 3.0 with attribution.