0

我需要每秒多次处理(更改亮度、对比度等)非常大的高质量位图(通常超过 10MPx),并且每次都需要在屏幕上更新它(在 WPF 中的图像控制上)。目前我正在使用 AForge.NET 库进行非托管图像处理,但有些问题我无法解决。首先,一个操作需要大约 300 毫秒(不更新屏幕),这对我来说是不可接受的。这是示例代码:

UnmanagedImage _img;
BrightnessCorrection _brightness = new BrightnessCorrection();

void Load()
{
   _img = UnmanagedImage.FromManagedImage((Bitmap)Bitmap.FromFile("image.jpg"));
}

void ChangeBrightness(int val) // this method is invoked by changing Slider value - several times per second
{
   _brightness.AdjustValue = val;
   _brightness.ApplyInPlace(_img); // it takes ~300ms for image 22MPx, no screen update - just change brightness "in background"
} 

我没有图像处理方面的经验,但我认为它的速度不会快得多,因为它的分辨率非常高。我对吗?

另一个问题——如何有效地更新屏幕?目前我有以下(ofc 非常糟糕)的解决方案:

void ChangeBrightness(int val)
{
   _brightness.AdjustValue = val;
   _brightness.ApplyInPlace(_img);

    using (MemoryStream ms = new MemoryStream())
    {
        using (Bitmap b = _img.ToManagedImage())
        {
            b.Save(ms, ImageFormat.Bmp);
            ms.Seek(0, SeekOrigin.Begin);

            var bmp = new BitmapImage();
            bmp.BeginInit();
            bmp.StreamSource = ms;
            bmp.CacheOption = BitmapCacheOption.OnLoad;
            bmp.EndInit();

            MyImageControl.Source = new WriteableBitmap(bmp); // !!!
        }
    }
}

如您所见,每次创建新的 WriteableBitmap 时(您可以想象会发生什么)。而不是这些“使用”,我尝试了这种方式:

    WriteableBitmapSource.Lock(); // this object (of type WriteableBitmap) is just MVVM ViewModel's property which is binded to MyImageControl.Source
    WriteableBitmapSource.Source.WritePixels(new Int32Rect(0, 0, _img.Width, _img.Height), _img.ImageData, _img.Stride * _img.Height * 3, _img.Stride, 0, 0); // image's PixelFormat is 24bppRgb

...但 WritePixels 方法抛出“值不在预期范围内”。任何想法为什么?任何帮助都感激不尽 :)

PS AForge.NET 是一个不错的选择吗?也许有更好的图像处理库?

对不起我的英语;P

4

1 回答 1

0

图像 22MPx 约 300 毫秒,每像素约 20 ns。这应该是对的。

您需要考虑 CPU 成本和内存访问成本。

如果您想进一步改进这一点,请考虑: 1) 使用多个线程,每个线程负责位图的一部分。2) 使用 SIMD 指令编写您自己的实现。3)不要对位图进行预处理,在需要时转换位图扫描线。

于 2012-08-07T03:31:49.240 回答