public static Complex[,] ConvolveInFrequencyDomain(Complex[,] fftImage, Complex[,] fftKernel) { Complex[,] convolve = null; int imageWidth = fftImage.GetLength(0); int imageHeight = fftImage.GetLength(1); int maskWidth = fftKernel.GetLength(0); int maskHeight = fftKernel.GetLength(1); if (imageWidth == maskWidth && imageHeight == maskHeight) { Complex[,] fftConvolved = new Complex[imageWidth, imageHeight]; for (int j = 0; j < imageHeight; j++) { for (int i = 0; i < imageWidth; i++) { fftConvolved[i, j] = fftImage[i, j] * fftKernel[i, j]; } } FourierTransform ftForConv = new FourierTransform(); ftForConv.InverseFFT(fftConvolved); convolve = FourierShifter.FFTShift(ftForConv.GrayscaleImageComplex); Rescale(convolve); } else { throw new Exception("padding needed"); } return(convolve); }
/* * public void Pad(int newWidth, int newHeight) * { * double[,] temp = (double[,])Kernel.Clone(); * PaddedKernel = ImagePadder.Pad(temp, newWidth, newHeight); * }*/ public void Pad(int unpaddedWidth, int unpaddedHeight, int newWidth, int newHeight) { cPaddedKernel = new Complex[newWidth, newHeight]; //32x32 Complex[,] unpaddedKernelFrequencyDomain = ImageDataConverter.ToComplex((double[, ])Kernel.Clone()); FourierTransform ftInverse = new FourierTransform(); ftInverse.InverseFFT(FourierShifter.RemoveFFTShift(unpaddedKernelFrequencyDomain)); //32x32 Complex[,] unpaddedKernelTimeDomain = FourierShifter.FFTShift(ftInverse.GrayscaleImageComplex); int startPointX = (int)Math.Ceiling((double)(newWidth - unpaddedWidth) / (double)2) - 1; int startPointY = (int)Math.Ceiling((double)(newHeight - unpaddedHeight) / (double)2) - 1; for (int j = startPointY; j < startPointY + unpaddedHeight; j++) { for (int i = startPointX; i < startPointX + unpaddedWidth; i++) { cPaddedKernel[i, j] = unpaddedKernelTimeDomain[i - startPointX, j - startPointY]; } } /* * for (int j = 0; j < newHeight; j++) * { * for (int i = 0; i < startPointX; i++) * { * unpaddedKernelTimeDomain[i, j] = 0; * } * for (int i = startPointX + unpaddedWidth; i < newWidth; i++) * { * unpaddedKernelTimeDomain[i, j] = 0; * } * } * * for (int i = startPointX; i < startPointX + unpaddedWidth; i++) * { * for (int j = 0; j < startPointY; j++) * { * unpaddedKernelTimeDomain[i, j] = 0; * } * for (int j = startPointY + unpaddedHeight; j < newHeight; j++) * { * unpaddedKernelTimeDomain[i, j] = 0; * } * } **/ FourierTransform ftForward = new FourierTransform(cPaddedKernel); ftForward.ForwardFFT(); //cPaddedKernel = ftForward.FourierImageComplex; }
private void fftButton_Click(object sender, EventArgs e) { Bitmap lena = inputImagePictureBox.Image as Bitmap; FourierTransform ft = new FourierTransform(lena); ft.ForwardFFT(); ___shifted = FourierShifter.FFTShift(ft.FourierImageComplex); Bitmap magnitudePlot = FourierPlotter.FftMagnitudePlot(___shifted); Bitmap phasePlot = FourierPlotter.FftPhasePlot(___shifted); fourierMagnitudePictureBox.Image = (Image)magnitudePlot; fourierPhasePictureBox.Image = (Image)phasePlot; }
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.FourierImageComplex; Complex[,] fftKernel = ftForMask.FourierImageComplex; Complex[,] fftConvolved = new Complex[imageWidth, imageHeight]; for (int j = 0; j < imageHeight; j++) { for (int i = 0; i < imageWidth; i++) { fftConvolved[i, j] = fftImage[i, j] * fftKernel[i, j]; } } FourierTransform ftForConv = new FourierTransform(); ftForConv.InverseFFT(fftConvolved); convolve = ftForConv.GrayscaleImageComplex; Rescale(convolve); convolve = FourierShifter.FFTShift(convolve); } else { throw new Exception("padding needed"); } return(convolve); }