以下代码将彩色图像转换为灰度,然后计算其FFT:
private void button1_Click(object sender, EventArgs e)
{
Bitmap source = pictureBox1.Image as Bitmap;
Bitmap gray = Grayscale.ToGrayscale(source);
Complex[,] cpxImage = ImageDataConverter.ToComplex(gray);
Complex[,] fftCpxImage = FourierTransform.ForwardFFT(cpxImage);
Complex[,] shiftedFftCpxImage = FourierShifter.ShiftFft(fftCpxImage);
Bitmap mag = FourierPlot.FftMagnitudePlot(shiftedFftCpxImage, PixelFormat.Format8bppIndexed);
Bitmap phase = FourierPlot.FftPhasePlot(shiftedFftCpxImage, PixelFormat.Format8bppIndexed);
pictureBox2.Image = gray;
pictureBox3.Image = mag;
pictureBox4.Image = phase;
}
以下代码将彩色图像分为三个通道,计算其FFT并将它们合并在一起以形成FFT的RGB图像。
private void button2_Click(object sender, EventArgs e)
{
Bitmap source = pictureBox1.Image as Bitmap;
int [,,] array3d = ImageDataConverter.ToInteger3d(source);
int[,] red = ArrayTools<int>.Split(array3d, 0);
int[,] green = ArrayTools<int>.Split(array3d, 1);
int[,] blue = ArrayTools<int>.Split(array3d, 2);
Complex [,] cpxRed = ImageDataConverter.ToComplex(red);
Complex [,] cpxGreen = ImageDataConverter.ToComplex(green);
Complex [,] cpxBlue = ImageDataConverter.ToComplex(blue);
Complex[,] fftCpxRed = FourierTransform.ForwardFFT(cpxRed);
Complex[,] fftCpxGreen = FourierTransform.ForwardFFT(cpxGreen);
Complex[,] fftCpxBlue = FourierTransform.ForwardFFT(cpxBlue);
Complex[,] shiftedFftCpxRed = FourierShifter.ShiftFft(fftCpxRed);
Complex[,] shiftedFftCpxGreen = FourierShifter.ShiftFft(fftCpxGreen);
Complex[,] shiftedFftCpxBlue = FourierShifter.ShiftFft(fftCpxBlue);
int[,] fftRed = ImageDataConverter.ToIntegerMagnitude(shiftedFftCpxRed);
int[,] fftGreen = ImageDataConverter.ToIntegerMagnitude(shiftedFftCpxGreen);
int[,] fftBlue = ImageDataConverter.ToIntegerMagnitude(shiftedFftCpxBlue);
int [,,] dest = ArrayTools<int>.Merge(fftRed, fftGreen, fftBlue);
Bitmap mag = ImageDataConverter.ToBitmap3d(dest, PixelFormat.Format8bppIndexed);
Grayscale.SetPalette(mag);
pictureBox3.Image = mag;
}
输出
在第一种情况下,结果非常好,并且符合预期。在第二种情况下,输出为全黑。
再进行一次测试::如果我仅参加一个频道,则输出仍然很酷:
... ... ...
Complex[,] shiftedFftCpxRed = FourierShifter.ShiftFft(fftCpxRed);
Complex[,] shiftedFftCpxGreen = FourierShifter.ShiftFft(fftCpxGreen);
Complex[,] shiftedFftCpxBlue = FourierShifter.ShiftFft(fftCpxBlue);
Bitmap mag = FourierPlot.FftMagnitudePlot(shiftedFftCpxRed, PixelFormat.Format8bppIndexed);
Bitmap phase = FourierPlot.FftPhasePlot(shiftedFftCpxRed, PixelFormat.Format8bppIndexed);
pictureBox2.Image = ImageDataConverter.ToBitmap2d(red, PixelFormat.Format8bppIndexed);
pictureBox3.Image = mag;
pictureBox4.Image = phase;
... ... ...
我认为
中存在问题 public static int[,] ToIntegerMagnitude(Complex[,] image)
{
int Width = image.GetLength(0);
int Height = image.GetLength(1);
int[,] integer = new int[Width, Height];
for (int j = 0; j <= Height - 1; j++)
{
for (int i = 0; i <= Width - 1; i++)
{
integer[i, j] = ((int)image[i, j].Magnitude);
}
}
return integer;
}
这只是重要的一环,因此在此过程中会丢失数据。
有什么建议吗?
。
相关源代码
public static class FourierPlot
{
public static Bitmap FftMagnitudePlot(Complex[,] fftImage, PixelFormat pixelFormat)
{
int[,] FourierMagnitudeNormalizedInteger = FourierNormalizer.Normalize(fftImage, NormalizeType.Magnitude);
Bitmap color = ImageDataConverter.ToBitmap2d(FourierMagnitudeNormalizedInteger, pixelFormat);
Grayscale.SetPalette(color);
return color;
}
public static Bitmap FftPhasePlot(Complex[,] fftImage, PixelFormat pixelFormat)
{
int[,] FourierPhaseNormalizedInteger = FourierNormalizer.Normalize(fftImage, NormalizeType.Phase);
Bitmap color = ImageDataConverter.ToBitmap2d(FourierPhaseNormalizedInteger, pixelFormat);
Grayscale.SetPalette(color);
return color;
}
}
public partial class FourierNormalizer
{
public static int[,] Normalize(Complex[,] Output, NormalizeType normalizeType)
{
int Width = Output.GetLength(0);
int Height = Output.GetLength(1);
double[,] FourierDouble = new double[Width, Height];
double[,] FourierLogDouble = new double[Width, Height];
int[,] FourierNormalizedInteger = new int[Width, Height];
double max = 0;
if (normalizeType == NormalizeType.Magnitude)
{
for (int i = 0; i <= Width - 1; i++)
{
for (int j = 0; j <= Height - 1; j++)
{
FourierDouble[i, j] = Output[i, j].Magnitude;
FourierLogDouble[i, j] = (double)Math.Log(1 + FourierDouble[i, j]);
}
}
max = FourierLogDouble[0, 0];
}
else
{
for (int i = 0; i <= Width - 1; i++)
{
for (int j = 0; j <= Height - 1; j++)
{
FourierDouble[i, j] = Output[i, j].Phase;
FourierLogDouble[i, j] = (double)Math.Log(1 + Math.Abs(FourierDouble[i, j]));
}
}
FourierLogDouble[0, 0] = 0;
max = FourierLogDouble[1, 1];
}
for (int i = 0; i <= Width - 1; i++)
{
for (int j = 0; j <= Height - 1; j++)
{
if (FourierLogDouble[i, j] > max)
{
max = FourierLogDouble[i, j];
}
}
}
for (int i = 0; i <= Width - 1; i++)
{
for (int j = 0; j <= Height - 1; j++)
{
FourierLogDouble[i, j] = FourierLogDouble[i, j] / max;
}
}
if (normalizeType == NormalizeType.Magnitude)
{
for (int i = 0; i <= Width - 1; i++)
{
for (int j = 0; j <= Height - 1; j++)
{
FourierNormalizedInteger[i, j] = (int)(2000 * FourierLogDouble[i, j]);
}
}
}
else
{
for (int i = 0; i <= Width - 1; i++)
{
for (int j = 0; j <= Height - 1; j++)
{
FourierNormalizedInteger[i, j] = (int)(255 * FourierLogDouble[i, j]);
}
}
}
return FourierNormalizedInteger;
}
}
public static Bitmap ToBitmap3d(int[, ,] image, PixelFormat pixelFormat)
{
int Width = image.GetLength(1);
int Height = image.GetLength(2);
Bitmap bmp = new Bitmap(Width, Height, pixelFormat);
BitmapLocker locker = new BitmapLocker(bmp);
locker.Lock();
int [,] red = ArrayTools<int>.Split(image, 0);
int [,] green = ArrayTools<int>.Split(image, 1);
int [,] blue = ArrayTools<int>.Split(image, 2);
for (int y = 0; y < Height; y++)
{
for (int x = 0; x < Width; x++)
{
int r = red[x,y];
int g = green[x,y];
int b = blue[x,y];
Color clr = Color.FromArgb(r,g,b);
locker.SetPixel(x, y, clr);
}
}
locker.Unlock();
return bmp;
}
答案 0 :(得分:1)
此评论解决了我的问题。
private void button2_Click(object sender, EventArgs e)
{
Bitmap source = (Bitmap)(pictureBox1.Image as Bitmap).Clone();
int[, ,] array3d = ImageDataConverter.ToInteger3d(source);
int[,] red = ArrayTools<int>.Split(array3d, 0);
int[,] green = ArrayTools<int>.Split(array3d, 1);
int[,] blue = ArrayTools<int>.Split(array3d, 2);
Complex[,] cpxRed = ImageDataConverter.ToComplex(red);
Complex[,] cpxGreen = ImageDataConverter.ToComplex(green);
Complex[,] cpxBlue = ImageDataConverter.ToComplex(blue);
Complex[,] fftCpxRed = FourierTransform.ForwardFFT(cpxRed);
Complex[,] fftCpxGreen = FourierTransform.ForwardFFT(cpxGreen);
Complex[,] fftCpxBlue = FourierTransform.ForwardFFT(cpxBlue);
Complex[,] shiftedFftCpxRed = FourierShifter.ShiftFft(fftCpxRed);
Complex[,] shiftedFftCpxGreen = FourierShifter.ShiftFft(fftCpxGreen);
Complex[,] shiftedFftCpxBlue = FourierShifter.ShiftFft(fftCpxBlue);
int[,] normRed = FourierNormalizer.Normalize(shiftedFftCpxRed, NormalizeType.Magnitude);
int[,] normGreen = FourierNormalizer.Normalize(shiftedFftCpxGreen, NormalizeType.Magnitude);
int[,] normBlue = FourierNormalizer.Normalize(shiftedFftCpxBlue, NormalizeType.Magnitude);
Bitmap mag = ImageDataConverter.ToBitmap3d(normRed, normGreen, normBlue, PixelFormat.Format8bppIndexed);
//Grayscale.SetPalette(mag);
//Bitmap mag = FourierPlot.FftMagnitudePlot(shiftedFftCpxRed, PixelFormat.Format8bppIndexed);
Bitmap phase = FourierPlot.FftPhasePlot(shiftedFftCpxRed, PixelFormat.Format8bppIndexed);
pictureBox2.Image = mag;
pictureBox3.Image = mag;
pictureBox4.Image = phase;
}