Я написал следующее приложение для достижения свертки двух изображений в частотной области.Свертка БПФ между двумя изображениями не работает
Я хочу сжать Лена с собой.
шаги я следовал:
(1) Преобразование Лену в матрицу комплексных чисел.
(2) Применить FFT для получения сложной матрицы.
(3) Затем я бы умножал два элемента сложных матриц на элемент (если это определение свертки).
(4) Затем я применил бы IFFT к результату умножения.
Я написал код C#. Но выход кажется не таким, как ожидалось.
Here is an excerpt from a book. Это говорит о том, как выход свертке должно быть.
Некоторые Актуальной код:
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;
}
}
Исходный код для GUI,
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;
}
Вот zipped source code как решение VS2013.
Также, there is a thread in SO, который, кажется, обсуждает ту же тему.
P.S. FFT и I-FFT отлично работают с теми же библиотеками.
Я вижу в вашем коде, что вам требуется маска и изображение, чтобы иметь такой же размер, что означает, что он «дополнен» к длине другого. Но когда вы говорите о быстрой свертке с помощью БПФ, «заполнение» означает «нулевое заполнение» входных изображений, так что когда вы выполняете 'ifft (fft (a) * fft (b))' вы получаете линейную свертку, а не круговую свертку, это суть [ответа на ссылку] (http://stackoverflow.com/a/12254741/500207). –
Знает ли C# 'Complex' тип сложного умножения, т. Е.' (A + j * b) * (c + j * d) = (a * c - b * d) + j * (a * d + б * с) '? –
Даже если вы не заполняли нулями два изображения до 2D FFT, ваш результат (черный фон, белая точка) очень неправильный. Если вы свертываете изображение с искаженной версией себя, вы все равно ожидаете (потенциально искаженной) экспоненциально-распадающейся автокорреляции, как предлагает учебник. –