【发布时间】:2016-07-20 23:46:41
【问题描述】:
我正在使用以下代码将位图转换为复杂,反之亦然。
尽管这些是直接从Accord.NET framework 复制的,但在测试这些静态方法时,我发现重复使用这些静态方法会导致“数据丢失”。结果,最终输出/结果变得扭曲。
public partial class ImageDataConverter
{
#region private static Complex[,] FromBitmapData(BitmapData bmpData)
private static Complex[,] ToComplex(BitmapData bmpData)
{
Complex[,] comp = null;
if (bmpData.PixelFormat == PixelFormat.Format8bppIndexed)
{
int width = bmpData.Width;
int height = bmpData.Height;
int offset = bmpData.Stride - (width * 1);//1 === 1 byte per pixel.
if ((!Tools.IsPowerOf2(width)) || (!Tools.IsPowerOf2(height)))
{
throw new Exception("Imager width and height should be n of 2.");
}
comp = new Complex[width, height];
unsafe
{
byte* src = (byte*)bmpData.Scan0.ToPointer();
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++, src++)
{
comp[y, x] = new Complex((float)*src / 255,
comp[y, x].Imaginary);
}
src += offset;
}
}
}
else
{
throw new Exception("EightBppIndexedImageRequired");
}
return comp;
}
#endregion
public static Complex[,] ToComplex(Bitmap bmp)
{
Complex[,] comp = null;
if (bmp.PixelFormat == PixelFormat.Format8bppIndexed)
{
BitmapData bmpData = bmp.LockBits( new Rectangle(0, 0, bmp.Width, bmp.Height),
ImageLockMode.ReadOnly,
PixelFormat.Format8bppIndexed);
try
{
comp = ToComplex(bmpData);
}
finally
{
bmp.UnlockBits(bmpData);
}
}
else
{
throw new Exception("EightBppIndexedImageRequired");
}
return comp;
}
public static Bitmap ToBitmap(Complex[,] image, bool fourierTransformed)
{
int width = image.GetLength(0);
int height = image.GetLength(1);
Bitmap bmp = Imager.CreateGrayscaleImage(width, height);
BitmapData bmpData = bmp.LockBits(
new Rectangle(0, 0, width, height),
ImageLockMode.ReadWrite,
PixelFormat.Format8bppIndexed);
int offset = bmpData.Stride - width;
double scale = (fourierTransformed) ? Math.Sqrt(width * height) : 1;
unsafe
{
byte* address = (byte*)bmpData.Scan0.ToPointer();
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++, address++)
{
double min = System.Math.Min(255, image[y, x].Magnitude * scale * 255);
*address = (byte)System.Math.Max(0, min);
}
address += offset;
}
}
bmp.UnlockBits(bmpData);
return bmp;
}
}
(The DotNetFiddle link of the complete source code)
输出:
如您所见,FFT 工作正常,但 I-FFT 不正常。
这是因为复杂的位图(反之亦然)没有按预期工作。
如何纠正 ToComplex() 和 ToBitmap() 函数以使它们不会丢失数据?
【问题讨论】:
-
小提琴不包含
ImageDataConverter类。我们可以看看吗?我怀疑转换回来后数据的动态范围存在问题。 -
我希望您知道 FFT 结果很复杂......您的 FFT 结果看起来只是灰度标量,并不复杂,因此您很可能会丢弃虚部或使用功率谱而不是复杂域此类数据无法重建原始图像。更别说换班了……看看What should be the input and output for an FFT image transformation?
-
@Spektre 更有理由检查
ImageDataConverter类的外观。我认为这是可疑结果背后的罪魁祸首。看着小提琴,FFT 代码似乎很好,但缺少显示图像数据时处理转换的代码。顺便说一句,很棒的链接。
标签: c#-4.0 image-processing bitmap fft ifft