2016-04-05 5 views
1

WindowsマシンでVisual C++フォームとOpenCVを使用して画像処理アプリケーションを作成しました。すべてがうまくいくように見えますが、画像を表示するのは非常に遅く、わずか数フレームです。私は30程度になることを望みます。私は現在、標準imshow(...)とそれに続くwaitkey(1)を使用しています。openCVを使用した画像の高速表示

私の質問です:画像をメモリからモニタに取り込むためのより良い(つまり速い)方法がありますか? openCVで使用されるMat構造体は、基本的に、unsigned char値の連続ブロックを指し示すファンシーヘッダです。

編集: 私はVS2013プロファイラで私のコードをテストし、それは私がimshowを/ waitkeyで実行時間の50%を費やしていたと主張。

私はOpenCV Q/Aフォーラムでこれについていくつかの議論をしてきました。彼らはいつも「デバッグ以外はimshowを使用すべきではありません」と終わりましたが、誰も使用することを提案していないので、ここで試してみてください。あなたが持っているものを見なければ

+0

「imshow」と「waitKey」がボトルネックであるという結論にどのように到達しましたか?あなたのコードをプロファイルしましたか?または少なくともそれは時間ですか?リリースビルドでテストしていますか? –

+1

[この小さなテスト](http://pastebin.com/PFPgzQn0)を実行すると、適切なnVidiaカードを搭載したi7-4930Kで1600x1200イメージの約55FPSが得られます。自分で画像を描画したい場合は、OnPaintハンドラのBitBltが最速です。私はWindowsフォームを使用していませんが、Windows APIに非常に近いWTLで使用する[スニペットを入手しました](http://pastebin.com/GkDQD3AV)です。あなたの目的に合うようにそれを修正するのはあまりにも厳しくすべきではありません。 –

+0

リリースモードはビット対デバッグに役立ちます(自分自身を考えていたはずです)、 –

答えて

2

、ここで私はあなたが望むものを達成するのにかかるアプローチがあります。

  1. カメラからフレームを取得する専用スレッドがあります。取得したフレームを同期キューに挿入します。このキューは、次のものによって消費されます。

  2. 画像処理スレッド。キューからフレームを取り出し、表示に適したイメージに処理します。それは、同期出力画像を変更し、そのことについてGUIに通知する。

  3. メイン(GUI)スレッドは、表示専用です。画像更新が通知されると、同期出力画像を現在の作業画像と交換する。 (コピーと余分な割り当てを避けるため、2つのイメージバッファを再利用するだけです)。次に、ウィンドウを無効にします。 WM_PAINTハンドラでは、BitBltを使用してイメージを表示します。

いくつかの注意:

  • は、バッファの割り当て/割り当て解除を最小限に抑えます。取得のために、事前に割り振られたバッファープールを循環させることができます。
  • 表示に適した形式とサイズで出力イメージを準備します。
  • キュー内のフレーム数を記録し、上限を設定します。過剰なフレームを削除するためのアルゴリズムを定義して、メモリが足りなくなったり、あまり遅れたりしないようにします。
  • あなただけwaitKeyに睡眠を捨てたいとシンプルな何かをしたい場合は、this question
  • インストゥルメントあなたのコードを見て - high resolution timerを使用して重要な部分のタイミングを追加します。それらを記録し、および/または統計、履歴を保持する。
関連する問題