12 | 2025/01 | 02 |
S | M | T | W | T | F | S |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
ブログは単なるメモ帳となる予定。
#include <GL/glut.h> void display(void){ // 全ピクセルクリア glClear(GL_COLOR_BUFFER_BIT); // 白色、幅0.8の方形 glColor3f(1.0, 1.0, 1.0); glBegin(GL_POLYGON); glVertex2f(0.1, 0.1); glVertex2f(0.9, 0.1); glVertex2f(0.9, 0.9); glVertex2f(0.1, 0.9); glEnd(); // 赤色、幅0.6の方形 glColor3f(1.0, 0.0, 0.0); glBegin(GL_POLYGON); glVertex3f(0.2, 0.2, 0.0); glVertex3f(0.8, 0.2, 0.0); glVertex3f(0.8, 0.8, 0.0); glVertex3f(0.2, 0.8, 0.0); glEnd(); // 緑色、幅0.4の方形 glColor3f(0.0, 1.0, 0.0); glRectf(0.3, 0.3, 0.7, 0.7); // 青色、幅0.2の方形 glColor3f(0.0, 0.0, 1.0); GLdouble start[2] = {0.4, 0.4}; GLdouble end[2] = {0.6, 0.6}; glRectdv(start, end); glFlush(); } // 初期化する関数 void init(void){ // 背景色 glClearColor(0,0,0,0); // 視野に関する値を初期化 glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0); } int _tmain(int argc, char* argv[]){ glutInit(&argc, argv); glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(100, 100); glutInitWindowPosition(100, 100); glutCreateWindow("hello"); init(); glutDisplayFunc(&display); glutMainLoop(); return 0; }【実行結果】
最近OpenCVばかりやってますが、OpenGLも勉強中です。
初期化関係の関数。
- ■void glutInit(int *argcp, char **argv);
- コマンドラインの引数を処理する。他のGLUTルーチンより最初に実行する必要有り。
- ■void glutInitDisplayMode(unsigned int mode);
- ウィンドウのモードを指定する。
- ■void glutInitWindowSize(int width, int height);
- ウィンドウのサイズを指定する。
- ■void glutInitWindowPosition(int x, int y);
- ウィンドウの位置を指定する。
- ■int glutCreateWindow(const char *title);
- ウィンドウを作成する。返却値はウィンドウの一意な識別子。
- ■void glutDisplayFunc(void (*func)(void));
- ウィンドウを描画する関数を指定する。
- ■void glutMainLoop()
- 作成された全てのウィンドウを表示し、イベント処理を開始し、ディスプレイコールバックを起動する。
そのほかの関数
- ■void glClear(GLbitfield mask);
-
指定したバッファをクリアカラーでクリアする。
バッファ 名前 カラーバッファ GL_COLOR_BUFFER_BIT デプスバッファ GL_DEPTH_BUFFER_BIT アキュムレーションバッファ GL_ACCUM_BUFFER_BIT ステンシルバッファ GL_STENCIL_BUFFER_BIT - ■void glClearColor(GLclampf red, GLClampf green, GLclampd blue, GLclampf alpha);
- カラーバッファのクリアに使用するクリアカラーをRGBAで設定する。
- ■void glColor3f(GLfloat red, GLfloat green, GLfloat blue);
- 描画するオブジェクトの色を指定する。
- ■void glBegin(GLenum mode); …ポリゴンの頂点群… glEnd();
-
頂点群を与えて、ポリゴンや点を描画する。modeのとりうる値は以下のとおり。
値 描画のされ方 GL_POINTS 点 GL_LINES 線分(v0v1、v2v3…) GL_LINE_STRIP 連続の線分(v0v1、v1v2…) GL_LINE_LOOP ループ GL_TRIANGLES 三角形(△v0v1v2、△v3v4v5…) GL_TRIANGLE_STRIP 連続の三角形(△v0v1v2、△v2v1v3…) GL_TRIANGLE_FAN v0を1つの頂点とする連続の三角形(△v0v1v2、△v0v2v3…) GL_QUADS 四角形 GL_QUAD_STRIP 連続の四角形 GL_POLYGON v0…vn-1を頂点とするポリゴン - ■void glVertex3f(GLfloat x, GLfloat y, GLfloat z);
- glBegin()~glEnd()内で頂点を指定する。引数により様々な関数が用意されている(下を参照)。
- ■void glVertex{234}{sifd}[v](TYPE coords);
-
上の一般形。
{234}で引数の数を指定する。2は2次元平面状の点(z=0)、3は3次元空間上の点、4は3次元空間上の点を斉次座標でそれぞれ指定する。
{sifd}で引数の型を指定。
[v]がついている場合は引数がベクトル形であることを示す。 - ■void glRect{sifd}[v](TYPE coords);
- 方形を描画する。
- ■void glFlush(void);
- OpenGLコマンドを実行する。これで不十分な場合はglFinish()関数を利用する。
今回のプログラムでは使わなかったがイベントを処理する関数を設定する関数には以下の物がある。
- ■void glutReshapeFunc(void (*func)(int width, int height));
- ウィンドウのサイズが変わったときに呼び出される関数を指定する。
- ■void glutKeyboardFunc(void (*func)(unsigned char key, int x, int y));
- キーボードからの入力があったときに呼び出される関数を指定する。
- ■void glutMouseFunc(void (*func)(int button, int state, int x, int y));
- マウスからの入力があったときに呼び出される関数を指定する。
- ■void glutMotionFunc(void (*func)(int x, int y));
- マウスボタンが押された状態で移動したとき(?)に呼び出される関数を指定する。
- ■void glutIdleFunc(void (*func)(void));
- アイドル時に呼び出される関数を指定する。
init関数内の他のコマンドについてはまた後で
画像を他の画像の(x,y)を左上とする位置に合成する関数を作った。自分は使わないけど。
void combine(IplImage* img, IplImage* add, IplImage* mask, const int x, const int y){ assert( img != NULL && add != NULL && mask != NULL ); assert( add->width == mask->width && add->height == mask->height ); const int i_max( ((x+add->width ) > img->width ) ? img->width - x : add->width ); const int j_max( ((y+add->height) > img->height) ? img->height - y : add->height ); for(int j = 0; j < j_max; ++j){ for(int i = 0; i < i_max; ++i){ if( mask->imageData[ j*mask->widthStep + i ] != 0 ){ // imgの(x+i,y+j)をadd(i,j)で上書き copyat(img, x+i, y+j, add, i, j); } } } return; }
とりあえずYIQ表色系とHSV表色系を併用するやり方でやってみた。おお、意外とこれだけでもうまくいってる。これなら補間とラベリングの組み合わせで何とかなりそう…というかHSVの方が良い肌色検出が出来てる気がするな…
今は時間がないのでソースは後ほど。
肌色検出にはYIQ表色系がいいらしいのでそれを使って肌色検出プログラムを作ってみた。しかし、私の部屋では背景も検出されてしまって使い物にならない。まあ壁の色が悪いんですが。実際の演習は、カメラ固定ではないので背景差分を使うことも出来ないし…あーでも演習の背景は風景だからこれでもいいのか…。とりあえず他の表色系での検出を併用する、輪郭情報を利用するなど何か他の方法を考えないといけないかな…。
以下、プログラム抜粋
void FreshDetect(IplImage* img, IplImage* detect_img, int max, int min){ const int maxpx(img->width*img->height); unsigned char b, g, r, i; // BGR -> YIQ // Y = 0.2990 * R + 0.5870 * G + 0.1140 * B // I = 0.5959 * R - 0.2750 * G + 0.3210 * B // Q = 0.2065 * R - 0.4969 * G - 0.2904 * B for(int a = 0; a < maxpx; ++a){ b = static_cast<unsigned char>(img->imageData[a*3+0]); g = static_cast<unsigned char>(img->imageData[a*3+1]); r = static_cast<unsigned char>(img->imageData[a*3+2]); i = static_cast<unsigned char>(0.5959*r - 0.2750*g + 0.3210*b); if( min <= i && i <= max ){ detect_img->imageData[a*3+0] = b; detect_img->imageData[a*3+1] = g; detect_img->imageData[a*3+2] = r; }else{ detect_img->imageData[a*3+0] = 0; detect_img->imageData[a*3+1] = 0; detect_img->imageData[a*3+2] = 0; } } }
前のエントリで動作確認してたWebカメラがUSBケーブルを一度抜き差ししたら認識されなくなった。いや、cvCreateCameraCapture()関数で何か見つけてきてるんだけど、それがカメラではないらしく、cvQueryFrame()関数で取得した物を表示すると縞模様という状態。本当は昨日何かプログラムを書きたかったんだけど、そのせいで何も出来なかった...
ようやく認識されるようになったので、他に同じ症状の人がいたときのために残しておく。
USB接続がどっかおかしいのかなあと思って、AMCAPというWebカメラ付属ソフトで見ると映像が表示できているので接続は問題ない。ただ、そのAMCAPではデバイスを選択する欄があり、そこにはBWC-130H01の他にも、NEC 61153 Captureというデバイスがあり、それを選択すると砂嵐が表示される。ということはOpenCVはこのNEC 61153 Captureを拾ってきているのかな?
じゃあ消しちゃえばいいじゃん。ということでデバイススマネージャでNEC 61153 Captureを削除しようと思ったんだけど、見つからない。で、ぐぐってみたらWebカメラの選択が出来ません。というスレッドを見つけた。
> デバイスマネージャから、NEC 61153・・・タブを無効に設定し、メッセンジャーのファイアーウォールも外し、プロキシの設定をしないでやっと映像が映りました!!!
> このデスクにはTVチューナーが内臓されているので、やはりロジクール以外の映像デバイスが邪魔をしていたようです。
> 映像デバイスを無効にしたので、メッセンジャーの設定でカメラもロジクールを選択することが出来ました。
そういや、俺のパソコンもキャプチャ(GV-MVP/RX3)はいってるな、と思ってデバイスマネージャの『サウンド、ビデオ、およびゲームコントローラ』内のI-O DATA GV-MVP/RX3を無効にして再起動したら、OpenCVがまたカメラを認識してくれるようになった。
今日こそは何かプログラムを...