りさーちゃーのひよこ
技術のこととか
2014年6月17日火曜日
OpenGL描画→OpenCV処理→ピクチャボックス描画
#背景 画像処理シミュレータを作成しようとした際、下記のような悩みを持ったことはないだろうか。
- カメラも画像処理をする対象も準備するのはお金かかるし、シミュレーションで検証できないかな。 - じゃあOpenGLで仮想世界を作ってみよう。 - OpenGLでレンダリングした画像をOpenCV側の画像に変換すれば画像処理ができるな。 - その結果をツールに表示したいな。色々検証したいからGUIも使えたら便利そうだな。 少なくとも私はしたいと思いました。
これまでいくつか書いた記事は、これを実現するためのものでした。フォームアプリはまったくの初心者だったので、試行錯誤でようやくそれっぽいものを実現しました。
ようやくフローが分かってきたので、一旦まとめようと思います。今回は実装ではなく、概念の部分です。実装は過去の記事で補完するものとします。
#OpenGL→ピクチャボックス あれ、OpenCVは?と思いますが、まずはここを理解する必要があります。まずは次の図を見てみます。
過去に一部を示しましたが、簡単におさらいします。大きく分けて2段階の処理に分かれます。初期処理と逐次処理です。
初期処理
OpenGLで描画する際にはフォームのピクチャボックスのハンドルからレンダリングコンテキストを取得する必要があります。
→
C++/CLI フォームアプリとOpenGLの連携(フォームへのレンダリングとGUI操作)
逐次処理
(※動画にしたい場合。静止画なら1回でいいです。)
描画対象のレンダリングコンテキストをカレントにし、OpenGLでバッファにレンダリングします。ただし、私の場合、ダブルバッファモードですのでレンダリングした画像はまだVRAMではない他のメモリに格納されており、ピクチャボックスに反映されません(
オフスクリーンレンダリング
)。
これをSwapbuffers()で入れ替えて、晴れてピクチャボックスに表示されます(
オンスクリーン化
)。
これをTimerなりで設定して繰り返し行えば動画が表示されます。
なお、オフスクリーンレンダリングの説明記事としては、次のサイトが分かりやすかったです。
sonson@Picture&Software-[OpenGL] オフスクリーンレンダリング
※ちなみに、オンスクリーンレンダリングは直接ピクチャボックスの領域に書き込むことを指します。描画の過程まで表示されるので描画の量が多いと画面がちらつきます。
#OpenGL→OpenCV→ピクチャボックス OpenGLで描画できましたが、私がやりたいのはこれだけではありません。OpenGLでレンダリングした画像を
表示させず
に、OpenCVで処理した結果だけをピクチャボックスに表示したいのです。ここで、上述した
オフスクリーンレンダリング
が役に立ちます。
下の図は先ほどの図にOpenCVの処理を追加したものです。先ほどと同様に説明をします。
初期処理
OpenGLでレンダリングする場合とまったく同じです。OpenGLでピクチャボックスに書き込むわけではないのですが、どちらにしてもピクチャボックスからウィンドウハンドルを取得し、それからデバイスコンテキストを取得しなければなりません。デバイスコンテキストはどこからともなく沸いて出てくるものではないようです。
(ピクチャボックスに限らず、何らかのウィンドウハンドルを取得できればいいとは思いますが、わざわざ余計なことを考えることもないでしょう。ピクチャボックスから取得すればウィンドウサイズも同一ですし。)
逐次処理
(※動画にしたい場合。静止画なら1回でいいです。)
先ほどオフスクリーンレンダリングをしたイメージバッファをcv::Matのイメージバッファにコピーします。
→
C++/CLI フォームアプリとOpenCVの連携(cv::Mat)-【1. OpenGL画像をOpenCV画像(cv::Mat)に変換】
コピーしたら画像処理を好き勝手します。OpenCV画像処理の解説は他の有用なサイトを参照ください。
cv:MatのイメージバッファをBitmat形式に変換し、ピクチャボックスに描画します。Windowsのフォームに書き込もうと思ったら、Bitmapオブジェクトの利用は避けられません。
→
C++/CLI フォームアプリとOpenCVの連携(cv::Mat)-【3. 結果画像(cv::Mat)をフォームのピクチャボックスに表示】
注意点ですが、OpenCVのバッファを表示する際はSwapBuffursは行ってはいけません。短時間のうちにOpenGLの画像とOpenCVの画像が高速に切り替わり画面がちらつきます。表示させるのは目的に応じてどちらか一方にしましょう。
#まとめ 手順は以上です。
これまであれが足りないこれが足りないと一個一個調べて作っていたものが、ようやく1つのループになりました。
下記画像の①、②については過去の記事でサンプルを公開しています(上記説明で前述ですが、まとめとして書きます)。
①:ウィンドウハンドルからレンダリングコンテキストを習得
→
C++/CLI フォームアプリとOpenGLの連携(フォームへのレンダリングとGUI操作)
②:OpenGLのイメージバッファをOpenCVのイメージバッファにコピー
OpenCVのイメージバッファをピクチャボックスに表示
→
C++/CLI フォームアプリとOpenCVの連携(cv::Mat)
これで少しは遊べるようになりました。
余談ですが、C#に興味はありましたが無理に使う必要はなさそうですね。C++に対するC#のメリットはWebや通信関係を便利にするくらいだと思います。C++でもGUIはフォームで簡単に作れますし。
会社で今度C#のセミナを受けさせてもらうことになったので、気が向いたら投稿しようと思います。
それでは。
0 件のコメント:
コメントを投稿
次の投稿
前の投稿
ホーム
登録:
コメントの投稿 (Atom)
0 件のコメント:
コメントを投稿