165 lines
3.8 KiB
C#
165 lines
3.8 KiB
C#
using System;
|
|
using System.Drawing;
|
|
using System.Drawing.Imaging;
|
|
using AForge.Math;
|
|
|
|
namespace AForge.Imaging;
|
|
|
|
public class ComplexImage : ICloneable
|
|
{
|
|
private Complex[,] data;
|
|
|
|
private int width;
|
|
|
|
private int height;
|
|
|
|
private bool fourierTransformed;
|
|
|
|
public int Width => width;
|
|
|
|
public int Height => height;
|
|
|
|
public bool FourierTransformed => fourierTransformed;
|
|
|
|
public Complex[,] Data => data;
|
|
|
|
protected ComplexImage(int width, int height)
|
|
{
|
|
this.width = width;
|
|
this.height = height;
|
|
data = new Complex[height, width];
|
|
fourierTransformed = false;
|
|
}
|
|
|
|
public object Clone()
|
|
{
|
|
ComplexImage complexImage = new ComplexImage(width, height);
|
|
Complex[,] array = complexImage.data;
|
|
for (int i = 0; i < height; i++)
|
|
{
|
|
for (int j = 0; j < width; j++)
|
|
{
|
|
ref Complex reference = ref array[i, j];
|
|
reference = data[i, j];
|
|
}
|
|
}
|
|
complexImage.fourierTransformed = fourierTransformed;
|
|
return complexImage;
|
|
}
|
|
|
|
public static ComplexImage FromBitmap(Bitmap image)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_000b: Invalid comparison between Unknown and I4
|
|
if ((int)((Image)image).PixelFormat != 198659)
|
|
{
|
|
throw new UnsupportedImageFormatException("Source image can be graysclae (8bpp indexed) image only.");
|
|
}
|
|
BitmapData val = image.LockBits(new Rectangle(0, 0, ((Image)image).Width, ((Image)image).Height), (ImageLockMode)1, (PixelFormat)198659);
|
|
try
|
|
{
|
|
return FromBitmap(val);
|
|
}
|
|
finally
|
|
{
|
|
image.UnlockBits(val);
|
|
}
|
|
}
|
|
|
|
public unsafe static ComplexImage FromBitmap(BitmapData imageData)
|
|
{
|
|
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
|
|
//IL_000b: Invalid comparison between Unknown and I4
|
|
if ((int)imageData.PixelFormat != 198659)
|
|
{
|
|
throw new UnsupportedImageFormatException("Source image can be graysclae (8bpp indexed) image only.");
|
|
}
|
|
int num = imageData.Width;
|
|
int num2 = imageData.Height;
|
|
int num3 = imageData.Stride - num;
|
|
if (!Tools.IsPowerOf2(num) || !Tools.IsPowerOf2(num2))
|
|
{
|
|
throw new InvalidImagePropertiesException("Image width and height should be power of 2.");
|
|
}
|
|
ComplexImage complexImage = new ComplexImage(num, num2);
|
|
Complex[,] array = complexImage.data;
|
|
byte* ptr = (byte*)imageData.Scan0.ToPointer();
|
|
for (int i = 0; i < num2; i++)
|
|
{
|
|
int num4 = 0;
|
|
while (num4 < num)
|
|
{
|
|
array[i, num4].Re = (float)(int)(*ptr) / 255f;
|
|
num4++;
|
|
ptr++;
|
|
}
|
|
ptr += num3;
|
|
}
|
|
return complexImage;
|
|
}
|
|
|
|
public unsafe Bitmap ToBitmap()
|
|
{
|
|
Bitmap val = Image.CreateGrayscaleImage(width, height);
|
|
BitmapData val2 = val.LockBits(new Rectangle(0, 0, width, height), (ImageLockMode)3, (PixelFormat)198659);
|
|
int num = val2.Stride - width;
|
|
double num2 = (fourierTransformed ? System.Math.Sqrt(width * height) : 1.0);
|
|
byte* ptr = (byte*)val2.Scan0.ToPointer();
|
|
for (int i = 0; i < height; i++)
|
|
{
|
|
int num3 = 0;
|
|
while (num3 < width)
|
|
{
|
|
*ptr = (byte)System.Math.Max(0.0, System.Math.Min(255.0, data[i, num3].Magnitude * num2 * 255.0));
|
|
num3++;
|
|
ptr++;
|
|
}
|
|
ptr += num;
|
|
}
|
|
val.UnlockBits(val2);
|
|
return val;
|
|
}
|
|
|
|
public void ForwardFourierTransform()
|
|
{
|
|
if (fourierTransformed)
|
|
{
|
|
return;
|
|
}
|
|
for (int i = 0; i < height; i++)
|
|
{
|
|
for (int j = 0; j < width; j++)
|
|
{
|
|
if (((j + i) & 1) != 0)
|
|
{
|
|
data[i, j].Re *= -1.0;
|
|
data[i, j].Im *= -1.0;
|
|
}
|
|
}
|
|
}
|
|
FourierTransform.FFT2(data, FourierTransform.Direction.Forward);
|
|
fourierTransformed = true;
|
|
}
|
|
|
|
public void BackwardFourierTransform()
|
|
{
|
|
if (!fourierTransformed)
|
|
{
|
|
return;
|
|
}
|
|
FourierTransform.FFT2(data, FourierTransform.Direction.Backward);
|
|
fourierTransformed = false;
|
|
for (int i = 0; i < height; i++)
|
|
{
|
|
for (int j = 0; j < width; j++)
|
|
{
|
|
if (((j + i) & 1) != 0)
|
|
{
|
|
data[i, j].Re *= -1.0;
|
|
data[i, j].Im *= -1.0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|