Я использую следующий код для преобразования Bitmap в Complex и наоборот.Потеря данных во время обратного БПФ изображения
Несмотря на то, что они были скопированы непосредственно с 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 работает правильно, но я-FFT ISN «т.
Это связано с тем, что битмап к сложному и наоборот не работает должным образом.
Что можно сделать, чтобы исправить функции ToComplex() и ToBitmap(), чтобы они не потеряли данные?
Скрипка не содержит класс «ImageDataConverter». Можем ли мы посмотреть? Я подозреваю, что проблема с динамическим диапазоном данных после преобразования. – rayryeng
Надеюсь, вы знаете, что результат FFT сложный ... ваш результат FFT выглядит как скаляр в градациях серого, который не является сложным, поэтому вы, скорее всего, выбрасываете мнимую часть или используете спектр мощности вместо сложного домена, так или иначе из таких данных, вы не можете восстановить оригинальные образ. Не говоря уже о смене ... Взгляните на [Что должно быть вводом и выводом для преобразования изображения FFT?] (Http://stackoverflow.com/a/26734979/2521214) – Spektre
@Spektre Тем более изучите, как выглядит класс 'ImageDataConverter'. Это я считаю виновником сомнительных результатов. Глядя на скрипку, код FFT кажется прекрасным, но код для обработки преобразования при отображении данных изображения отсутствует. Кстати, отличная ссылка. – rayryeng