• 締切済み

テンプレートマッチングの高速化手法について

openCVのテンプレートマッチング(cvMatchTemplate関数)のアルゴリズムについて質問があります。 相関係数マッチング手法(第4引数:CV_TM_CCOEFF_NORMED)を、openCVを使った場合と自分で実装したものを比べたところ、断然openCVの方が速く計算できました。 openCVではどのような高速化手法を利用しているのでしょうか? どなたかわかる方がいましたら教えてください。

みんなの回答

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

ソース公開されてますから、眺めてみては?

関連するQ&A

  • OpenCV cvmatchtemplate

    OpenCVで画像一致検出のプログラムを組んでいます。 Cvmatchtemplateは動作していますが、そのパラメーター、 CV_TM_SQDIFFはSquared difference 輝度差の二乗和 CV_TM_CCORRはCross correlation 相互相関 CV_TM_CCOEFFはCorrelation coefficient 相関係数 でNORMEDはそれらの正規化したもの と言う所までは判ったのですが、(分かったでは無い-笑-)それらの意味が良く分かりません、かろうじて理解出来るのは輝度差の二乗和のみです。 私としては各々の詳細を理解出来なくても、どの様な結果を導きたい時使うパラメーターかが判れば良いのですが、色々サイトを探しても、数式が書かれている所はありますが具体例が書かれている所が見つかりませんでした。 どなたか良いサイト、もしくは本をご存知無いでしょうか。 よろしくお願いいたします。

  • テンプレートマッチングの座標を表示する方法を教えて

    OpenCVでテンプレートマッチング(http://opencv.jp/sample/matching.html)するには、  (1)cvMatchTemplate (src_img, tmp_img, dst_img, CV_TM_CCOEFF_NORMED);  (2) cvMinMaxLoc (dst_img, &min_val, &max_val, &min_loc, &max_loc, NULL); の2種類を用いていますが、 マッチング部分の座標を取得して、表示するにはどうすればよいのでしょうか? ご存知なら、どうか教えていただけないでしょうか。

  • 画像の比較について

    書き込み失礼します。 プログラム初心者です。 現在、私はVC++とOpenCVをつかってテンプレートマッチングなるものを試しています。 その中でマッチング結果(0.0や0.5、1.0など)を見たいと思っているのですが、画像と画像を比較すると0.0から1.0に正規化しているにも関わらず現れる数値は15495939などの値になってしまったりします。 見ようとしている場所が悪いのかプログラムが悪いのか画像が悪いのか(画像はカメラで取得したものを使用)が全くわかりません。 大変申し訳ありませんがご助言に頂けたら幸いです。 いかに私が書いているテンプレートマッチングのプログラムの一部をしめします。 //テンプレートマッチングを行う cvMatchTemplate(sourceBinaryImage,templateBinaryImage,differenceMapImage,CV_TM_SQDIFF); //テンプレートが画像のどの部分にあるのかという情報を得る cvMinMaxLoc(differenceMapImage,&minValue,&maxValue,&minLocation,&maxLocation,NULL); //結果の表示方法の統一 cvNormalize(differenceMapImage,differenceMapImage,1,0,CV_MINMAX); printf("%d\n",&minValue);

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

  • 画像パターンマッチングの演算について

    画像認識のパターンマッチングの中で正規化相互相関法がありますが、 テンプレートとして使う画像と比較画像において、 例えば、「し」という画像のテンプレートに対し、比較画像が「じ」である場合は「゛」が余分にあり正規化相互相関法では相関1になりませんが(背景濃度値は同じとして)、 これを「し」の部分が合致しているため、相関1としたいのですが、何か良い演算方法はありますでしょうか。 つまり、テンプレートに対し全く同じ領域が合致してさえすれば、テンプレートの画素以外にノイズがあっても相関を1としたいのです。 相互相関の手法以外でももちろん結構です。詳しい方ご教授ください。

  • 画像処理 (3次元のモデルと画像のマッチングのアルゴリズムについて)

    画像処理を勉強しているものなのですが、 現在2次元画像同士のマッチング(テンプレートマッチング)などはプログラムが組めるのですが 計算機内に作った3次元のモデルと画像のマッチング、つまり3次元物体の姿勢推定のアルゴリズムがよくわかりません。簡単でいいので教えてください。 よろしくお願いします。

  • 解像度の異なる画像間のマッチング

    添付画像(右上がテンプレート画像)のような,2種類の異なる解像度の画像を用いてテンプレートマッチングを行いたい場合,どのような手法がありますでしょうか. ここまで大きく解像度が変わると通常のFFTなどによる画像相関では不可能で,SIFTなどの画像特徴量を用いる方法は使えないことも確認しています. どちらかの解像度をもう片方に合わせれば可能ですが,拡大率等の情報が既知ではない状態でマッチングを行いたいと考えています.また,テンプレートは時々刻々変わることを想定していますので,顔認識のような特定の特徴量を用いることもできません. 特徴量を用いない,拡大縮小回転に頑強な良い方法をご存知でしたら宜しくお願い致します.

  • 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をやりだした初心者です. opencvには「canny関数」だとか「2値化関数」だとかありますよね. アルゴリズムが知りたいので,関数の中身を参照したいです. そのような方法はあるのでしょうか? opencvに詳しい方ご教授お願いいたします(u_u)

  • opencvの関数の中身をみることができますか?

    opencvの、たとえば「cvAdd」や「cvAbs」などの関数がどういったアルゴリズムで計算しているか知りたのですが、見ることは可能でしょうか? openCVの関数の中身を参照することはできますか? http://okwave.jp/qa/q5365660.html この質問を見た所canny関数は「cvcanny.cpp」で見ることが可能なようですが「cvAdd.cpp」などのファイルがないため、これらの中身を見る方法がわかりません。