質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.52%

  • C

    4517questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • C++

    4423questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • OpenCV

    1509questions

    OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。

テンプレートマッチングでの最大値の座標

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,409

yamata

score 28

opencvでテンプレートマッチングを行っています。
以下の流れで、マッチング箇所を囲っているのですが、
最大値の座標が分からないため、cvrectangle内の+
temp_up->widthの値を5などに変更して、最大値の座標がどこらへんにあるのか確認しようとしました。
しかし、すべての画像で同じ場所を囲ってしまい、最大値の座標を確認できません。
最大値の座標を囲む方法はないのでしょうか?
よろしくお願いします。

```  
int main( int argc , char** argv)  
{  
int counter = 0;  
char str[64];  
#define LINE_THICKNESS    1  
#define LINE_TYPE    8  
#define SHIFT    0  
#define SCALE_X 0.2  
#define SCALE_Y 0.2  
#define SCALE_XX 5.0  
#define SCALE_YY 5.0  
IplImage * temp_up = NULL;  
IplImage * temp_side = NULL;  
IplImage * dst1 = NULL;  
IplImage * dst2 = NULL;  
IplImage * img = NULL;  
IplImage * scale_img = NULL;  
IplImage * copy_img1 = NULL;  
IplImage * copy_img2 = NULL;  
IplImage * grey_img1 = NULL;  
IplImage * grey_img2 = NULL;  

IplImage * grey_temp_up = NULL;  
IplImage * grey_temp_side = NULL;  

FILE *file;  
file=fopen("result.csv","w");  

double max_inter1inkage=0;  
double min_inter1inkage=0;  
double max_inter2inkage=0;  
double min_inter2inkage=0;  

CvPoint max_point1;  
CvPoint min_point1;  
CvPoint max_point2;  
CvPoint min_point2;  


//---------テンプレート画像を読み込む-------  
temp_up=cvLoadImage("temp_up.png",CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);    //カラー読み込み  
temp_side=cvLoadImage("temp_side.png",CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);    //カラー読み込み  
grey_temp_up=cvCreateImage(cvGetSize(temp_up),IPL_DEPTH_8U,1);        //1チャンネル8ビットのIplImage作成(元画像)  
grey_temp_side=cvCreateImage(cvGetSize(temp_side),IPL_DEPTH_8U,1);        //1チャンネル8ビットのIplImage作成(元画像)  

cvCvtColor(temp_up,grey_temp_up,CV_BGR2GRAY);  
cvCvtColor(temp_side,grey_temp_side,CV_BGR2GRAY);  

//for ( int number =83; number<202;++number)  
{  
int64 start = cv::getTickCount();//所要時間計測      

//------------------------原画像読み込み-------------------------------  
IplImage * img= cvLoadImage("C:\\opencv_ICImage\\2016-11-8黒ネジ10本40fps\\Image0105.bmp",CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);      
//--------------------------------------------------------------------------  

//変換画像用IplImage  
scale_img=cvCreateImage(cvSize((int)(img->width*SCALE_X), (int)(img->height*SCALE_Y)), IPL_DEPTH_8U, 3);  
//変換  
cvResize(img, scale_img, CV_INTER_LINEAR);  

//原画像コピー  
copy_img1=cvCloneImage(scale_img);  
copy_img2=cvCloneImage(scale_img);  

//赤枠で囲む  
cvRectangle(scale_img,cvPoint(100,65),cvPoint(155,135),CV_RGB(255,0,0),LINE_THICKNESS,LINE_TYPE,SHIFT);  
cvRectangle(scale_img,cvPoint(185,70),cvPoint(240,135),CV_RGB(255,0,0),LINE_THICKNESS,LINE_TYPE,SHIFT);//左上、右下  

//-----------------ROIの設定----------------------  
CvRect rect1;  
rect1.x = 100;  
rect1.y = 65;  
rect1.width = 55;  
rect1.height = 70;  
cvSetImageROI(copy_img1,rect1);  

CvRect rect2;  
rect2.x = 185;  
rect2.y = 70;  
rect2.width = 55;  
rect2.height =65;  
cvSetImageROI(copy_img2,rect2);//左上、幅、高さ  
//----------------------------------------------------  

//入力画像表示  
cvNamedWindow("img_window",CV_WINDOW_AUTOSIZE);  
cvShowImage("img_window",scale_img);  

//--------------------------グレースケールの場合----------------------------------------------------------------  
//テンプレート・マッチングに用いる相関値データを格納する画像の領域確保  
//グレー・スケール画像用に領域確保  
grey_img1=cvCreateImage(cvGetSize(copy_img1),IPL_DEPTH_8U,1);            //1チャンネル8ビットのIplImage作成(元画像)  
grey_img2=cvCreateImage(cvGetSize(copy_img2),IPL_DEPTH_8U,1);            //1チャンネル8ビットのIplImage作成(元画像)  

dst1=cvCreateImage(cvSize(abs(grey_img1->width-grey_temp_up->width)+1,abs(grey_img1->height-grey_temp_up->height)+1),IPL_DEPTH_32F,1);    //領域確保  
dst2=cvCreateImage(cvSize(abs(grey_img2->width-grey_temp_side->width)+1,abs(grey_img2->height-grey_temp_side->height)+1),IPL_DEPTH_32F,1);    //領域確保  

//グレー・スケールに変換して格納  
cvCvtColor(copy_img1,grey_img1,CV_BGR2GRAY);  
cvCvtColor(copy_img2,grey_img2,CV_BGR2GRAY);  

cvMatchTemplate(grey_img1,grey_temp_up,dst1,CV_TM_CCOEFF_NORMED);    //テンプレートマッチング  
cvMatchTemplate(grey_img2,grey_temp_side,dst2,CV_TM_CCOEFF_NORMED);    //テンプレートマッチング  

IplImage *dst3=cvCloneImage(dst1);  
IplImage *dst=cvCreateImage(cvSize((int)(dst3->width*SCALE_XX), (int)(dst3->height*SCALE_YY)), IPL_DEPTH_32F, 1);  
cvResize(dst3, dst, CV_INTER_LINEAR);  

cvNamedWindow("dst_window",CV_WINDOW_AUTOSIZE);  
cvShowImage("dst_window",dst);  

//-------------------------------------------------------------------------------------------------------------  

//-----------マッチング点を求める---------  
cvMinMaxLoc(dst1,&min_inter1inkage,&max_inter1inkage,&min_point1,&max_point1,NULL);  
cvMinMaxLoc(dst2,&min_inter2inkage,&max_inter2inkage,&min_point2,&max_point2,NULL);  

//------マッチングを表示する-----  
//相関値0.75以下ならばLostを表示して次に行く  

//if(max_inter1inkage>0.01&& max_inter2inkage>0.01)  
{  
//マッチング箇所を四角で描画  
cvRectangle(scale_img,cvPoint(max_point1.x+rect1.x,max_point1.y+rect1.y),cvPoint(max_point1.x+rect1.x+temp_up->width,max_point1.y+rect1.y+temp_up->height),CV_RGB(255,0,0),3);  
cvRectangle(scale_img,cvPoint(max_point2.x+rect2.x,max_point2.y+rect2.y),cvPoint(max_point2.x+rect2.x+temp_side->width,max_point2.y+rect2.y+temp_side->height),CV_RGB(0,255,255),3);  
cvCircle(scale_img,cvPoint(max_point1.x+rect1.x,max_point1.y+rect1.y),10,CV_RGB(0,255,255),5,3,0);  

//画像を表示  
cvNamedWindow("result",CV_WINDOW_AUTOSIZE);  
cvShowImage("result",scale_img);  

//類似度表示  
printf("up_Detection %lf\n",max_inter1inkage);  
printf("side_Detection %lf\n",max_inter2inkage);  

}  

//タイマー終了  
int64 end = cv::getTickCount();  
double elapsedMsec = ( end - start )*1000/cv::getTickFrequency();  

//タイマー表示  
std::cout << elapsedMsec <<"ms" <<std::endl;  
printf("\n");  

cvWaitKey(0);  

fprintf(file,"%f,%f,%f\n",max_inter1inkage,max_inter2inkage,elapsedMsec);  

//メモリ解放  
cvReleaseImage(&img);  
cvReleaseImage(&scale_img);  
cvReleaseImage(&copy_img1);  
cvReleaseImage(&copy_img2);  
cvReleaseImage(&grey_img1);  
cvReleaseImage(&grey_img2);  
cvReleaseImage(&dst1);  
cvReleaseImage(&dst2);  
cvDestroyWindow("result");  

}  

fclose(file);  

//メモリ解放  
cvReleaseImage(&temp_up);  
cvReleaseImage(&temp_side);  
cvReleaseImage(&grey_temp_up);  
cvReleaseImage(&grey_temp_side);  

//メモリ開放  
cvDestroyWindow("img_window");  
//cvDestroyWindow("copy_img1_window");  
//cvDestroyWindow("copy_img2_window");  
//cvDestroyWindow("temp_up_window");  
//cvDestroyWindow("temp_side_window");  
//cvDestroyWindow("grey_temp_up_window");  
//cvDestroyWindow("grey_temp_side_window");  
//cvDestroyWindow("grey_img1_window");  
//cvDestroyWindow("grey_img2_window");  

return 0;  
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

0

ソースを整理するために、新しい回答欄を使います。(前の回答の流れが分からなくなりそうだったので)

#define LINE_THICKNESS    1  
#define LINE_TYPE    8  
#define SHIFT    0  
#define SCALE_X 0.2  
#define SCALE_Y 0.2  
#define SCALE_XX 5.0  
#define SCALE_YY 5.0  
int main( int argc , char** argv)  
{  
    int counter = 0;  // どこにも使ってない、なんかのカウンター
    char str[64];     // どこにも使ってない、なんかの配列

    IplImage * temp_up = NULL;  
    IplImage * temp_side = NULL;  
    IplImage * dst1 = NULL;  
    IplImage * dst2 = NULL;  
    IplImage * img = NULL;  
    IplImage * scale_img = NULL;  
    IplImage * copy_img1 = NULL;  
    IplImage * copy_img2 = NULL;  
    IplImage * grey_img1 = NULL;  
    IplImage * grey_img2 = NULL;  

    IplImage * grey_temp_up = NULL;  
    IplImage * grey_temp_side = NULL;  

    FILE *file;  
    file=fopen("result.csv","w");  

    double max_inter1inkage=0;  
    double min_inter1inkage=0;  
    double max_inter2inkage=0;  
    double min_inter2inkage=0;  

    CvPoint max_point1;  
    CvPoint min_point1;  
    CvPoint max_point2;  
    CvPoint min_point2;  


//---------テンプレート画像を読み込む-------  
    temp_up=cvLoadImage("temp_up.png",CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);    //カラー読み込み  
    temp_side=cvLoadImage("temp_side.png",CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);    //カラー読み込み  
    grey_temp_up=cvCreateImage(cvGetSize(temp_up),IPL_DEPTH_8U,1);        //1チャンネル8ビットのIplImage作成(元画像)  
    grey_temp_side=cvCreateImage(cvGetSize(temp_side),IPL_DEPTH_8U,1);        //1チャンネル8ビットのIplImage作成(元画像)  

    cvCvtColor(temp_up,grey_temp_up,CV_BGR2GRAY);  
    cvCvtColor(temp_side,grey_temp_side,CV_BGR2GRAY);  




//for ( int number =83; number<202;++number)  
//{ ???  
    int64 start = cv::getTickCount();//所要時間計測      

//------------------------原画像読み込み-------------------------------  
    IplImage * img= cvLoadImage("C:\\opencv_ICImage\\2016-11-8黒ネジ10本40fps\\Image0105.bmp",CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);      
//--------------------------------------------------------------------------  

//変換画像用IplImage  
    scale_img=cvCreateImage(cvSize((int)(img->width*SCALE_X), (int)(img->height*SCALE_Y)), IPL_DEPTH_8U, 3);  
//変換  
    cvResize(img, scale_img, CV_INTER_LINEAR);  

//原画像コピー  
    copy_img1=cvCloneImage(scale_img);  
    copy_img2=cvCloneImage(scale_img);  

//赤枠で囲む  
   cvRectangle(scale_img,cvPoint(100,65),cvPoint(155,135),CV_RGB(255,0,0),LINE_THICKNESS,LINE_TYPE,SHIFT);  
   cvRectangle(scale_img,cvPoint(185,70),cvPoint(240,135),CV_RGB(255,0,0),LINE_THICKNESS,LINE_TYPE,SHIFT);//左上、右下  

//-----------------ROIの設定----------------------  
    CvRect rect1;  
    rect1.x = 100;  
    rect1.y = 65;  
    rect1.width = 55;  
    rect1.height = 70;  
    cvSetImageROI(copy_img1,rect1);  

    CvRect rect2;  
    rect2.x = 185;  
    rect2.y = 70;  
    rect2.width = 55;  
    rect2.height =65;  
    cvSetImageROI(copy_img2,rect2);//左上、幅、高さ  
//----------------------------------------------------  

//入力画像表示  
    cvNamedWindow("img_window",CV_WINDOW_AUTOSIZE);  
    cvShowImage("img_window",scale_img);  

//--------------------------グレースケールの場合----------------------------------------------------------------  
//テンプレート・マッチングに用いる相関値データを格納する画像の領域確保  
//グレー・スケール画像用に領域確保  
    grey_img1=cvCreateImage(cvGetSize(copy_img1),IPL_DEPTH_8U,1);            //1チャンネル8ビットのIplImage作成(元画像)  
    grey_img2=cvCreateImage(cvGetSize(copy_img2),IPL_DEPTH_8U,1);            //1チャンネル8ビットのIplImage作成(元画像)  

    dst1=cvCreateImage(cvSize(abs(grey_img1->width-grey_temp_up->width)+1,abs(grey_img1->height-grey_temp_up->height)+1),IPL_DEPTH_32F,1);    //領域確保  
    dst2=cvCreateImage(cvSize(abs(grey_img2->width-grey_temp_side->width)+1,abs(grey_img2->height-grey_temp_side->height)+1),IPL_DEPTH_32F,1);    //領域確保  

//グレー・スケールに変換して格納  
    cvCvtColor(copy_img1,grey_img1,CV_BGR2GRAY);  
    cvCvtColor(copy_img2,grey_img2,CV_BGR2GRAY);  

    cvMatchTemplate(grey_img1,grey_temp_up,dst1,CV_TM_CCOEFF_NORMED);    //テンプレートマッチング  
    cvMatchTemplate(grey_img2,grey_temp_side,dst2,CV_TM_CCOEFF_NORMED);    //テンプレートマッチング  

    IplImage *dst3=cvCloneImage(dst1);  
    IplImage *dst=cvCreateImage(cvSize((int)(dst3->width*SCALE_XX), (int)(dst3->height*SCALE_YY)), IPL_DEPTH_32F, 1);  
    cvResize(dst3, dst, CV_INTER_LINEAR);  

    cvNamedWindow("dst_window",CV_WINDOW_AUTOSIZE);  
    cvShowImage("dst_window",dst);  

//-------------------------------------------------------------------------------------------------------------  

//-----------マッチング点を求める---------  
     cvMinMaxLoc(dst1,&min_inter1inkage,&max_inter1inkage,&min_point1,&max_point1,NULL);  
     cvMinMaxLoc(dst2,&min_inter2inkage,&max_inter2inkage,&min_point2,&max_point2,NULL);  

//------マッチングを表示する-----  
//相関値0.75以下ならばLostを表示して次に行く  

//if(max_inter1inkage>0.01&& max_inter2inkage>0.01)  
{  
//マッチング箇所を四角で描画  
    cvRectangle(scale_img,cvPoint(max_point1.x+rect1.x,max_point1.y+rect1.y),cvPoint(max_point1.x+rect1.x+temp_up->width,max_point1.y+rect1.y+temp_up->height),CV_RGB(255,0,0),3);  
    cvRectangle(scale_img,cvPoint(max_point2.x+rect2.x,max_point2.y+rect2.y),cvPoint(max_point2.x+rect2.x+temp_side->width,max_point2.y+rect2.y+temp_side->height),CV_RGB(0,255,255),3);  
    cvCircle(scale_img,cvPoint(max_point1.x+rect1.x,max_point1.y+rect1.y),10,CV_RGB(0,255,255),5,3,0);  

//画像を表示  
    cvNamedWindow("result",CV_WINDOW_AUTOSIZE);  
    cvShowImage("result",scale_img);  

//類似度表示  
    printf("up_Detection %lf\n",max_inter1inkage);  
    printf("side_Detection %lf\n",max_inter2inkage);  

}  

//タイマー終了  
    int64 end = cv::getTickCount();  
    double elapsedMsec = ( end - start )*1000/cv::getTickFrequency();  

//タイマー表示  
    std::cout << elapsedMsec <<"ms" <<std::endl; 
    std::cout << std::endl; 

    cvWaitKey(0);  

    fprintf(file,"%f,%f,%f\n",max_inter1inkage,max_inter2inkage,elapsedMsec);  

//メモリ解放  
    cvReleaseImage(&img);  
    cvReleaseImage(&scale_img);  
    cvReleaseImage(&copy_img1);  
    cvReleaseImage(&copy_img2);  
    cvReleaseImage(&grey_img1);  
    cvReleaseImage(&grey_img2);  
    cvReleaseImage(&dst1);  
    cvReleaseImage(&dst2);  
    cvDestroyWindow("result");  

    }  
    fclose(file);  

//メモリ解放  
    cvReleaseImage(&temp_up);  
    cvReleaseImage(&temp_side);  
    cvReleaseImage(&grey_temp_up);  
    cvReleaseImage(&grey_temp_side);  


    cvDestroyWindow("img_window");  
    return 0;  
}


さて、途中に’本当に’って’{’や’}’があったが。これを添削してみよう。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/11/14 17:31

    丁寧にありがとうございます。
    添削をしてみました。
    見やすくありがとうございます

    キャンセル

  • 2016/11/14 17:31

    まず、’scale_img=cvCreateImage(cvSize((int)(img->width*SCALE_X), (int)(img->height*SCALE_Y)), IPL_DEPTH_8U, 3); ’の’img->width*SCALE_X’と’img->height*SCALE_Y’ここ。本文中では気が付かないのだが、’(float)img->height*SCALE_Y)'と’(float)’img->height*SCALE_Y)'に書き換えてみて。(int型)*(float)’ではなくて'(float)*(float)'に。

    キャンセル

  • 2016/11/14 17:36

    今、自分の環境で同じように"#define hogehoge 0.2'として(int型)の変数に同様の式を与えて確認したけど結果はどんな数字でも'0'に。まずここですね。

    キャンセル

  • 2016/11/14 17:42

    ’scale_img=cvCreateImage(cvSize((float)(img->width*SCALE_X), (float)(img->height*SCALE_Y)), IPL_DEPTH_8U, 3); ’
    以上ということでしょうか?

    キャンセル

  • 2016/11/14 17:52

    違います。まず'img->width’と’img->height'を(float)に一時的に変換しないと。だから'scale_img=cvCreateImage(cvSize((int)((float)img->width*SCALE_X), (int)((float)img->height*SCALE_Y)), IPL_DEPTH_8U, 3); ’です。やれやれ。実験的にご自分でも、printf("No float %d\n",img->width*SCALE_X);'と’prinft("Float %d\n",(float)img->width*SCALE_X);を直近の部分にでも入れて試してみてください。これがデバッグプリント(古典的だけど)

    キャンセル

  • 2016/11/14 17:55

    今までの流れでdstをimshowしたら小さすぎるって所でピンときた。

    キャンセル

  • 2016/11/14 17:58

    両者ともに0がひょうじされました。

    キャンセル

  • 2016/11/14 18:01

    img->widthの値は'0'ですか?

    キャンセル

  • 2016/11/14 18:03

    No float 1280
    float 0
    になりました。

    キャンセル

  • 2016/11/14 18:05

    ついでに'printf("SCALE_X %d\n",SCALE_X);’も。

    キャンセル

  • 2016/11/14 18:08

    ??img-widthは6400?どんなカメラで撮影?

    キャンセル

  • 2016/11/14 18:10

    訂正:ついでに'printf("SCALE_X %d\n",SCALE_X);’も。⇒’ついでに'printf("SCALE_X %f\n",SCALE_X);’も。

    キャンセル

  • 2016/11/14 18:10

    -178955798といったような数字が表示されました。

    キャンセル

  • 2016/11/14 18:10

    1280です。産業用USB3.0カメラになります。

    キャンセル

  • 2016/11/14 18:14

    ならば’1280*0.2=256’が必要とする数字になるから、これになるようにするには(float)1280*(float)SCALE_Xになるように指示するわけで。しかし(float)1280*SCALE_X=0になるにはSCALE_Xが0という事になる上記のfloat 0では。

    キャンセル

  • 2016/11/14 18:16

    念のため'#define SCALE_X 0.2F’と’#define SCALE_Y 0.2F'(明確にfloatと宣言)して再度確認。

    キャンセル

  • 2016/11/14 22:15

    仕事の合間に、自分の持っているデータで貴殿のソースを基に再現をしていますが、やはり指摘している部分(しかし貴殿の結果とは違う)のでOpenCVのバージョンの違いと記載の方法方法?と考えて検証していますが。不思議です。

    キャンセル

  • 2016/11/15 10:10

    回答を見直してミスに気が付きました。’printf("No float %d\n",img->width*SCALE_X);'と’prinft("Float %d\n",(float)img->width*SCALE_X);’の所で’prinft("Float %d\n",(int)((float)img->width*SCALE_X));’で確認を。

    キャンセル

  • 2016/11/15 11:51

    ありがとうございます。
    へんこうしてみたのですが、SCALE_Xが-1610612736という値を取ります。
    NOfloat,floatはともに1280をとります。

    キャンセル

  • 2016/11/15 11:57 編集

    'printf("SCALE_X %f\n",SCALE_X);’⇒’printf("SCALE_X %f\n",(float)SCALE_X);'は?’%f’ですよ。

    キャンセル

  • 2016/11/15 13:54

    0.2000と表示するようになりました。

    キャンセル

  • 2016/11/15 14:08

    となると’#define SCALE_X (float)0.2'と’#define SCALE_Y (float)0.2'としてみましょう。”0.2F"でも明示できそうだけど”

    キャンセル

  • 2016/11/15 14:19

    変更してみました。
    printf("No float %d\n",img->width);
    printf("Float %d\n",(int)((float)img->width));ともに1280.
    SCALEは0.2000と表示されます。

    キャンセル

  • 2016/11/15 14:27 編集

    確かめるのは’’prinft("Float %d\n",(float)img->width*SCALE_X);’ですよ。resizeにの引数の確認のため。img->widthとSCALE_Xを掛けたものが256にならないと正常に動きませんから。

    つまり’#define 'ではSCALE関係の定義には(float)もしくは'F'をつけて、明確にする。int型と小数の計算ではintに(float)をつけて一時的に小数として取り扱う。小数計算の結果をintに渡すときは(int)で変換。C系の基本のcastなのですが。

    キャンセル

  • 2016/11/15 14:36

    %dで実行し256が表示されました。

    キャンセル

  • 2016/11/15 14:37

    修正すべきは’'scale_img=cvCreateImage(cvSize((int)((float)img->width*(float)SCALE_X), (int)((float)img->height*(float)SCALE_Y)), IPL_DEPTH_8U, 3); ’。これで動きが変わるはず。

    キャンセル

  • 2016/11/15 14:45

    丁寧にありがとうございます。
    申し訳ないのですが、特に動きに変わりはありませんでした。

    キャンセル

  • 2016/11/15 14:50

    少し前の回答の部分ですが、マッチング結果の表示'dst1'をimshowするといった部分をもう一度行ってみてください。先ほどの修正部分が生きていればdst1のウインドウサイズが正常になっているはずですから。

    キャンセル

  • 2016/11/15 15:02

    16*6の大きさのdst1が表示されました。(前回とあまり変化していない?)

    キャンセル

  • 2016/11/15 15:05

    本来ならば’256*?’ですよね。だからそれに至る部分をチェック。

    キャンセル

  • 2016/11/15 15:13

    dstウィンドウは、マッチング領域?なので、256*xにはならないと考えています。
    探索領域が55*70になるので、それ以下になるのではないかと考えています。(勘違いだったらすいません)

    キャンセル

  • 2016/11/15 16:46

    こちらも、貴殿が何をもって正しいと判断されるのかは不明ですので、デバッグの仕方としての意見を。まず今回問題とした(int)と0.2などの小数の処理のゴールは恐らく、’ cvResize(img, scale_img, CV_INTER_LINEAR); ’でscale_imgに読み込んだ映像が正しい縮尺で格納されているか?これは直後にimshowすることで確認できますね。続いて本題のmatchingについて。まず理解しないといけないのが入力と出力。正しい出力を得るには入力を正しくです。従って双方の途中データを確認。これにはprintfなどのデバッグプリントもしくはブレークポイントで止めてのウォッチによる内容確認。これを続けて自己の誤りをつぶしていくっていう繰り返しです。

    キャンセル

  • 2016/11/16 10:59

    ありがとうございます。繰り返していきたいと思います。

    キャンセル

0

先ずは’MatchTemplate’の結果dst1をそのままimshowしてみて、その輝度でマッチング状態を確認してみてください。
minmaxの結果の前にしておけば、何が問題か可視化できると思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/11/11 13:10

    表示してみたのですが、よくわかりませんでした、、、
    最大値の座標を表示、囲むことはできないのでしょうか?

    キャンセル

  • 2016/11/11 13:18

    また、囲む枠の左上の座標が最大のマッチング点の座標でいいのでしょうか?

    キャンセル

  • 2016/11/11 13:24

    参考になるページを示します。(過去に見てた)
    http://ishidate.my.coocan.jp/opencv_12/opencv_12.htm

    キャンセル

  • 2016/11/11 13:50

    ありがとうございます。こちらのサイトは、私もよく見ています。
    最大値の座標を表示しようとしたのですが、
    printf("最大値 %lf\n",max_point1);
    これだと、0しか表示しませんでした。
    何が駄目なのでしょうか?

    キャンセル

  • 2016/11/11 13:57

    また、dst1を表示したのですが、非常に小さい(見えないくらい)画像しか表示されません。
    dst1を以下の様に定義しているのですが、駄目なのでしょうか?
    dst1=cvCreateImage(cvSize(abs(grey_img1->width-grey_temp_up->width)+1,abs(grey_img1->height-grey_temp_up->height)+1),IPL_DEPTH_32F,1); //領域確保

    キャンセル

  • 2016/11/11 15:04

    まずパラメーター(例えば’grey_img1->width-grey_temp_up->width’とか)をprintf("%d ",grey_img1->width-grey_temp_up->width);でコンソールに出して観て判断ですね。

    キャンセル

  • 2016/11/11 15:29

    15と表示されました。
    元画像が256*192、テンプレートが35*61
    なのですが、なぜこのような結果になるのでしょうか?

    キャンセル

  • 2016/11/11 15:34

    すいません。計算はあっていました。
    最大値の座標を表示することはできないのでしょうか?

    キャンセル

  • 2016/11/11 15:44

    後は’MinMaxLoc’の結果もprintfしますか?

    キャンセル

  • 2016/11/11 16:12

    色々見てたら、’http://opencv.jp/sample/matching.html’を参考にされていますね?
    ならば’CV_TM_CCOEFF_NORMED’だから最大値の所の座標を中心にすると。

    キャンセル

  • 2016/11/14 12:02

    printfしようとしているのですが、max_point1.xを表示できません。

    キャンセル

  • 2016/11/14 12:27

    であればこの部分にブレークポイントを仕掛けて、止まった時にmax_point1をクイックウォッチで、中に何が入っているかをウォッチのウインドウで確認しましょう。

    キャンセル

  • 2016/11/14 12:42

    0しか表示されません。

    キャンセル

  • 2016/11/14 12:44

    max_point1.xもウォッチするか、ウオッチの中で内部の要素もツリー状に表示できますが、これも’0'ですか?もし'0'ならそれが原因。

    キャンセル

  • 2016/11/14 12:48

    最大値のところを座標の中心にはどのように変更したらいいのでしょうか?

    キャンセル

  • 2016/11/14 12:49

    やりかたを詳しく教えてはいただけないでしょうか?

    キャンセル

  • 2016/11/14 13:11

    囲む長方形?の中心から左のオフセット(長方形の横の長さの半分)を引いて(0以下になった場合の処理も必要)、同様に縦のオフセットを引いて(0以下の処理も同様)そしてこの長方形を描画すれば真中が最大値。

    キャンセル

  • 2016/11/14 13:47

    例えば、
    max_point1.x+rect1.x,max_point1.y+rect1.y
    この部分からオフセットを引けば真ん中になるということでしょうか?

    キャンセル

  • 2016/11/14 13:49

    cvrectangleは一つの頂点と反対側の頂点を決めていると思うのですが、
    この関数で中心からの描画が可能なのでしょうか?

    キャンセル

  • 2016/11/14 14:20

    要は’temp_up->width’と’temp_up->height’が長方形の各辺の長さですから、この半分を左上では引く、右下では足すと真中に最大値になりませんか?

    キャンセル

  • 2016/11/14 14:37

    なるほど、そういことですか。
    直接的に真ん中に点を表示するなどはできないのでしょうか?

    キャンセル

  • 2016/11/14 14:42

    cvCircleでちっちゃい○でも描けば?

    キャンセル

  • 2016/11/14 14:45

    epistemeさんの通り、cvCircleが一番手っ取り早いですね。またその時の色が明確に分かりやすい色であれば。(私はよく水色を使いますが)

    キャンセル

  • 2016/11/14 14:56

    cvCircle(scale_img,cvPoint(max_point1.x+rect1.x,max_point1.y+rect1.y),10,CV_RGB(0,255,255),5,3,0);
    これを使うと、真ん中ではなく左上に表示されるのですが、、、

    キャンセル

  • 2016/11/14 15:05

    rect1.x, rect1.y にはナニが入ってんです?
    cvPoint(max_point1.x, max_point1.y) でマッチ長方形の左上なら、それぞれに幅/2, 高/2 を加えた位置が中心かと。

    キャンセル

  • 2016/11/14 15:05

    ’rect1.x’と’rect1.y’ってどこから?またどの位の値?

    キャンセル

  • 2016/11/14 15:27

    言葉足らずですいません。rect1には、ROIで切り取る際の左上の座標が入っています。

    キャンセル

  • 2016/11/14 15:30

    cvCircleなら引数のcvPoint(の部分は円の中心ですよ。

    キャンセル

  • 2016/11/14 15:31

    void cvCircle(
    CvArr* img, //描写対象の画像
    CvPoint center, //円の中心座標
    int radius, //円の半径
    CvScalar color, //色
    int thickness, //線の太さ
    int line_type, //線の描写法
    int shift //座標の小数点以下のビット数
    );

    キャンセル

  • 2016/11/14 15:37

    ...なんでROIを足さなきゃいけないんだ?
    ROIって”この領域(Region)だけ注目(Interest)してね”ですよね?
    # cvMatchTemplateにROIなんて食わせたっけ?

    キャンセル

  • 2016/11/14 15:53

    ROIの領域にマッチングをしているので必要なのかと考えました。

    キャンセル

  • 2016/11/14 16:01

    "考えた"はいいんだが、実際はどうだったんだ、と。
    cvPoint(max_point1.x, max_point1.y) の位置に○を描いたらドコに現れましたか?
    マッチ対象長方形の左上隅?

    キャンセル

  • 2016/11/14 16:23

    で、結果はどうなりました?デバッグは自分の考え違いを正す行為でもありますし。

    キャンセル

  • 2016/11/14 16:37

    左上隅に表示されました。

    キャンセル

  • 2016/11/14 16:39

    テンプレート幅と高さの半分も足す必要があるとも思い、それぞれ足したところ、場所が変化するようになりました。
    こちらで正しいのでしょうか?

    キャンセル

  • 2016/11/14 16:45

    いやそれで正しいか否かはあなたが確認するんでしょうに。
    てかmax_pointが左上隅を差してるなら、それに幅/2,高/2を加えたら中心位置になるのは自明でしょ?

    キャンセル

  • 2016/11/14 16:49

    最初そのように考えていたのですが、ROIの領域でマッチングした後に、ROIの前の画像で枠を囲もうとすると、ずれが生じるのでrect1を足すことに変更しました。
    ありがとうございます

    キャンセル

  • 2016/11/14 16:50

    ソースが読みにくい(```)で囲んでくれればよいのだが。

    キャンセル

  • 2016/11/14 16:51

    それに変数名がxx1とかxx2は自分自身が良くても、他人には難解。

    キャンセル

  • 2016/11/14 16:51

    今、流れで整理してみている。

    キャンセル

  • 2016/11/14 16:55

    囲ったつもりが下の'''がなくなっていました。
    自分勝手なプログラムで申し訳ありません。

    キャンセル

同じタグがついた質問を見る

  • C

    4517questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • C++

    4423questions

    C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

  • OpenCV

    1509questions

    OpenCV(オープンソースコンピュータービジョン)は、1999年にインテルが開発・公開したオープンソースのコンピュータビジョン向けのクロスプラットフォームライブラリです。