HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

FFT Convolution

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
convolutionfftstackoverflow

Problem

I have written the following routines to convolve two images in the frequency domain which are represented as 2d Complex arrays.

How can I optimize my routines for better performance?

```
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.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;
}

//Rescale values between 0 and 255.
private static void Rescale(Complex[,] convolve)
{
int imageWidth = convolve.GetLength(0);
int imageHeight = convolve.GetLength(1);

double maxAmp = 0.0;
for (int j = 0; j < imageHeight; j++)
{
for (int i = 0; i < imageWidth; i++)
{
maxAm

Solution

A few detail remarks:

Complex[,] convolve = null;


This variable declaration should be moved further down, to the line where it is actually needed. Initializing it with null is misleading.

maxAmp = Math.Max(maxAmp, convolve[i, j].Magnitude);


Since Magnitude involves a square root, it is expensive to calculate. Prefer calculating the square magnitude only and calculate the square root only once at the end. This saves width * height - 1 square root calculations.

In the second loop, maxAmp is calculated again but never used. Removing it saves another width * height calculations.

Code Snippets

Complex[,] convolve = null;
maxAmp = Math.Max(maxAmp, convolve[i, j].Magnitude);

Context

StackExchange Code Review Q#139860, answer score: 3

Revisions (0)

No revisions yet.