2012-06-14 17 views
7

OpenNIを使用した奥行き処理(Xbox Kinect、Asus Xtionなど)アプリケーションを開発しています。C#高速ピクセルレンダリング

センサーから新しい奥行きデータが入手できる場合(解像度に応じて30または60 fps)、Windowsフォームで実際に簡単に描画する方法が必要です。

現在、私は、データが利用可能になったときに別のスレッドからダブルバッファーパネルを無効にしてから、パネルのペイント方法でビットマップのピクセルを設定して、恐ろしい5fpsを予測します。

System.Drawing.Graphicsは、誰かが他に指示することができない限り、個々のピクセルを設定するための迅速な方法が不足しているようです。

文字通り、ピクセルの色を設定するだけで済みますので、できるだけサードパーティの高速レンダリングAPIを使用しないようにして、可能な限りネイティブのものを使用するのが理想的です。

誰にも提案はありますか?

+0

どのようにピクセルを現在設定していますか? – leppie

+0

image.SetPixel(x、y、color)を使用してビットマップを作成しました。結局、graphics.drawImage(画像など) –

+2

を呼び出すことは 'SetPixel'は非常に遅いです。 'Scanline'アプローチを見てください。 – leppie

答えて

4

ビットマップを使用している場合は、LockBitsとUnlockBitsを使用してメモリ内のデータに直接アクセスする必要があります。 C#では、安全でないコードブロックやポインタを使用することで、パフォーマンスを向上させることができます。

は、詳細については、このリンクを参照してください:http://web.archive.org/web/20150227183132/http://bobpowell.net/lockingbits.aspx

+0

これは抜本的な改善でした。私は空の640x480ビットマップを描くときに10fps以上を達成することができなかったので、System.Drawingは基本的に高速ではないという結論に達しました。このソリューションは、画像を縮小し、必要なFPSを達成するためにピクセルの一部のみをレンダリングすることと組み合わせて答えました。 –

4

image.SetPixel()は、1フレームあたり多くのピクセルを置き換え、1秒あたりに多くのフレームが必要な場合は非常に遅いです。

それはあなたがWriteableBitmapを使用するときに非常に速くなり、あなたが複数のスレッドを使用してピクセルデータを持つ配列を記入し、単に単一の呼び出し中の画像に配列をブリットすることができますこの方法CopyPixels

を呼び出します。

EDIT WriteableBitmapはWPFクラスです

注意。 WinFormsにバインドされている場合は、独自の実装を作成する必要があります。 WPF/WinForms/GDI interop: converting a WriteableBitmap to a System.Drawing.Image?

+0

返信いただきありがとうございますが、あなたが提供した回答リンクはWriteableBitmapからSystem.Drawing.Imageへの変換で.SetPixel()を使用します。 –

+0

はい、それはスピードにとって恐ろしいことです。代わりに配列に書き込んでエンコーダ(PNG、BMP、...)を使用して、画像を表示してそれを表示する方法もあります。 SetPixelの主な問題は、1ピクセルを設定することです。 –

0

あなたの「バッファ・ビットマップ」で動作するように私のLINQ image processing libraryを試みることができます。非常にアクセス可能な構文を使用しますが、大きなビットマップの場合は非常に優れています。これは、Nugetで、プロジェクトに1つのファイルが含まれているため利用できます。

希望に役立ちます!