2015年6月30日火曜日

OpenGL 取得した画像をOpenCVで処理してOpenGLで表示する。

内部でSimulationをするために、OpenGLでレンダリングし、その画像を取得しOpenCVで処理することを考えた。まぁ、一般的だと思う。そのためには、

1.OpenGLから画像情報の取得
画像情報の取得には3つ方法がある。
・OpenGLで画像を表示させ、glReadPixels を使って画像情報を取得
・ビデオメモリからWindowの画像情報を取得
・オフスクリーンレンダリング
・ダブルバッファから画像情報の取得
下の3つはまだ試していないので今後にやったらご紹介するとして、1つ目が一番簡単なのでその手法を採用した。

仮のコード(double bufferを使うコードから取得)
cv::Mat ReadDisplay;

glutSwapBuffers();
glReadPixels(0, 0, WIDTH, HEIGHT, GL_BGR_EXT, GL_UNSIGNED_BYTE, ReadDisplay.data);

2.画像を上下反転
OpenGLの座標系のY軸は上向きが正。OpenCVの座標系のY軸は下向きが正(左上が原点)。これを変換する必要がある。

cv::flip(ReadDisplay, ReadDisplay, 0);

3.なんか処理する。
特徴点抽出でもやりましょう。でも、本題でないため細かくは略します。ほしかったら連絡ください。
detector = new ORB(80, 1.25f, 4, 7, 0, 2, 0, 7);
detector->detect(img1, keypoints);
cv::drawKeypoints(img1, keypoints, output);

4.OpenCV 色の変更
なぜだかわからないけど、OpenCVはBGR らしい。そのため、BGRから RGB変更しましょう。

cv::cvtColor(output, output, CV_BGR2RGB);

これをやらないとセピア色になります。

5. 画像を上下反転
OpenGLで表示するために、また画像を上下反転します。

cv::flip(output, output, 0);

6.OpenGLのテクスチャに張り付けて、GLのWindowに画像を表示する。
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glOrtho(0.0, WIDTH, HEIGHT, 0.0, -1.0, 1.0);

glEnable(GL_TEXTURE_2D);//テクスチャ有効
//glBindTexture(GL_TEXTURE_2D, img.data);

/* テクスチャ画像はバイト単位に詰め込まれている */
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
/* テクスチャの割り当て */
glTexImage2D(GL_TEXTURE_2D, 0, 3, img.cols, img.rows, 0, GL_RGB, GL_UNSIGNED_BYTE, img.data);
/* テクスチャを拡大・縮小する方法の指定 */
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

glEnable(GL_ALPHA_TEST);//アルファテスト開始
glBegin(GL_POLYGON);
glTexCoord2f(0.0f, 0.0f); glVertex2d(0, HEIGHT);//左下
glTexCoord2f(0.0f, 1.0f); glVertex2d(0, 0);//左上
glTexCoord2f(1.0f, 1.0f); glVertex2d(WIDTH, 0);//右上
glTexCoord2f(1.0f, 0.0f); glVertex2d(WIDTH, HEIGHT);//右下
glEnd();
glDisable(GL_ALPHA_TEST);//アルファテスト終了
glDisable(GL_TEXTURE_2D);//テクスチャ無効

glutSwapBuffers();

参考:
OpenGL描画→OpenCV処理→ピクチャボックス描画
http://ameblo.jp/morimoridiary/theme-10081830227.html
C++/CLI フォームアプリとOpenCVの連携(cv::Mat)
http://ameblo.jp/morimoridiary/entry-11879119909.html
【1. OpenGL画像をOpenCV画像(cv::Mat)に変換】
http://ameblo.jp/morimoridiary/entry-11879119909.html
Kinect for Windows SDKによる3次元ポイントクラウド
http://kassymemo.blogspot.com/2012/04/kinect-for-windows-sdk3.html
http://whoopsidaisies.hatenablog.com/entry/2014/08/20/200215

0 件のコメント:

コメントを投稿