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); }
private void iFftButton_Click(object sender, EventArgs e) { FourierTransform ft = new FourierTransform(); ft.InverseFFT(___shifted); inverseFftPictureBox.Image = (Image)ft.ImageBitmap; }
/* * 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; }
public List <Bitmap> Apply(Bitmap bitmap) { Kernels = new List <KassWitkinKernel>(); double degrees = FilterAngle; KassWitkinKernel kernel; for (int i = 0; i < NoOfFilters; i++) { kernel = new KassWitkinKernel(); kernel.Width = KernelDimension; kernel.Height = KernelDimension; kernel.CenterX = (kernel.Width) / 2; kernel.CenterY = (kernel.Height) / 2; kernel.Du = 2; kernel.Dv = 2; kernel.ThetaInRadian = Tools.DegreeToRadian(degrees); kernel.Compute(); //SleuthEye kernel.Pad(kernel.Width, kernel.Height, WidthWithPadding, HeightWithPadding); Kernels.Add(kernel); degrees += degrees; } List <Bitmap> list = new List <Bitmap>(); Bitmap image = (Bitmap)bitmap.Clone(); Complex[,] cImagePadded = ImageDataConverter.ToComplex(image); FourierTransform ftForImage = new FourierTransform(cImagePadded); ftForImage.ForwardFFT(); Complex[,] fftImage = ftForImage.FourierImageComplex; foreach (KassWitkinKernel k in Kernels) { Complex[,] cKernelPadded = k.ToComplexPadded(); Complex[,] convolved = Convolution.ConvolveInFrequencyDomain(fftImage, cKernelPadded); Bitmap temp = ImageDataConverter.ToBitmap(convolved); list.Add(temp); } return(list); }
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); }