#include#include #include #include #include #include #include #include #include #include #include #include #include "glut.h" char *deviceName; char *_progName; static int sWinid1, sWinid2; static int action = 0; #ifndef MAXNAMLEN #define MAXNAMLEN 1024 #endif #define KEEP 1 /* 運動を表す文字定数 */ #define UP 2 #define DOWN 3 #define RIGHT 4 #define LEFT 5 #define FORWARD 6 #define BACK 7 #define ROTX 8 #define ROT_X 9 #define ROTY 10 #define ROT_Y 11 #define ROTZ 12 #define ROT_Z 13 /* 抽出した点に関する情報を格納するための構造体 */ struct point { int rsize; /* 赤色の球の面積 */ int gsize; /* 緑色の球の面積 */ int row_r; /* 赤色の球の重心のy座標 */ int col_r; /* 赤色の球の重心のx座標 */ int row_g; /* 緑色の球の重心のy座標 */ int col_g; /* 緑色の球の重心のx座標 */ int left_r; /* 赤色の球の直径の左端の点のx座標 */ int right_r; /* 赤色の球の直径の右端の点のx座標 */ int up_r; /* 赤色の球の直径の上端の点のy座標 */ int down_r; /* 赤色の球の直径の下端の点のy座標 */ int left_g; /* 緑色の球の直径の左端の点のx座標 */ int right_g; /* 緑色の球の直径の右端の点のx座標 */ int up_g; /* 緑色の球の直径の上端の点のy座標 */ int down_g; /* 緑色の球の直径の下端の点のy座標 */ }; VLServer svr; VLBuffer buffer; int frames = 0; VLPath path; VLNode src, drn; int xsize; int ysize; int histrow_r[1024]; /* 赤色の成分についてのx方向のヒストグラム */ int histcol_r[1024]; /* 赤色の成分についてのy方向のヒストグラム */ int histrow_g[1024]; /* 緑色の成分についてのx方向のヒストグラム */ int histcol_g[1024]; /* 緑色の成分についてのy方向のヒストグラム */ int thres_r,thres_g; /* 色の識別を行なう際に用いるしきい値 */ void docleanup(int); void ProcessEvent(VLServer, VLEvent *, void *); void calc_hist(short, short, int, int); struct point sample_point(int, int, int *, int *, int *, int *); void put_point(struct point); int interpret_motion(struct point, struct point); void change_model(int, int); void myinit(void); void idleFunc(void); void myReshape1(int, int); void myReshape2(int, int); void display(void); void keyboard(unsigned char, int, int); /* ヒストグラムを生成する関数 */ void calc_hist(short r,short g,int x,int y) { if (r > g && r > thres_r) { histrow_r[y] ++; histcol_r[x] ++; } if (r < g && g > thres_g) { histrow_g[y] ++; histcol_g[x] ++; } } /* 画像ファイルからのデータの読み込み */ void DumpImage(char *data, int xinputsize, int yinputsize) { unsigned short rbuf[1024]; unsigned short gbuf[1024]; unsigned short bbuf[1024]; int x, y; /* 初期化 */ for (y=0; y reason) { case VLTransferComplete: /* First Window */ glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); glutInitWindowSize(xsize,ysize); glutInitWindowPosition(0,0); sWinid1 = glutCreateWindow ("point"); glClearColor(0.0, 0.0, 0.0, 0.0); glutIdleFunc(idleFunc); glutReshapeFunc(myReshape1); glutDisplayFunc(display); /* Second Window */ glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); glutInitWindowSize(400,400); glutInitWindowPosition(0,500); sWinid2 = glutCreateWindow ("model"); myinit(); /* glClearColor(0.9, 0.9, 0.8, 0.0);*/ glClearColor(0.0, 0.0, 0.0, 0.0); glutIdleFunc(idleFunc); glutKeyboardFunc(keyboard); glutReshapeFunc(myReshape2); glutDisplayFunc(display); glutMainLoop(); docleanup(0); break; case VLTransferFailed: fprintf(stderr,"%s: Transfer failed.\n",_progName); docleanup(1); break; default: break; } } void docleanup(int ret) { vlEndTransfer(svr, path); vlDeregisterBuffer(svr, path, drn, buffer); vlDestroyBuffer(svr, buffer); vlDestroyPath(svr, path); vlCloseVideo(svr); exit(ret); } /* 光源の設定 */ void myinit (void) { GLfloat mat_ambient[] = {0.0, 0.0, 1.0, 1.0 }; GLfloat mat_diffuse[] = { 0.4, 0.4, 0.4, 1.0 }; GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat mat_shininess[] = { 10.0 }; GLfloat light_ambient[] = { 0.0, 0.0, 0.0, 1.0 }; GLfloat light_diffuse[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat light_specular[] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat lmodel_ambient[] = { 0.7, 0.7, 0.7, 1.0 }; glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient); glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient); glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse); glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular); glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lmodel_ambient); glEnable(GL_LIGHTING); glEnable(GL_LIGHT0); glDepthFunc(GL_LESS); glEnable(GL_DEPTH_TEST); glShadeModel(GL_FLAT); } void idleFunc(void) { glutSetWindow( sWinid1 ); /* Change Window ID */ glutPostRedisplay(); glutSetWindow( sWinid2 ); /* Change Window ID */ glutPostRedisplay(); } void myReshape1(int w, int h) { glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluOrtho2D(0.0, 320.0, -240.0, 0.0); glutPostRedisplay(); } void myReshape2(int w, int h) { GLfloat light_position[] = { 1.0, 1.0, 1.0, 0.0 }; glMatrixMode (GL_PROJECTION); glLoadIdentity (); gluPerspective (40.0, (GLfloat) w/(GLfloat) h, 1.0, 20.0); glMatrixMode (GL_MODELVIEW); glViewport (0.0, 0.0, w, h); glTranslatef (0.0, 0.0, -8.0); glLightfv(GL_LIGHT0, GL_POSITION, light_position); glutPostRedisplay(); } void display(void) { VLInfoPtr info; char *dataPtr; int motion; struct point newpoint; static struct point oldpoint; static int premotion = KEEP; /* 初期値の設定 */ if (action == 1) { frames = 0; premotion = KEEP; } do { sginap(1); info = vlGetNextValid(svr, buffer); } while (!info); /* フレームへのポインタの取得 */ dataPtr = vlGetActiveRegion(svr, buffer, info); frames++; /* 入力画像の取り込み */ DumpImage(dataPtr, xsize, ysize); /* 識別子の特徴抽出 */ newpoint = sample_point(xsize, ysize, histrow_r, histcol_r, histrow_g, histcol_g); /* printf("rsize = %d\n",newpoint.rsize); printf("gsize = %d\n",newpoint.gsize); printf("row_r = %d\n",newpoint.row_r); printf("col_r = %d\n",newpoint.col_r); printf("row_g = %d\n",newpoint.row_g); printf("col_g = %d\n",newpoint.col_g); printf("left_r = %d\n",newpoint.left_r); printf("right_r = %d\n",newpoint.right_r); printf("up_r = %d\n",newpoint.up_r); printf("down_r = %d\n",newpoint.down_r); printf("left_g = %d\n",newpoint.left_g); printf("right_g = %d\n",newpoint.right_g); printf("up_g = %d\n",newpoint.up_g); printf("down_g = %d\n",newpoint.down_g);*/ /* 特徴点の描画 */ glutSetWindow(sWinid1); glClear (GL_COLOR_BUFFER_BIT); put_point(newpoint); glFlush(); /* リセットが押されていない場合 */ if (action == 0) { /* 基準値の設定 */ if (frames == 1) oldpoint = newpoint; /* 運動の認識 */ motion = interpret_motion(oldpoint,newpoint); if (motion != KEEP) oldpoint = newpoint; printf("*****frames = %d***** motion = %d\n",frames,motion); /* 3D_CGの変更および描画 */ glutSetWindow(sWinid2); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); if (frames != 1) change_model(motion, premotion); glutSwapBuffers(); glFlush(); if (motion != KEEP) premotion = motion; } /* バッファの解放 */ vlPutFree(svr, buffer); } void keyboard(unsigned char ch, int x, int y) { switch (ch) { case 27 : /* exit */ exit(0); break; case 's': /* stop */ action = 1; break; case 'b' : /* begin */ action = 0; break; } }