|
分類:[C/C++]
プログラミングを始めて1年程の初心者の質問です。
VisualC++2008でC++言語で開発しています。
現在、ARToolKitとOpenCVとを組み合わせたプログラムを作っています。
それは動くようになり(問題点も多々あるでしょうが)良かったのですが、
それと同時に加速度センサーのプログラムも動かして、その情報を使いたいと
考えております。
その方法として、マルチスレッドを採用することにしました。
そして、作ってみたのはいいのですが、何故かargMainLoopの関数に到達した
時点でプログラムが止まって(こちらの方のスレッドだけが止まり、もう一つのwii関数の中は動く)
しまいます。単純なマルチスレッドのプログラム等を書いたりインターネットで調べたりして、
自分なりには考えてみたのですが、完全につまづいてしまいましたので、質問が悪いかとは思いますが、
どなたかご回答、もしくはヒントを頂けないでしょうか?
#include<windows.h> //windowsプログラムの際付けることがある
#include<stdio.h>
#include<process.h>
#include<GL/gl.h> //OpenGLのヘッダファイルを読み込む
#include<Gl/glu.h>
#include<GL/glut.h>
#include<AR/ar.h> //ARToolKitのヘッダファイルを読み込む
#include<AR/param.h>
#include<AR/video.h>
#include<AR/gsub.h>
#include<cv.h>
#include<highgui.h>
//グローバル変数
char *vconf_name="Data/WDM_camera_flipV.xml"; //ビデオデバイスの設定
char *cparam_name="Data/camera_para.dat"; //カメラパラメータファイル
char *patt_name="Data/patt.elenew"; //パターンファイル
int patt_id; //パターンID
double patt_trans[3][4]; //座標変換行列
double patt_center[2]={0.0, 0.0}; //パターン中心座標
double patt_width=80.0; //パターンのサイズ
int thresh=100; //二値化の閾値
//プロトタイプ宣言
void MainLoop(void);
void KeyEvent(unsigned char key, int x, int y);
void MouseEvent(int button, int state, int x, int y);
void Cleanup(void);
void DrawObject(void);
void wii(LPVOID pParam); //つけた!!!!
void func(LPVOID pParam); //つけた!!!
//マクロ・大域変数等の設定
#define Page 5 //最大ページ数
IplImage *sourceImage; //現在の画像を格納する
IplImage *sourceImages[Page+1]; //全ての画像を個々に格納する配列
int page; //現在のページ数
IplImage *TransImage; //平行移動後の画像を格納する
IplImage *ScaleImage; //拡大後の画像を格納する
int opencv(double x, double y, double z){
//中身は省略
return 0;
}
int main(int argc, char **argv){ //引数はコマンドライン
ARParam cparam; //カメラパラメータ
ARParam wparam; //カメラパラメータ(作業用変数)
int xsize,ysize; //画像サイズ
//HANDLE hThread[2];
glutInit(&argc, argv); //GLUTの初期化
if(arVideoOpen(vconf_name)<0){ //ビデオデバイスの設定
printf("video devise error!");
return -1; //プログラムの終了
}
//計算に用いるパラメータをグローバル変数で内部管理している。ファイルから値を読み込んで
//内部の変数にセットする必要があるが、ファイルを読み込んだ後、カメラ画像の解像度に合わせて
//変更してからセットをしなければならない。よって次の4ステップを踏む。
if(arVideoInqSize(&xsize, &ysize)<0) return -1; //画像サイズの習得
if(arParamLoad(cparam_name, 1, &wparam)<0){ //カメラパラメータファイルのロード
printf("miss reading camera parameta");
return -1;
}
arParamChangeSize(&wparam, xsize, ysize, &cparam); //画像サイズに合わせてカメラパラメータを変更
arInitCparam(&cparam); //カメラパラメータをセット
if( (patt_id=arLoadPatt(patt_name))<0 ){ //パターンファイルのロード(パターンごとにIDを割り当てる)
printf("miss reading patten file");
return -1;
}
//画像の読み込み(ページごとに)
sourceImages[0] = cvLoadImage("img0.jpg", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);
sourceImages[1] = cvLoadImage("img1.jpg", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);
sourceImages[2] = cvLoadImage("img2.jpg", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);
sourceImages[3] = cvLoadImage("img3.jpg", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);
sourceImages[4] = cvLoadImage("img4.jpg", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);
sourceImages[5] = cvLoadImage("img5.jpg", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);
sourceImages[6] = cvLoadImage("img6.jpg", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);
int jj;
for(jj=0; jj<=Page+1; jj++){
if(sourceImages[jj]==NULL){
puts("画像が読み込めませんでした");
return -1;
}
}
sourceImage = sourceImages[page]; //初期画像の選択
argInit(&cparam, 1.0, 0, 0, 0, 0); //ウインドウの設定(3つ目の引数はフルスクリーンモード1(On)0(Off))
//フルスクリーンモードにする場合は、二つ目の引数の拡大率も変更しないといけない
arVideoCapStart(); //ビデオキャプチャーの開始
cvNamedWindow("ScaleChange", CV_WINDOW_AUTOSIZE);
//!!!!!!!!!!!!!!!!!!!!マルチスレッドの開始!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
HANDLE hThread[2];
hThread[0] = (HANDLE)_beginthread(func,0,NULL); //スレッド1作成
hThread[1] = (HANDLE)_beginthread(wii,0,NULL); //スレッド2作成
//スレッド1、2終了待ち
WaitForMultipleObjects(2,hThread,TRUE,INFINITE); //どういう意味??
//ハンドルクローズ
CloseHandle(hThread[0]);
CloseHandle(hThread[1]);
//argMainLoop(MouseEvent, KeyEvent, MainLoop); //メインループの開始(マウス入力・キーボード入力・メインループ関数)
return 0;
}
void wii(LPVOID pParam){
while(1){
Sleep(100);
puts("aaa");
}
}
void func(LPVOID pParam){
argMainLoop(MouseEvent, KeyEvent, MainLoop); //メインループの開始(マウス入力・キーボード入力・メインループ関数)
}
void MainLoop(void){
ARUint8 *image;
ARMarkerInfo *marker_info;
int marker_num;
int j,k;
if( (image=(ARUint8 *)arVideoGetImage()) ==NULL){ //カメラ画像の習得
arUtilSleep(2); //失敗したら(画像の準備ができていなければ)少し待って
return; //mainループ最初から(一度抜ける)
}
//カメラ画像の描写(レンズの歪みの補正も行うため、次の2ステップが必要)
argDrawMode2D(); //2次元画像を描写するための準備
argDispImage(image, 0, 0); //画像を描写
//marker_infoについて
//area(マーカ領域の画素数=面積) id(パターンID) dir(方向1〜3のいずれか)
//cf(信頼度) pos[2](マーカーの中心座標) line[4][3](直線の式(ax+by+c=0)*4辺)
//vertex[4][2](頂点座標(x,y)*4辺)
if(arDetectMarker(image, thresh, &marker_info, &marker_num)<0){ //マーカーの検出と認識
Cleanup();
exit(0); //変ならプログラム終了
}
arVideoCapNext(); //次の画像のキャプチャー指示(画像の描写とマーカ検出が終われば指令を出さないといけない)
//マーカーの一致度の比較(自分で書く!!)
k=-1;
for(j=0;j<marker_num;j++){
if(patt_id==marker_info[j].id){
if(k==-1) k=j;
else if(marker_info[k].cf<marker_info[j].cf) k=j;
}
}
//マーカーを近づけすぎると急に値が飛ぶ!!
if(k!=-1){ // マーカー情報ポインタ、マーカーの原点位置、マーカーサイズ(mm)、マーカー・カメラ間の座標変換行列
arGetTransMat(&marker_info[k], patt_center, patt_width, patt_trans);
printf("距離:%f\n", patt_trans[2][3]); //マーカーとの距離を表示
printf("x:%f y:%f\n", patt_trans[0][3], patt_trans[1][3]); //縦・横を表示
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
if(100<patt_trans[2][3] && patt_trans[2][3]<1000 && -300<patt_trans[0][3] && patt_trans[0][3]<300 && -200<patt_trans[1][3] && patt_trans[1][3]<200)
opencv(patt_trans[0][3], patt_trans[1][3], patt_trans[2][3]);
DrawObject(); //3Dオブジェクトの描写
}
argSwapBuffers(); //バッファの内容を画面に表示(ダブルバッファの考え方で、表と裏画像を交換する)
}
void DrawObject(void){ //3Dオブジェクトの描写を行う関数
double gl_para[16];
argDrawMode3D();
argDraw3dCamera(0,0);
argConvGlpara(patt_trans, gl_para);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixd(gl_para);
glTranslatef(0.0, 0.0, 20.0);
glColor3f(0.0, 1.0, 0.0);
glLineWidth(3.0);
glutWireCube(40.0);
}
void KeyEvent(unsigned char key, int x, int y){ //キーボード入力処理関数
if(key==0x1b){
Cleanup();
exit(0);
}
else if(key==0x09){
if(--page<0)
exit(0);
puts("前の画像を表示します");
sourceImage = sourceImages[page]; //注目画像の変更
argMainLoop(MouseEvent, KeyEvent, MainLoop);
}
else if(key==0x20){
if(++page>Page)
exit(0);
puts("次の画像を表示します");
sourceImage = sourceImages[page]; //注目画像の変更
argMainLoop(MouseEvent, KeyEvent, MainLoop);
}
}
void MouseEvent(int button, int state, int x, int y){ //マウス入力処理関数
printf("button:%d, statement:%d, zahyou:(x,y)=(%d, %d)\n", button, state, x, y);
}
void Cleanup(void){ //終了処理関数
arVideoCapStop();
arVideoClose();
argCleanup();
cvReleaseImage(&sourceImage);
cvReleaseImage(sourceImages); //配列の先頭ポインタを渡して開放すればよい!
cvReleaseImage(&TransImage);
cvReleaseImage(&ScaleImage);
cvDestroyWindow("ScaleChange");
}
|