OpenCVでのテンプレートマッチングについて

このQ&Aのポイント
  • OpenCVを使ったテンプレートマッチングで「Bad argument(Array should be CvMat or IplImage)in function cvGetSize」というエラーが発生しています。
  • テンプレートマッチングを行う際に、画像の読み込みの部分でエラーが発生しています。
  • 現在、OpenCVのテンプレートマッチングを用いた物体追跡を試みていますが、エラーが出てしまいます。
回答を見る
  • ベストアンサー

OpenCVでのテンプレートマッチングについて

質問させてください。 現在画像処理ライブラリのOpenCVを使ってテンプレートマッチングを用いた物体追跡しようと考えています。 今回作ってみたのですがどうしても、 「Bad argument(Array should be CvMat or IplImage)in function cvGetSize」 というエラーが出てしまいます。 おそらく画像の読み込みの部分だとは思うのですが・・・・ よろしくお願いします。 ソースプログラムは次のようになってます。 int main( void ) { int device1 = 0; int key=0; double max_interlinkage=0; double min_interlinkage=0; CvPoint max_point; CvPoint min_point; CvPoint corner_point; char windowNameTemplate[] = "Template"; // テンプレート画像を表示するウィンドウの名前 char windowNameDestination[] = "Destination"; // マッチング結果を表示するウィンドウの名前 //videoInputオブジェクト videoInput VI; //利用可能なキャプチャデバイス数を取得 int numDevices = VI.listDevices(); //キャプチャデバイスが見つからなかったら終了 if(numDevices == 0) { cerr << "[Error] Capture device not found!!" << endl; exit(-1); } //デバイス初期化(今回はデバイスID = 0,CAPTURE_WIDTH x CAPTURE_HEIGHTでキャプチャ) VI.setupDevice(device1, CAPTURE_WIDTH, CAPTURE_HEIGHT); IplImage *templateImage = cvLoadImage( "C:/Documents and Settings/ito/My Document/My Pictures/temp.jpg", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR ); IplImage *tempGray = cvCreateImage( cvGetSize(templateImage), IPL_DEPTH_8U, 1 ); if ( templateImage == NULL ) { // 画像が見つからなかった場合 printf( "画像が見つかりません\n" ); return -1; } cvCvtColor(templateImage,tempGray,CV_BGR2GRAY); IplImage *frameImage = cvCreateImage( cvSize(CAPTURE_WIDTH, CAPTURE_HEIGHT), IPL_DEPTH_8U, 3 ); // 画像用IplImage IplImage *grayImage = cvCreateImage( cvSize(CAPTURE_WIDTH, CAPTURE_HEIGHT), IPL_DEPTH_8U, 1 ); // 元画像をグレースケール化した画像用IplImage IplImage *dstImage = cvCreateImage( cvSize( frameImage->width - templateImage->width + 1, frameImage->height - templateImage->height + 1 ), IPL_DEPTH_32F, 1 ); // 相違度マップ画像用IplImage memcpy(frameImage->imageData, VI.getPixels(device1, false , true), frameImage->imageSize); cvCvtColor(templateImage,tempGray,CV_BGR2GRAY); //ループ開始 while(1){ //カメラ・デバイスから画像取得 memcpy(frameImage->imageData, VI.getPixels(device1, false , true), frameImage->imageSize); cvCvtColor(frameImage,grayImage,CV_BGR2GRAY); // テンプレートマッチングを行う cvMatchTemplate( grayImage, tempGray, dstImage, CV_TM_CCOEFF_NORMED ); // テンプレートが元画像のどの部分にあるのかという情報を得る cvMinMaxLoc( dstImage, &min_interlinkage, &max_interlinkage, &min_point, &max_point, NULL ); if(max_interlinkage>0.75){ corner_point=cvPoint(max_point.x+templateImage->width , max_point.y+templateImage->height); printf("point x=%d ",max_point.x+templateImage->width); printf("point y=%d ",max_point.y+templateImage->height); cvRectangle(frameImage , max_point , corner_point , CV_RGB(255,0,0) , LINE_THICKNESS , LINE_TYPE , SHIFT); printf("\n"); }else{ printf("point Lost\n"); } // ウィンドウを生成する cvNamedWindow( windowNameTemplate, CV_WINDOW_AUTOSIZE ); cvNamedWindow( windowNameDestination, CV_WINDOW_AUTOSIZE ); // 画像を表示する cvShowImage( windowNameTemplate, templateImage ); cvShowImage( windowNameDestination , frameImage ); //キー入力 key = cvWaitKey(1); if(key=='q'){ break; }else if(key=='c'){ cvSaveImage("image/frame.bmp",frameImage); } }

質問者が選んだベストアンサー

  • ベストアンサー
回答No.1

 こんばんは。  ファイルのロードに失敗しているのではないでしょうか。パスをもう一度確認してみましょう。  手っ取り早く、配下のフォルダに入れてtemp.jpgのファイル名だけでロード出来る様にして置いた方が、無難かもしれません。  原因は、  ロードに失敗  ↓  templateImage=NULL  ↓  cvGetSize(templateImage)に渡される  ↓  「Bad argument(Array should be CvMat or IplImage)in function cvGetSize」  です。

berserk_00
質問者

お礼

アドバイスありがとうございました! 今日実際に試したところうまく実行することができました!

関連するQ&A

  • 解像度と誤差について

    失礼します。 OpenCVという画像処理ライブラリを用いてテンプレートマッチング法を使った物体追跡を行っています。 今、観測画面内でテンプレート画像とマッチングした箇所を矩形で囲んでその部分の座標X,Y(単位[pixel])を随時コマンドプロンプトに表示させています。 このとき、矩形で囲んでいる物体が一定の場所に置いてあっても、コマンドプロンプト上に表示させている座標にプラスマイナス2[pixel]ぐらいの誤差が生じてしまいます。 この誤差というのは[pixel]→[mm]に単位変換した場合どのくらいの誤差になるのでしょうか?? パソコンはWindows XPでモニターサイズは普通の15インチ(72dpi?)だと思います。観測画面は640×480の解像度でキャプチャーしています。 どうでもいいかもしれませんがmain内のテンプレートマッチングに関係した分のプログラムだけ貼っておきます。 よろしくお願いします。 int main( void ) { int device1 = 0; int key=0; double max_interlinkage=0; double min_interlinkage=0; int X1 = 351; int X2 = 351; int Y1 = 349; int Y2 = 349; CvPoint end_point1; CvPoint end_point2; CvPoint max_point; CvPoint min_point; CvPoint corner_point; char windowNameTemplate[] = "Template"; // テンプレート画像を表示するウィンドウの名前 char windowNameDestination[] = "Destination"; // マッチング結果を表示するウィンドウの名前 //videoInputオブジェクト videoInput VI; //利用可能なキャプチャデバイス数を取得 int numDevices = VI.listDevices(); //キャプチャデバイスが見つからなかったら終了 if(numDevices == 0) { cerr << "[Error] Capture device not found!!" << endl; exit(-1); } //デバイス初期化(今回はデバイスID = 0,CAPTURE_WIDTH x CAPTURE_HEIGHTでキャプチャ) VI.setupDevice(device1, CAPTURE_WIDTH, CAPTURE_HEIGHT); IplImage *templateImage = cvLoadImage( "C:/Documents and Settings/ito/デスクトップ/cv_samples/image/temp.jpg", CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR ); IplImage *tempGray = cvCreateImage( cvGetSize(templateImage), IPL_DEPTH_8U, 1 ); if ( templateImage == NULL ) { // 画像が見つからなかった場合 printf( "画像が見つかりません\n" ); return -1; } cvCvtColor(templateImage,tempGray,CV_BGR2GRAY); IplImage *frameImage = cvCreateImage( cvSize(CAPTURE_WIDTH, CAPTURE_HEIGHT), IPL_DEPTH_8U, 3 ); // 画像用IplImage IplImage *grayImage = cvCreateImage( cvSize(CAPTURE_WIDTH, CAPTURE_HEIGHT), IPL_DEPTH_8U, 1 ); // 元画像をグレースケール化した画像用IplImage IplImage *dstImage = cvCreateImage( cvSize( frameImage->width - templateImage->width + 1, frameImage->height - templateImage->height + 1 ), IPL_DEPTH_32F, 1 ); // 相違度マップ画像用IplImage memcpy(frameImage->imageData, VI.getPixels(device1, false , true), frameImage->imageSize); cvCvtColor(templateImage,tempGray,CV_BGR2GRAY); //ループ開始 while(1){ //カメラ・デバイスから画像取得 memcpy(frameImage->imageData, VI.getPixels(device1, false , true), frameImage->imageSize); cvCvtColor(frameImage,grayImage,CV_BGR2GRAY); end_point1=cvPoint(X1,Y1); end_point2=cvPoint(X2,Y2); cvRectangle(frameImage , end_point1 , end_point2 , CV_RGB(255,0,0) , LINE_THICKNESS , LINE_TYPE , SHIFT); // テンプレートマッチングを行う cvMatchTemplate( grayImage, tempGray, dstImage, CV_TM_CCOEFF_NORMED ); // テンプレートが元画像のどの部分にあるのかという情報を得る cvMinMaxLoc( dstImage, &min_interlinkage, &max_interlinkage, &min_point, &max_point, NULL ); if(max_interlinkage>0.60){ corner_point=cvPoint(max_point.x+templateImage->width , max_point.y+templateImage->height); printf("point x=%d ",max_point.x+templateImage->width); printf(" y=%d ",max_point.y+templateImage->height); cvRectangle(frameImage , max_point , corner_point , CV_RGB(255,0,0) , LINE_THICKNESS , LINE_TYPE , SHIFT); printf("\n"); }else{ printf("point Lost\n"); }

  • openCVの動画書き込みのプログラムを作っているのですが・・・

    openCVの動画書き込みのプログラムを作っているのですが・・・ openCVで、読み込んだ動画(元動画)を背景差分法で2値化処理して出来た動画を保存する、というプログラムを作っています。 しかし、保存された動画を見ると、上手く書き込まれていません。というのも、元動画は15秒あるのですが、保存された動画を見ると、わずか2秒ほどで再生が終わってしまいます。 以下がプログラムのソースです。 #include <stdio.h> #include <cv.h> #include <cxcore.h> #include <highgui.h> #define THRESHOLD_MAX_VALUE 255 #define THRESHOLD 45 #define WIDTH 960 #define HEIGHT 540 int main( int argc, char **argv ){ int key; CvCapture *capture = NULL; IplImage *frameImage; IplImage *backgroundImage = cvCreateImage( cvSize(WIDTH, HEIGHT), IPL_DEPTH_8U, 1 ); IplImage *grayImage = cvCreateImage( cvSize(WIDTH, HEIGHT), IPL_DEPTH_8U, 1 ); IplImage *differenceImage = cvCreateImage( cvSize(WIDTH, HEIGHT), IPL_DEPTH_8U, 1 ); IplImage *binaryImage = cvCreateImage( cvSize(WIDTH, HEIGHT), IPL_DEPTH_8U, 1 ); double fps = 30.0; CvVideoWriter* VideoWriter = cvCreateVideoWriter("binary.avi", CV_FOURCC('F','L','V','1'), fps, cvSize(WIDTH, HEIGHT), 0 ); if ( ( capture = cvCreateFileCapture( "00011.avi" ) ) == NULL ) { printf( "File Not Found\n" ); return -1; } frameImage = cvLoadImage("haikei.bmp"); if(frameImage == NULL){ printf("Can't Get\n"); return -1; } cvCvtColor( frameImage, backgroundImage, CV_BGR2GRAY ); while ( 1 ) { frameImage = cvQueryFrame( capture ); if ( frameImage == NULL ){ break; } cvCvtColor( frameImage, grayImage, CV_BGR2GRAY ); cvAbsDiff( grayImage, backgroundImage, differenceImage ); cvThreshold( differenceImage, binaryImage, THRESHOLD, THRESHOLD_MAX_VALUE, CV_THRESH_BINARY ); cvWriteFrame(VideoWriter, binaryImage); key = cvWaitKey( 10 ); if ( key == 'q' ) { break; } } cvReleaseCapture( &capture ); cvReleaseVideoWriter( &VideoWriter ); cvReleaseImage( &backgroundImage ); cvReleaseImage( &grayImage ); cvReleaseImage( &differenceImage ); cvReleaseImage( &binaryImage ); return 0; } 抽出している際に、プロンプト画面に Compiler did not align stack variables.~ と出てきます。 また、非圧縮などでやると再生が出来ません。 PC環境はWindowsXPです。 助けてください!!

  • opencvを用いた二値画像のアクセスと座標の取得

    いつもお世話になっています。 opencvを用いたプログラムを作成しています。 真ん中に大きな塗りつぶされた●が1つあるカラー画像を二値画像に変換して、●の部分のすべての座標をとりたいと考えています。(●は大きいので1ピクセルではありません。●を構成しているピクセルの座標すべてをとるといった感じです。) 今、途中まで作成したのですが間違っているところがあると考えられるので、エラーは出ないのですがプログラムが正常に動きません。このプログラム内での間違いであるとは考えられるので、間違っている部分を教えてもらえないでしょうか? よろしくお願いします。 //元のカラー画像 IplImage* image = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 3); IplImage* gray_image = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1); //二値画像 IplImage* niti_image = cvCreateImage(cvSize(width, height), IPL_DEPTH_8U, 1); //座標を入れるための配列 int test_width[500]; int test_height[500]; //カラー画像ここでimage画像に大きな●を書きました。これ以降は●がimageに存在するものとして考えてくださいお願いします cvDrawContours( image, hand_contour[0], CV_RGB (0, 0, 0), CV_RGB (0, 0, 0), -1, CV_FILLED, 8 ,cvPoint(0,0)); //グレースケールの作成 cvCvtColor(image,gray_image,CV_BGR2GRAY); // 画像の二値化【判別分析法(大津の二値化)】 cvThreshold (gray_image, niti_image, 90, 255, CV_THRESH_BINARY); int k = 0;      // 左上から順番に画像を見ていく for( int y = 0; y < niti_image->height; y++){ for(int x = 0; x < niti_image->width; x++){ //もし黒色の値が入っていたら配列に座標を代入する if(niti_image->imageData[y * niti_image->widthStep + x * niti_image->nChannels] == 0){ test_width[k] = x; test_height[k] = y;   k++;             }//if } }

  • OpenCV 2値化について

    いつもお世話になっております。 画像の2値化(黒は全てゼロ、白は全て255)をした画像bw_imgを用意して 左上端から11×11サイズのROIに切り取って決まった処理をかけていこうとしていますが、 2値化した画像をROIで保持させることができず、困っています。 int main() { //画像の2値化処理用変数 IplImage *src_img = 0, *dst_img = 0, *bw_img = 0; IplImage *src_img_gray = 0; IplImage *tmp_img, *out_img, *lap_img; CvMemStorage *storage = cvCreateMemStorage(0); CvSeq *contours = 0; // (1)画像を読み込み、グレースケール化(src_img_gray)、二値化(tmp_img) src_img = cvLoadImage("C:\\Users...\\サンプル画像\\sample.jpg", CV_LOAD_IMAGE_COLOR); tmp_img = cvCreateImage(cvGetSize(src_img), IPL_DEPTH_8U, 1); src_img_gray = cvCreateImage(cvGetSize(src_img), IPL_DEPTH_8U, 1);//もとはIPL_DEPTH_8U cvCvtColor(src_img, src_img_gray, CV_BGR2GRAY); cvAdaptiveThreshold(src_img_gray, tmp_img, 255, CV_ADAPTIVE_THRESH_GAUSSIAN_C, CV_THRESH_BINARY, 7, 8); //11×11 走査用変数 dst_img = cvCreateImage(cvGetSize(tmp_img), IPL_DEPTH_8U, 1); bw_img = cvCreateImage(cvGetSize(tmp_img), IPL_DEPTH_8U, 1); out_img = cvCreateImage(cvGetSize(tmp_img), IPL_DEPTH_8U, 1); cvThreshold(tmp_img, bw_img, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU); for (x = 0; x < bw_img->width; x++){ // x 座標を 1ピクセルずつ進める for (y = 0; y < bw_img->height; y++){ // y 座標を 1ピクセルずつ進める //(1) 11×11ピクセルに切り取って2値化する。 cvCopy(bw_img, dst_img); lap_img = cvCreateImage(cvSize(11, 11), IPL_DEPTH_8U, 1); CvMat *sub = cvCreateMatHeader(11, 11, CV_8UC1); cvGetSubRect(bw_img, sub, cvRect(y, x, 11, 11)); //コピー画像から11×11切り取り。 cvThreshold(sub, lap_img, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU); //2値化、結果はlap_img. uchar iro = lap_img->imageData[lap_img->widthStep * (y + 6) + (x + 6)]; if (iro ==0){ →ここでどうみても黒なのにiroに「238」「71」などの値が入っています。 roiで切り取ったlap_imgが2値になっていません。 何が問題で2値化できていないのでしょうか。 どうすると2値化した画像(lap_img)を決まったサイズのウィンドウで扱えるでしょうか。 もしおわかりでしたらヒントでも結構ですのでぜひ教えてください。 よろしくお願いします。

  • セグメンテーション違反なってしまいます。

    LinuxでopenCVを使っているのですが、どうしてもセグメンテーション違反が出てしまいます。 画像の輪郭座標の表示をさせたいのですが、どうしたらセグメンテーション違反がとれるのでしょうか? ちなみにプログラムは、 #include<cv.h> #include<stdio.h> #include<cxcore.h> #include<highgui.h> #include<stdio.h> void GetContourFeature(CvSeq *Contour); #define THRESHOLD 10 #define THRESHOLD_MAX_VALUE 50 #define MIN_CONTOUR_COUNT 100 #define CONTOUR_MAX_LEVEL 1 #define LINE_THICKNESS 2 #define LINE_TYPE 8 //座標格納用変数 CvPoint *point; CvPoint pt[200000]; //制御点の座標 int main(int argc, char** argv) { char windowNameSource[]="Source"; char windowNameContour[]="Contour"; IplImage *sourceImage=cvLoadImage(arg[0],CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR); if(sourceImage==NULL) { printf("画像が見つかりません\n"); return -1; } IplImage *grayImage=cvCreateImage(cvGetSize(sourceImage), IPL_DEPTH_8U,1); IplImage *binaryImage=cvCreateImage(cvGetSize(sourceImage),IPL_DEPTH_8U,1); IplImage *contourImage=cvCreateImage(cvGetSize(sourceImage),IPL_DEPTH_8U,3); cvCvtColor(sourceImage,grayImage,CV_BGR2GRAY); cvThreshold(grayImage,binaryImage,THRESHOLD,THRESHOLD_MAX_VALUE, CV_THRESH_BINARY); contourImage=cvCloneImage(sourceImage); CvMemStorage *storage = cvCreateMemStorage(0); CvSeq *contours=NULL; CvSize size = cvGetSize(sourceImage); //領域検出用の画像 IplImage* img_tmp = cvCreateImage(size,8,1); int contour_num = cvFindContours(binaryImage,storage, &contours,sizeof(CvContour),CV_RETR_LIST, CV_CHAIN_APPROX_NONE, cvPoint(0,0)); CvPoint ptMaxDist = cvPoint(-1,-1); double maxValue = 0.0; if(contour_num){ //距離変換画像 IplImage* img_dist = cvCreateImage(size,IPL_DEPTH_32F,1); IplImage* img_dist_norm = cvCreateImage(size,IPL_DEPTH_8U,1); //距離変換 cvDistTransform(binaryImage,img_dist,CV_DIST_L2,3,NULL,NULL); //0-255に正規化 cvNormalize(img_dist,img_dist_norm,0.0,255.0,CV_MINMAX,NULL); //最大距離の値と座標を取得する cvMinMaxLoc(img_dist,0,&maxValue,0,&ptMaxDist,0); cvReleaseImage(&img_dist); cvReleaseImage(&img_dist_norm); } //最大距離の点を持つ輪郭線を探す CvSeq* contour_max = NULL; if((ptMaxDist.x >= 0) && (ptMaxDist.x < size.width) && (ptMaxDist.y >= 0) && (ptMaxDist.y < size.height) && (maxValue > 0.0)) { cvZero(img_tmp); CvSeq* c = contours; for(contours=0;c != NULL;c = c -> h_next){ if(c -> total < MIN_CONTOUR_COUNT) continue; //この輪郭線を塗りつぶす cvDrawContours(img_tmp,c,cvScalarAll(255),cvScalarAll(255),CONTOUR_MAX_LEVEL,LINE_THICKNESS,LINE_TYPE,cvPoint(0,0)); //この領域に最大距離の点があるかどうか if(255.0 == cvGetReal2D( img_tmp, ptMaxDist.y, ptMaxDist.x)) { contour_max = c; break; } } cvReleaseImage(&img_tmp); } //この輪郭線を塗りつぶす cvDrawContours(contourImage,contour_max,CV_RGB(255,0,0),CV_RGB(255,0,0),CONTOUR_MAX_LEVEL,LINE_THICKNESS,LINE_TYPE,cvPoint(0,0)); int i; for (i=0;i < contour_max->total; i++){ point = CV_GET_SEQ_ELEM(CvPoint, contour_max, i); pt[i].x = point->x; pt[i].y = point->y; printf("(%d,%d)\n",pt[i].x,pt[i].y); } cvNamedWindow(windowNameSource, CV_WINDOW_AUTOSIZE); cvNamedWindow(windowNameContour, CV_WINDOW_AUTOSIZE); cvShowImage(windowNameSource,sourceImage); cvShowImage(windowNameContour,sourceImage); cvWaitKey(0); cvSaveImage("counter",contourImage); cvReleaseImage(&sourceImage); cvReleaseImage(&grayImage); cvReleaseImage(&contourImage); cvDestroyWindow(windowNameSource); cvDestroyWindow(windowNameContour); return 0; } です。よろしくお願いします。

  • コマンドプロンプトからファイルへの出力

    失礼します。 いまテンプレートマッチングを用いた物体追跡を行っています。 画面内に映っている物体のなかでテンプレート画像とマッチした部分を四角で囲み追跡します、さらにその部分のピクセル座標を随時コマンドプロンプトに表示させています。 そこで質問なのですが、このコマンドプロンプトに表示させている座標をtxtファイルに出力させたいのですが可能でしょうか?? ためしに自分でやってみたのですがうまくいきませんでした。。 よろしければアドバイスお願いします。 以下に関係ある部分のソースコードを載せます。 ofstream fout("matchdata.txt"); if(!fout){ cout<<"ファイルをオープンできませんでした。\n"; return 1; }else{ cout<<"ファイルをオープンしました。\n"; } //ループ開始 while(1){ //カメラ・デバイスから画像取得 memcpy(frameImage->imageData, VI.getPixels(device1, false , true), frameImage->imageSize); cvCvtColor(frameImage,grayImage,CV_BGR2GRAY); // テンプレートマッチングを行う cvMatchTemplate( grayImage, tempGray, dstImage, CV_TM_CCOEFF_NORMED ); // テンプレートが元画像のどの部分にあるのかという情報を得る cvMinMaxLoc( dstImage, &min_interlinkage, &max_interlinkage, &min_point, &max_point, NULL ); if(max_interlinkage>0.60){ corner_point=cvPoint(max_point.x+templateImage->width , max_point.y+templateImage->height); //コマンドプロンプトへの表示 printf("point x=%d ",max_point.x+templateImage->width); printf(" y=%d ",max_point.y+templateImage->height); cvRectangle(frameImage , max_point , corner_point , CV_RGB(255,0,0) , LINE_THICKNESS , LINE_TYPE , SHIFT); printf("\n"); } fout<<"point x= "<<max_point.x+templateImage->width<<" y= "<<max_point.y+templateImage->height; fout.close(); // ウィンドウを生成する cvNamedWindow( windowNameTemplate, CV_WINDOW_AUTOSIZE ); cvNamedWindow( windowNameDestination, CV_WINDOW_AUTOSIZE ); // 画像を表示する cvShowImage( windowNameTemplate, templateImage ); cvShowImage( windowNameDestination , frameImage ); //キー入力 key = cvWaitKey(1); if(key=='q'){ break; }else if(key=='c'){ cvSaveImage("image/frame.bmp",frameImage); } }

  • OpenCV2.4.6で色抽出を行いたい。

    Webカメラから取得した映像を用いて色抽出を行いたいです。 システム開発はVisual Studio 2012で言語はC++です。 OpenCV2.4.6を利用しているのですが、サンプルプログラムが古いバージョンで、OpenCV2.4.6では動かないので以下のプログラムを改良したいです。 参考にしたサイトはこちらです。 http://d.hatena.ne.jp/wah-wah-hawah/20090325/1237996168 以下プログラム #include <cv.h> #include <highgui.h> void GetMaskHSV(IplImage* src, IplImage* mask,int erosions, int dilations) { int x = 0, y = 0; uchar H, S, V; uchar minH, minS, minV, maxH, maxS, maxV; CvPixelPosition8u pos_src, pos_dst; uchar* p_src; uchar* p_dst; IplImage* tmp; tmp = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 3); //HSVに変換 cvCvtColor(src, tmp, CV_RGB2HSV); CV_INIT_PIXEL_POS(pos_src, (unsigned char*) tmp->imageData, tmp->widthStep,cvGetSize(tmp), x, y, tmp->origin); CV_INIT_PIXEL_POS(pos_dst, (unsigned char*) mask->imageData, mask->widthStep, cvGetSize(mask), x, y, mask->origin); minH = 100; maxH = 115; minS = 80; maxS = 255; minV = 120; maxV = 255; for(y = 0; y < tmp->height; y++) { for(x = 0; x < tmp->width; x++) { p_src = CV_MOVE_TO(pos_src, x, y, 3); p_dst = CV_MOVE_TO(pos_dst, x, y, 3); H = p_src[0]; //0から180 S = p_src[1]; V = p_src[2]; if( minH <= H && H <= maxH && minS <= S && S <= maxS && minV <= V && V <= maxV ) { p_dst[0] = 255; p_dst[1] = 255; p_dst[2] = 255; } else { p_dst[0] = 0; p_dst[1] = 0; p_dst[2] = 0; } } } if(erosions > 0) cvErode(mask, mask, 0, erosions); if(dilations > 0) cvDilate(mask, mask, 0, dilations); cvReleaseImage(&tmp); } int main(int argc, char **argv) { int c; CvCapture* capture = 0; IplImage* frame = 0; IplImage* mask = 0; IplImage* dst = 0; if(argc == 1 || (argc == 2 && strlen (argv[1]) == 1 && isdigit(argv[1][0]))) capture = cvCreateCameraCapture(argc == 2 ? argv[1][0] - '0' : 0); frame = cvQueryFrame(capture); mask = cvCreateImage(cvSize(frame->width, frame->height), IPL_DEPTH_8U, 3); dst = cvCreateImage(cvSize(frame->width, frame->height), IPL_DEPTH_8U, 3); cvNamedWindow("src", CV_WINDOW_AUTOSIZE); cvNamedWindow("dst", CV_WINDOW_AUTOSIZE); while(1) { frame = cvQueryFrame(capture); GetMaskHSV(frame, mask, 1, 1); cvAnd(frame, mask, dst); cvShowImage("src", frame); cvShowImage("dst", dst); c = cvWaitKey(10); if(c == 'q') break; } cvDestroyWindow("src"); cvDestroyWindow("dst"); cvReleaseImage(&frame); cvReleaseImage(&dst); cvReleaseImage(&mask); cvReleaseCapture(&capture); return(0); }

  • OpenCVによる時間差表示

    書き込みさせていただきます。 今OpenCVをインストールしてVC++にてプログラミングをしています。 カメラ画像を取得してそこに点を打とうとしています。 //中心 cvCircle(frameImage,cvPoint(320,250),1,CV_RGB(0,255,0),5,8,0); //右隅 cvCircle(frameImage,cvPoint(635,250),1,CV_RGB(0,255,0),5,8,0); //左隅 cvCircle(frameImage,cvPoint(5,250),1,CV_RGB(0,255,0),5,8,0); //上 cvCircle(frameImage,cvPoint(320,470),1,CV_RGB(0,255,0),5,8,0); //下 cvCircle(frameImage,cvPoint(320,5),1,CV_RGB(0,255,0),5,8,0); のようにして無理やり点を作って表示させることができました。 この点を 中心→0秒から5秒まで表示 右隅→5秒から10秒まで表示 左隅→10秒から15秒まで表示 のように時間をずらして表示するようなプログラムを作りたいのですが、やり方が調べてもよくわかりません。 教えていただければ幸いです。 よろしくお願いいたします。

  • OpenCVでの静止画像の保存

    書き込みさせていただきます。 今、OpenCVのサンプルにあるfacedetectをいじっているのですが、赤い円もしっかりと顔を認識することができました。 その中に静止画像の保存をするプログラムを入れたいのですが、実行をすると赤い円はしっかりと表示されるのですが、保存すると消えてしまいます。理由がまったくわからないので教えていただければ幸いです。 if( capture ) { for(;;) {      //カメラからの入力画像1フレームをframeImageに格納する frameImage = cvQueryFrame( capture ); if( !cvGrabFrame( capture )) break; frame = cvRetrieveFrame( capture ); if( !frame ) break; if( !frame_copy ) frame_copy = cvCreateImage( cvSize(frame->width,frame->height), IPL_DEPTH_8U, frame->nChannels ); if( frame->origin == IPL_ORIGIN_TL ) cvCopy( frame, frame_copy, 0 ); else cvFlip( frame, frame_copy, 0 );    //画像を輝度画像に変換,縮小,ヒストグラムを平坦化 detect_and_draw( frame_copy ); // 画像を表示する cvShowImage( windowNameCapture, frameImage ); //cvShowImage( windowNameFace, faceImage ); //キー入力が行われるまで表示を続ける key = cvWaitKey( 2 ); //'c'キーが入力されったら画像を保存する if ( key == 'c' ){ sprintf(filename,"C:/Documents and Settings/ryoji/My Documents/My Pictures/CV-P/fame%d.bmp", count);  cvSaveImage(filename,frameImage);  count++; } // 'q'キーが入力されたらループを抜ける else if ( key == 'q' ){ break; } } cvReleaseImage( &frame_copy ); cvReleaseCapture( &capture ); } facedetectのファイルの中にcが押されたら保存、qが押されたら終了にしています。保存、終了ともにできていますが、赤い丸だけ消えます。 よろしくお願いします。

  • opencvのプログラムについて

    if (argc < 2 || (src_img = cvLoadImage (argv[1], CV_LOAD_IMAGE_COLOR)) == 0) return -1; src_gray = cvCreateImage (cvGetSize (src_img), IPL_DEPTH_8U, 1); この部分で画像を取り込んでるのは分かるのですが、cvLoadImageの第一引数で画像を指定するんですよね?この場合はどの画像を読み込むのですか?

専門家に質問してみよう