I want to Convolve Lena with itself in the Frequency Domain. Here is an excerpt from a book. which suggests how should the output of the convolution be:
I have written the following application to achieve the Convolution of two images in the frequency domain. The steps I followed are as follows:
- Convert Lena into a matrix of complex numbers.
- Apply FFT to obtain a complex matrix.
- Multiply two complex matrices element by element (if that is the definition of Convolution).
- Apply IFFT to the result of the multiplication.
The output seems to be not coming as expected:
Two issues are visible here:
- The output only contains a black background with only one dot at its center.
- The original image gets distorted after the the execution of convolution.
.
Note. FFT and I-FFT are working perfectly with the same libraries.
Note-2. There is a thread in SO that seems to be discussing the same topic.
.
Source Code:
public static class Convolution
{
public static Complex[,] Convolve(Complex[,]image, Complex[,]mask)
{
Complex[,] convolve = null;
int imageWidth = image.GetLength(0);
int imageHeight = image.GetLength(1);
int maskWidth = mask.GetLength(0);
int maskeHeight = mask.GetLength(1);
if (imageWidth == maskWidth && imageHeight == maskeHeight)
{
FourierTransform ftForImage = new FourierTransform(image); ftForImage.ForwardFFT();
FourierTransform ftForMask = new FourierTransform(mask); ftForMask.ForwardFFT();
Complex[,] fftImage = ftForImage.FourierTransformedImageComplex;
Complex[,] fftKernel = ftForMask.FourierTransformedImageComplex;
Complex[,] fftConvolved = new Complex[imageWidth, imageHeight];
for (int i = 0; i < imageWidth; i++)
{
for (int j = 0; j < imageHeight; j++)
{
fftConvolved[i, j] = fftImage[i, j] * fftKernel[i, j];
}
}
FourierTransform ftForConv = new FourierTransform();
ftForConv.InverseFFT(fftConvolved);
convolve = ftForConv.GrayscaleImageComplex;
//convolve = fftConvolved;
}
else
{
throw new Exception("padding needed");
}
return convolve;
}
}
private void convolveButton_Click(object sender, EventArgs e)
{
Bitmap lena = inputImagePictureBox.Image as Bitmap;
Bitmap paddedMask = paddedMaskPictureBox.Image as Bitmap;
Complex[,] cLena = ImageDataConverter.ToComplex(lena);
Complex[,] cPaddedMask = ImageDataConverter.ToComplex(paddedMask);
Complex[,] cConvolved = Convolution.Convolve(cLena, cPaddedMask);
Bitmap convolved = ImageDataConverter.ToBitmap(cConvolved);
convolvedImagePictureBox.Image = convolved;
}
ifft( fft(a) * fft(b) )
you get linear convolution and not circular convolution—that’s the gist of the answer you link to. – Ahmed FasihComplex
type know how to do complex multiplication, i.e.,(a + j*b) * (c + j*d) = (a*c - b*d) + j*(a*d + b*c)
? – Ahmed Fasih