#include "opencv2/core/core.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/highgui/highgui.hpp"
#include <iostream>
#include <stdlib.h>
#include <opencv2/opencv.hpp>
#include <stdio.h>
using namespace cv;
using namespace std;
Mat updateMag(Mat complex);
void updateResult(Mat complex);
Mat computeDFT(Mat image);
Mat createavg(Size imsize);
void shift(Mat magI);
int kernel_size = 0;
int r = 100;
int main( int argc, char** argv )
{
String file;
file = "lena.png";
Mat image = imread(file, CV_LOAD_IMAGE_GRAYSCALE);
namedWindow( "Orginal window", CV_WINDOW_AUTOSIZE );// Create a window for display.
imshow( "Orginal window", image ); // Show our image inside it.
Mat complex = computeDFT(image);
/*Mat temp=updateMag(complex);
namedWindow( "image fourier", CV_WINDOW_AUTOSIZE );
imshow("image fourier", temp);*/
namedWindow( "spectrum", CV_WINDOW_AUTOSIZE );
Mat mask = createavg(complex.size());
shift(mask);
//mask= computeDFT(mask); //Compute DFT of mask
//mask =updateMag(mask); //show the mask spectrum
imshow("gaus-mask", mask);
Mat planes[] = {Mat::zeros(complex.size(), CV_32F), Mat::zeros(complex.size(), CV_32F)};
Mat kernel_spec;
planes[0] = mask; // real
planes[1] = mask; // imaginar
merge(planes, 2, kernel_spec);
mulSpectrums(complex, kernel_spec, complex, DFT_ROWS);
Mat temp = updateMag(complex);
imshow("spectrum", temp);
// compute magnitude of complex, switch to logarithmic scale and display...
updateResult(complex); // do inverse transform and display the result image
waitKey(0);
return 0;
}
void updateResult(Mat complex)
{
Mat work;
idft(complex, work);
// dft(complex, work, DFT_INVERSE + DFT_SCALE);
Mat planes[] = {Mat::zeros(complex.size(), CV_32F), Mat::zeros(complex.size(), CV_32F)};
split(work, planes); // planes[0] = Re(DFT(I)), planes[1] = Im(DFT(I))
magnitude(planes[0], planes[1], work); // === sqrt(Re(DFT(I))^2 + Im(DFT(I))^2)
normalize(work, work, 0, 1, NORM_MINMAX);
imshow("result", work);
}
Mat updateMag(Mat complex )
{
Mat magI;
Mat planes[] = {Mat::zeros(complex.size(), CV_32F), Mat::zeros(complex.size(), CV_32F)};
split(complex, planes); // planes[0] = Re(DFT(I)), planes[1] = Im(DFT(I))
magnitude(planes[0], planes[1], magI); // sqrt(Re(DFT(I))^2 + Im(DFT(I))^2)
// switch to logarithmic scale: log(1 + magnitude)
magI += Scalar::all(1);
log(magI, magI);
shift(magI);
normalize(magI, magI, 1, 0, NORM_INF); // Transform the matrix with float values into a
return magI; // viewable image form (float between values 0 and 1).
//imshow("spectrum", magI);
}
Mat computeDFT(Mat image) {
Mat padded; //expand input image to optimal size
int m = getOptimalDFTSize( image.rows );
int n = getOptimalDFTSize( image.cols ); // on the border add zero values
copyMakeBorder(image, padded, 0, m - image.rows, 0, n - image.cols, BORDER_CONSTANT, Scalar::all(0));
Mat planes[] = {Mat_<float>(padded), Mat::zeros(padded.size(), CV_32F)};
Mat complex;
merge(planes, 2, complex); // Add to the expanded another plane with zeros
dft(complex, complex, DFT_COMPLEX_OUTPUT); // furier transform
return complex;
}
Mat createavg(Size imsize) {
// call openCV gaussian kernel generator
/*double sigma = (r/SIGMA_CLIP+0.5f);
Mat kernelX = getGaussianKernel(2*radius+1, sigma, CV_32F);
Mat kernelY = getGaussianKernel(2*radius+1, sigma, CV_32F);*/
Mat kernel = (Mat_<float>(3, 3) << 0.111, 0.111, 0.111,
0.111, 0.111, 0.111,
0.111, 0.111, 0.111);
// create 2d gaus
//Mat kernel = kernelX * kernelY.t();
int w = imsize.width-kernel.cols;
int h = imsize.height-kernel.rows;
int r ...
(more)
Really make a good and shorter example
Just focus on the function createavg(Size imsize); I commented the code for gaussian kernel but it works fine for that, but when replaced with average kernel the output is different.
There is no problem in your code and result seems good. Instead of :
try
Can you please explain what it does? I just need to apply the mean blur filter so need a Mat kernel for the same.
f*g=TF^(-1)(Tf(f).TF(g))
if g is your kernel then in space frequency domain you have to multiply with TF(g)
see https://en.wikipedia.org/wiki/Fourier...
The output image is quite distorted after using the kernel you specified. Why so? And what was my kernel doing and what is your kernel doing? I just want to understand the logic behind it. Also in your kernel code can you please explain what Scalar is doing? and why you have used a decimal after 127
And the kernel isnt Blurring the image,, i changed the values from 127 to 255 in your specified kernel @LBerger and i got a more crisper image
"The output image is quite distorted after using the kernel you specified." windowing effect
Really try to understand f*g=TF^(-1)(Tf(f).TF(g)) * convolution and dot product
You can fin many tutorial about fourier transform and image processing
Can you provide me a kernel for performing average blur to the image in frequency domain?According to me it should have worked by the above kernel
I first computed dft of my main image, then made a kernel mask padded it with zeroes to the size of image, after that i shifted the mask and multiplied the dft image and mask, then made the inverse dft I just need to apply a mean blur on image in frequency domain