0

非常に大きな高品質のビットマップ(多くの場合10MPxを超える)を1秒間に数回処理(明るさ、コントラストなどを変更)する必要があり、毎回画面上で(WPFの画像コントロール上で)更新する必要があります。現在、アンマネージド画像処理にAForge.NETライブラリを使用していますが、解決できない問題がいくつかあります。まず、1回の操作で(画面を更新せずに)約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"
} 

画像処理の経験はありませんが、解像度が非常に高いので、それほど速くはないと思います。私は正しいですか?

別の問題-画面を効率的に更新する方法は?現時点では、次の(多くの場合非常に悪い)解決策があります。

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の約300msは、ピクセルあたり約20nsです。それはほぼ正しいはずです。

CPUコストとメモリアクセスコストを考慮する必要があります。

これをさらに改善したい場合は、次のことを検討してください。1)それぞれがビットマップのセクションを担当する複数のスレッドを使用します。2)SIMD命令を使用して、独自の実装を作成します。3)ビットマップを前処理せず、必要に応じてビットマップスキャンラインを変換します。

于 2012-08-07T03:31:49.240 に答える