• 締切済み

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

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; } です。よろしくお願いします。

みんなの回答

  • jjk65536
  • ベストアンサー率59% (66/111)
回答No.3

ん?ループ終了の行でセグメンテーション違反ですか? ちょっと考えにくいですね。 さきほど言い忘れましたが、コンパイルオプションで -g -O0 を付ける必要があります。 (-O0は必須ではないけど、ないと行がずれたりするんで)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

例えば「変数の値を調べてみよう」などとは思いませんでしたか?

  • jjk65536
  • ベストアンサー率59% (66/111)
回答No.1

gdbで走らせて、死んだ後btと打つとどの関数で死んだかわかると思いますが、 どの関数でセグメンテーション違反が出ていますか?

megu210jp
質問者

補足

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); } で終わってしまいます。

関連するQ&A

  • 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 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)を決まったサイズのウィンドウで扱えるでしょうか。 もしおわかりでしたらヒントでも結構ですのでぜひ教えてください。 よろしくお願いします。

  • OpenCVのcvFindContours

    添付画像(2値)の一番外側の輪郭線を抽出するコードを書きたいのですが, contoursがNULLになってしまい、うまく行きません。 サンプルで添付した画像(小さくてすみません)に、問題があるのでしょうか。 いろいろと調べましたが原因がわからず困っています。 どこを修正するべきか ぜひ教えてください。 よろしくお願い致します。 void test(char myPath){ int i; Iplimage *kuro; CvSeq *contours = NULL; kuro = cvLoadImage(myPath, CV_LOAD_IMAGE_ANYCOLOR);  //2値画像 cvThreshold(kuro, kuro, 100, 255, CV_THRESH_BINARY); // 以下の contours がNULLになってしまいます。 cvFindContours(kuro, storage, &contours, sizeof(CvContour), CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE); cvDrawContours(img, contours, CV_RGB(255, 0, 0), CV_RGB(0, 255, 0), 1, 2, CV_AA, cvPoint(0, 0)); }

  • OpenCV輪郭抽出→座標取得でのバグ(C++)

    プログラミング初心者の者です。 今OpenCVを色々勉強してるのですが、全く行き詰ってしまいました。 サンプルを打ち込んだりして、輪郭抽出、表示まではできましたが、それに加えて座標の取得、表示の部分を書いてみたんですが、バグが一向に取れません。 OpenCV2.4.1 Visual Studio2010ExpressC++でやっています。 0x00411845 でハンドルされていない例外が発生しました: 0xC0000005: 場所 0x00000004 を読み込み中にアクセス違反が発生しました。 という内容が表示されます。 以下のようなコードを書きました。 おかしいところもたくさんあると思いますが、何卒ご教示頂ければと思います。 using namespace cv; using namespace std; int i; IplImage *g_image = NULL; IplImage *g_gray = NULL; IplImage *src_img = NULL; IplImage *tmp_img = NULL; int g_thresh = 100;//閾値 CvMemStorage *g_storage = NULL;//データ格納用低レベル構造体 CvFileStorage *fs;//ファイルストレッジ CvTreeNodeIterator it;//イテレータ CvPoint *point,*tmp; void on_trackbar(int){ if( g_storage == NULL ){ g_gray = cvCreateImage( cvGetSize( g_image ), 8, 1 ); g_storage = cvCreateMemStorage(0); } else { cvClearMemStorage( g_storage ); } CvSeq* contours = 0; cvCvtColor( g_image, g_gray, CV_BGR2GRAY ); cvThreshold( g_gray, g_gray, g_thresh, 255, CV_THRESH_BINARY ); cvFindContours( g_gray, g_storage, &contours,sizeof(CvContour ),CV_RETR_TREE,CV_CHAIN_APPROX_NONE); //輪郭抽出 (入力画像、保存先、一番外の輪郭、サイズ、  ) 抽出モード cvZero( g_gray ); if( contours ){ cvDrawContours( g_gray, contours, cvScalarAll(255), cvScalarAll(255), 100 ); } cvInitTreeNodeIterator (&it, contours,1); fs=cvOpenFileStorage("Contours.xml",NULL,CV_STORAGE_WRITE); //輪郭線上を走査 while((contours=(CvSeq*)cvNextTreeNode(&it))!=NULL){ cvClearMemStorage( g_storage ); cvStartWriteStruct(fs,"Contours",CV_NODE_SEQ); for (i=0;i<contours->total;i++){ point=CV_GET_SEQ_ELEM(CvPoint,contours,i); cvLine(g_gray,*tmp,*point,CV_RGB(0,0,255),2); cvStartWriteStruct(fs,NULL,CV_NODE_MAP); cvWriteInt(fs,"x",point->x); cvWriteInt(fs,"y",point->y); //座標取得 cvEndWriteStruct(fs); tmp=point; } cvEndWriteStruct(fs); cvReleaseFileStorage(&fs); } cvShowImage( "Contours", g_gray ); } int _tmain(int argc, _TCHAR* argv[]){ g_image = cvLoadImage( "C:\\OpenCV2.4.1\\opencv\\samples\\c\\lena.jpg" ); //入力画像       cvNamedWindow( "Contours", 1 ); cvCreateTrackbar( "Threshold", "Contours", &g_thresh, 255, on_trackbar ); on_trackbar(0); cvWaitKey(); return 0; }

  • 解像度と誤差について

    失礼します。 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でサンプルコードを使うとエラーが出ます

    環境はVidualStudio2008、OpenCVは2.1のバージョンを利用しています。 OpenCVのテンプレートマッチングのサンプルを利用したところエラーが発生しました。 ソースは以下のものを使っています。 ところどころに入っているprintfは私が自分で入れたものですがこれが原因であるとは考えにくいのです。 エラーは添付したような画像で現れます。 またデバッグしたところ [下のフレームは間違っているか、または見つかりません。KernelBase.dll に対して読み込まれたシンボルはありません。] KernelBase.dll!76b7b9bc() このような文章も表示されました。 どうすれば解決できるでしょうか。 #include <cv.h> #include <highgui.h> int main (int argc, char **argv) { double min_val, max_val; CvPoint min_loc, max_loc; CvSize dst_size; IplImage *src_img, *tmp_img, *dst_img; argv[1]="○○"; argv[2]="○○"; argc=3; printf("1complete\n"); cvNamedWindow ("Image", 1); src_img = cvLoadImage (argv[1], CV_LOAD_IMAGE_COLOR); tmp_img = cvLoadImage (argv[2], CV_LOAD_IMAGE_COLOR); if(argc != 3 || (src_img = cvLoadImage (argv[1], CV_LOAD_IMAGE_COLOR))==0||(tmp_img = cvLoadImage (argv[2], CV_LOAD_IMAGE_COLOR))==0) return -1; printf("2complete\n"); // (1)探索画像全体に対して,テンプレートのマッチング値(指定した手法に依存)を計算 dst_size = cvSize (src_img->width - tmp_img->width + 1, src_img->height - tmp_img->height + 1); printf("2-1complete\n"); dst_img = cvCreateImage (dst_size, IPL_DEPTH_32F, 1);    //ここで動作停止 printf("2-2complete\n"); cvMatchTemplate (src_img, tmp_img, dst_img, CV_TM_CCOEFF_NORMED); printf("2-3complete\n"); cvMinMaxLoc (dst_img, &min_val, &max_val, &min_loc, &max_loc, NULL); printf("3complete\n"); // (2)テンプレートに対応する位置に矩形を描画 cvRectangle (src_img, max_loc, cvPoint (max_loc.x + tmp_img->width, max_loc.y + tmp_img->height), CV_RGB (255, 0, 0), 3); printf("4complete\n"); cvShowImage ("Image", src_img); printf("ALL COMPLETE!\n"); cvWaitKey (0); cvDestroyWindow ("Image"); cvReleaseImage (&src_img); cvReleaseImage (&tmp_img); cvReleaseImage (&dst_img); return 0; }

  • 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); } }

  • opencv c++についての質問です

    int main (int argc, char **argv){ int i, c, counter; int INIT_TIME = 100; int w = 0, h = 0; char *FileName = "動画名"; if((capture = cvCaptureFromFile(FileName)) == NULL){ printf("指定された動画がみつかりません\n"); return -1; } CvCapture *capture = 0; IplImage *frame; IplImage *av_img, *sgm_img; IplImage *lower_img, *upper_img, *tmp_img; IplImage *dst_img, *msk_img; CvFont font; capture = cvCreateFileCapture (FileName); // (2)1フレームキャプチャし,キャプチャサイズを取得する. frame = cvQueryFrame (capture); w = frame->width; h = frame->height; // (3)作業用の領域を生成する av_img = cvCreateImage (cvSize (w, h), IPL_DEPTH_32F, 3); sgm_img = cvCreateImage (cvSize (w, h), IPL_DEPTH_32F, 3); tmp_img = cvCreateImage (cvSize (w, h), IPL_DEPTH_32F, 3); lower_img = cvCreateImage (cvSize (w, h), IPL_DEPTH_32F, 3); upper_img = cvCreateImage (cvSize (w, h), IPL_DEPTH_32F, 3); dst_img = cvCreateImage (cvSize (w, h), IPL_DEPTH_8U, 3); msk_img = cvCreateImage (cvSize (w, h), IPL_DEPTH_8U, 1); // (4)背景の輝度平均の初期値を計算する printf ("Background statistics initialization start\n"); cvSetZero (av_img); for (i = 0; i < INIT_TIME; i++) { frame = cvQueryFrame (capture); cvAcc (frame, av_img); } cvConvertScale (av_img, av_img, 1.0 / INIT_TIME); // (5)背景の輝度振幅の初期値を計算する cvSetZero (sgm_img); for (i = 0; i < INIT_TIME; i++) { frame = cvQueryFrame (capture); cvConvert (frame, tmp_img); cvSub (tmp_img, av_img, tmp_img); cvPow (tmp_img, tmp_img, 2.0); cvConvertScale (tmp_img, tmp_img, 2.0); cvPow (tmp_img, tmp_img, 0.5); cvAcc (tmp_img, sgm_img); } cvConvertScale (sgm_img, sgm_img, 1.0 / INIT_TIME); printf ("Background statistics initialization finish\n"); // (6)表示用ウィンドウを生成する cvInitFont (&font, CV_FONT_HERSHEY_COMPLEX, 0.7, 0.7); cvNamedWindow ("Input", CV_WINDOW_AUTOSIZE); cvNamedWindow ("Substraction", CV_WINDOW_AUTOSIZE); // (7)取得画像から背景を分離するループ counter = 0; while (1) { frame = cvQueryFrame (capture); cvConvert (frame, tmp_img); // (8)背景となりうる画素の輝度値の範囲をチェックする cvSub (av_img, sgm_img, lower_img); cvSubS (lower_img, cvScalarAll (Zeta), lower_img); cvAdd (av_img, sgm_img, upper_img); cvAddS (upper_img, cvScalarAll (Zeta), upper_img); cvInRange (tmp_img, lower_img, upper_img, msk_img); // (9)輝度振幅を再計算する cvSub (tmp_img, av_img, tmp_img); cvPow (tmp_img, tmp_img, 2.0); cvConvertScale (tmp_img, tmp_img, 2.0); cvPow (tmp_img, tmp_img, 0.5); // (10)背景と判断された領域の背景の輝度平均と輝度振幅を更新する cvRunningAvg (frame, av_img, B_PARAM, msk_img); cvRunningAvg (tmp_img, sgm_img, B_PARAM, msk_img); // (11)物体領域と判断された領域では輝度振幅のみを(背景領域よりも遅い速度で)更新する cvNot (msk_img, msk_img); cvRunningAvg (tmp_img, sgm_img, T_PARAM, msk_img); // (12)物体領域のみを出力画像にコピーする(背景領域は黒) cvSetZero (dst_img); cvCopy (frame, dst_img, msk_img); // メディアンフィルタでノイズを除去する cvSmooth( dst_img, dst_img, CV_MEDIAN ); cvMoments( frame, &moment, 0 ); m_00 = cvGetSpatialMoment( &moment, 0, 0 ); m_10 = cvGetSpatialMoment( &moment, 1, 0 ); m_01 = cvGetSpatialMoment( &moment, 0, 1 ); gravityX = m_10 / m_00; gravityY = m_01 / m_00; if (frame->nChannels == 3 && cvGetImageCOI (frame) == 0) cvSetImageCOI (frame, 1); cvSetImageCOI (frame, 0); cvCircle( dst_img, cvPoint( gravityX, gravityY ), CIRCLE_RADIUS,CV_RGB( 255, 0, 0 ), LINE_THICKNESS, LINE_TYPE, 0 ); // (13)処理結果を表示する cvShowImage ("Input", frame); cvShowImage ("Substraction", dst_img); counter++; c = cvWaitKey (10); if (c == '\x1b') break; } cvDestroyWindow ("Input"); cvDestroyWindow ("Substraction"); cvReleaseImage (&frame); cvReleaseImage (&dst_img); cvReleaseImage (&av_img); cvReleaseImage (&sgm_img); cvReleaseImage (&lower_img); cvReleaseImage (&upper_img); cvReleaseImage (&tmp_img); cvReleaseImage (&msk_img); return 0; } 動画を指定して背景差分を行い、動画内の物体の重心を求めて円を描きたいのですがcvMoments()とcvCircle()関数を入れてコンパイルしたところウィンドウが出て動画が始まる前に終了してしまいます。 どのようにすれば正常に動くようになるのでしょうか?

  • 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を利用し、用意した画像1、画像2間のオプティカルフローを計算し、画像3に描画するというプログラムを組みました。 その過程での、オプティカルフローのx成分「vel_x」、y成分「vel_y」の値をテキストファイルに書き出したいのですが、それぞれ「003B3340」「003B33E0」と記録されるだけで(多分アドレス?)うまくいきません。 どなたか詳しい方、ご教授いただけると幸いです。 環境はWindows XP、Visual C++ .NET2003です。 以下にコードを示します。 #include <cv.h> #include <highgui.h> #include <stdio.h> #include <fstream> const char *imgA_file = "01.bmp"; const char *imgB_file = "02.bmp"; using namespace std; int main(int argc, char** argv){ IplImage *imgA_src = cvLoadImage( imgA_file, -1); //画像読み込み IplImage *imgB_src = cvLoadImage( imgB_file, -1); IplImage *imgA = cvCreateImage(cvGetSize(imgA_src), IPL_DEPTH_8U, 1); cvCvtColor(imgA_src, imgA, CV_BGR2GRAY); IplImage *imgB = cvCreateImage(cvGetSize(imgA_src), IPL_DEPTH_8U, 1); cvCvtColor(imgB_src, imgB, CV_BGR2GRAY); IplImage *vel_x = cvCreateImage(cvGetSize(imgA_src), IPL_DEPTH_32F, 1); //x,y方向の速度を記録するバッファを確保する IplImage *vel_y = cvCreateImage(cvGetSize(imgA_src), IPL_DEPTH_32F, 1); IplImage *imgC = cvCloneImage(imgA); //結果画像用に入力画像をコピーする cvCalcOpticalFlowLK( imgA, imgB, cvSize( 11, 11), vel_x, vel_y); //オプティカルフローを求める,第3引数:ウインドウサイズ ofstream ofx("vel_x.txt"); //vel_x, vel_y のデータをテキストへ書き込み string buf; ofx << vel_x << endl; ofstream ofy("vel_y.txt"); buf; ofy << vel_y << endl; /* FILE *fp1, *fp2; //vel_x, vel_y のデータをテキストへ書き込み fp1 = fopen("vel_x.txt", "w"); fp2 = fopen("vel_y.txt", "w"); fprintf(fp1, "%d", vel_x); fprintf(fp2, "%d", vel_y); fclose(fp1); fclose(fp2); const CvArr *m, *n; // FILE *fp1, *fp2; fp1 = fopen("vel_x.txt", "r"); fp2 = fopen("vel_y.txt", "r"); fscanf(fp1, "%d", &m); fscanf(fp2, "%d", &n); fclose(fp1); fclose(fp2); */ for ( int i=0;i<imgA->height;i+=10 ){ //結果画像の作成 for ( int j=0;j<imgA->width;j+=10 ){ int dx = (int)cvGetReal2D( vel_x, i, j); int dy = (int)cvGetReal2D( vel_y, i, j); cvLine( imgC, cvPoint( j, i), cvPoint( j+dx, i+dy), CV_RGB( 255, 255, 255), 1, 8, 0); cvRectangle( imgC, cvPoint( j+dx-1, i+dy-1), cvPoint( j+dx+1, i+dy+1), CV_RGB( 255, 255, 255), 1, 8, 0); } } cvSaveImage( "03.bmp", imgC); //画像保存 cvReleaseImage( &imgA); cvReleaseImage( &imgB); cvReleaseImage( &vel_x); cvReleaseImage( &vel_y); return 0; }