If you use a certain pattern time and again, you might want to make a utility method for it.
for (int j = 0; j < imageHeight; j++)
{
for (int i = 0; i < imageWidth; i++)
{
// do something ..
}
}
static void Walk(int height, int width, Action<int, int> visit)
{
foreach (var point in (
from j in Enumerable.Range(0, height)
from i in Enumerable.Range(0, width)
select (i, j)))
{
visit(point.i, point.j);
}
}
public static Complex[,] Convolve(Complex[,] image, Complex[,] mask)
{
image = image ?? throw new ArgumentNullException(nameof(image));
mask = mask ?? throw new ArgumentNullException(nameof(mask));
var imageWidth = image.GetLength(0);
var imageHeight = image.GetLength(1);
var maskWidth = mask.GetLength(0);
var maskHeight = mask.GetLength(1);
if (!(imageWidth == maskWidth && imageHeight == maskHeight))
{
throw new Exception("padding needed");
}
var imageTransform = new FourierTransform(image);
var maskTransform = new FourierTransform(mask);
imageTransform.ForwardFFT();
maskTransform.ForwardFFT();
var imageComplex = imageTransform.FourierImageComplex;
var maskComplex = maskTransform.FourierImageComplex;
var convolvedComplex = new Complex[imageWidth, imageHeight];
for Walk(int j = 0; j < imageHeight; j++)
imageHeight, imageWidth, {
for (int i = 0; i < imageWidth;, i++j)
{
=> convolvedComplex[i, j] = imageComplex[i, j] * maskComplex[i, j];
}
}j]);
var convolvedTransform = new FourierTransform();
convolvedTransform.InverseFFT(convolvedComplex);
var convolve = convolvedTransform.GrayscaleImageComplex;
Rescale(convolve);
convolve = FourierShifter.FFTShift(convolve);
return convolve;
}