DFT in the spatial domain in OpenCV does not work

I created a dft image, and after some setup with filters, I want to convert it back to a real image, but every time I do this, it gives me the wrong result. It does not seem to convert it back. ForierTransform and createGaussianHighPassFilter are my own functions of the rest of the code, which I use, as shown below, to invert back to the real image.

 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); 

even if I donโ€™t apply the filter, I canโ€™t reverse the dft result ... here is my dft code, I couldnโ€™t find any pattern for returning back to the normal image.

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

kind help

[EDIT: after I found the solution using megatron] (below is the correct code)

  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); 

Now it can display the protrusions of the valley of the finger and can also be more optimized with respect to the threshold

+4
source share
1 answer

I see several problems here.

First, you need to use the mulSpectrums function to convolve two FFTs and not multiply .

Secondly, createGaussianHighPassFilter only displays a single-channel non- createGaussianHighPassFilter filter. You probably just need to set the complex channel to Mat::zeros in the same way as for your input image.

Third, do not convert the output of the FFT into a spectrum of a logarithmic value. It will not combine correctly with the filter, and you will not get the same when doing the opposite. So, return complexImg right after the DFT. The log-magnetic spectrum is useful for a person to look at the data, but not at what you are trying to do.

Finally, make sure you pay attention to the difference between the full complex output dft and the complex conjugate symmetric (CCS) packed output. Intel has a good page on how this data is formatted here . In your case, for simplicity, I would save everything in a difficult mode to make your life easier.

Hope this helps!

+3
source

Source: https://habr.com/ru/post/1400724/


All Articles