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

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

ただいまの
回答率

89.63%

opencvを利用した複数枚のテンプレートマッチング

受付中

回答 0

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,526

yamata

score 34

opencvを利用して、カメラで写真を撮り、撮った写真に対してテンプレートマッチングを行うプログラムを作っています。

現状では、キーボードを押すと写真を撮り、その写真に対してマッチングを行うことまでできました。

解決したいことは、
・キーボードを押すと5秒おきに写真を自動で撮影し、自動的にマッチングを行う
・1つの写真に対して、5枚くらいのテンプレートをあてはめてマッチングを行いたい(撮影した写真に5枚のテンプレートをマッチングさせて判断)
・写真を撮ってから、マッチングまでの時間を計測したい→解決しました!
の2点があります。

初心者な為、教えていただけたらと思います。

使用環境は、opencv2.4.9、VC++2010Expressです。

以下に現状のプログラムをのせます。(include部分は省略)
よろしくお願いします。

using namespace cv;


//静止画像をマッチング

int _tmain( int argc , _TCHAR* argv[])
{
    int key;//キー入力用の変数
    CvCapture *capture;//カメラキャプチャ用の構造体
    IplImage *frameImage;//キャプチャ画像用IplImage
    char windowNameCapture[] = "Capture";//キャプチャした画像を表示するウィンドウの名前

    int counter = 0;
    char str[32];


    //カメラを初期化する
    if ( ( capture = cvCreateCameraCapture( -1 ) ) == NULL ) 
    {
        //カメラが見つからなかった場合
        printf( "カメラが見つかりません\n" );
        return -1;
    }


    //Windowの生成
    cvNamedWindow("Show", CV_WINDOW_AUTOSIZE);

    //カメラ・デバイスから画像を取得
    frameImage=cvQueryFrame(capture);

    //メインループ
    while ( 1 )
    {
        //カメラからの入力画像1フレームをframeImageに格納する
        frameImage = cvQueryFrame( capture );

        //画像を表示する
        cvShowImage( windowNameCapture, frameImage );

        //'q'キーが入力されたらループを抜ける
        key = cvWaitKey( 1 );

        if ( key == 'q' )
        {
            break;
        }
        else if( key == 'c')
        {
            sprintf_s(str, "sign.bmp", counter++);
            cvSaveImage(str, frameImage );


        //--------原画像を読み込む---------
        Mat src_image = imread("sign.bmp");
        namedWindow("原画像");
        imshow("原画像", src_image);

        //---------テンプレート画像を読み込む-------
        Mat temp_image = imread("temp.png");
        namedWindow("テンプレート画像");
        imshow("テンプレート画像",temp_image);

        //Mat temp1_image = imread("temp1.png");
        //namedWindow("テンプレート画像");
        //imshow("テンプレート画像1",temp1_image);

        //Mat temp2_image = imread("temp2.png");
        //namedWindow("テンプレート画像");
        //imshow("テンプレート画像2",temp2_image);

        //Mat temp3_image = imread("temp3.png");
        //namedWindow("テンプレート画像");
        //imshow("テンプレート画像3",temp3_image);

        //Mat temp4_image = imread("temp4.png");
        //namedWindow("テンプレート画像");
        //imshow("テンプレート画像4",temp4_image);

        //Mat temp5_image = imread("temp5.png");
        //namedWindow("テンプレート画像");
        //imshow("テンプレート画像5",temp5_image);

        //Mat temp6_image = imread("temp6.png");
        //namedWindow("テンプレート画像");
        //imshow("テンプレート画像6",temp6_image);

        //Mat temp7_image = imread("temp7.png");
        //namedWindow("テンプレート画像");
        //imshow("テンプレート画像7",temp7_image);

        //Mat temp8_image = imread("temp8.png");
        //namedWindow("テンプレート画像");
        //imshow("テンプレート画像8",temp8_image);



        //-------テンプレートマッチングを取る-----
        Mat result;
        matchTemplate(src_image,temp_image,result,TM_CCORR_NORMED);
        //namedWindow("マッチング画像");
        //imshow("マッチング画像",result);

        //Mat result1;
        //matchTemplate(src_image,temp1_image,result,TM_CCORR_NORMED);
        //namedWindow("マッチング画像");
        //imshow("マッチング画像1",result1);

        //Mat result2;
        //matchTemplate(src_image,temp2_image,result,TM_CCORR_NORMED);
        //namedWindow("マッチング画像");
        //imshow("マッチング画像2",result2);

        //Mat result3;
        //matchTemplate(src_image,temp3_image,result,TM_CCORR_NORMED);
        //namedWindow("マッチング画像");
        //imshow("マッチング画像3",result3);

        //Mat result4;
        //matchTemplate(src_image,temp4_image,result,TM_CCORR_NORMED);
        //namedWindow("マッチング画像");
        //imshow("マッチング画像4",result4);

        //Mat result5;
        //matchTemplate(src_image,temp5_image,result,TM_CCORR_NORMED);
        //namedWindow("マッチング画像");
        //imshow("マッチング画像5",result5);

        //Mat result6;
        //matchTemplate(src_image,temp6_image,result,TM_CCORR_NORMED);
        //namedWindow("マッチング画像");
        //imshow("マッチング画像6",result6);

        //Mat result7;
        //matchTemplate(src_image,temp7_image,result,TM_CCORR_NORMED);
        //namedWindow("マッチング画像");
        //imshow("マッチング画像7",result7);

        //Mat result8;
        //matchTemplate(src_image,temp8_image,result,TM_CCORR_NORMED);
        //namedWindow("マッチング画像");
        //imshow("マッチング画像8",result8);



        //-----------マッチング点を求める---------
        Point maxPt;
        minMaxLoc(result,0,0,0,&maxPt);

        //------マッチングを表示する-----
        rectangle(src_image,maxPt,Point(maxPt.x + temp_image.cols,maxPt.y+temp_image.rows),Scalar(0,255,255),2,8,0);
        namedWindow("マッチング表示画像");
        imshow("マッチング表示画像",src_image);

        waitKey(0);
        destroyAllWindows();
        return 0;
        }
        }
}
コード

また、その改良版を作ってみました。
すると、R6010、Array Should be CvMat or IplImage
という警告がでました。
どの部分で重複しているのかわかりません。
R6010の解決方法を教えていただけたらと思います。

よろしくお願いします。

{
    int key;//キー入力用の変数
    CvCapture *capture;//カメラキャプチャ用の構造体
    IplImage *frameImage;//キャプチャ画像用IplImage
    char windowNameCapture[] = "Capture";//キャプチャした画像を表示するウィンドウの名前

    IplImage * temp = NULL;
    IplImage * dst = NULL;
    IplImage * img = NULL;
    IplImage * grey = NULL;


    double max_inter1inkage=0;
    double min_inter1inkage=0;

    CvPoint max_point;
    CvPoint min_point;
    CvPoint corner_point;

    int counter = 0;
    char str[32];


    //カメラを初期化する
    if ( ( capture = cvCreateCameraCapture( -1 ) ) == NULL ) 
    {
        //カメラが見つからなかった場合
        printf( "カメラが見つかりません\n" );
        return -1;
    }


    //Windowの生成
    cvNamedWindow("Show", CV_WINDOW_AUTOSIZE);

    //カメラ・デバイスから画像を取得
    //frameImage=cvQueryFrame(capture);

    //テンプレート・マッチングに用いる相関値データを格納する画像の領域確保
    //グレー・スケール画像用に領域確保
    grey=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
    dst =cvCreateImage(cvSize(img->width-temp->width+1,img->height-temp->height+1),IPL_DEPTH_32F,1);

    //メインループ
    while ( 1 )
    {
        //カメラからの入力画像1フレームをframeImageに格納する
        frameImage = cvQueryFrame( capture );

        //画像を表示する
        cvShowImage( windowNameCapture, frameImage );

        //'q'キーが入力されたらループを抜ける
        key = cvWaitKey( 1 );

        if ( key == 'q' )
        {
            break;
        }
        else if( key == 'c')
        {
            int64 start = cv::getTickCount();//所要時間計測

            sprintf_s(str, "sign.bmp", counter++);
            cvSaveImage(str, frameImage );


            //--------原画像を読み込む---------
            img=cvLoadImage("sign.png",0);
            //namedWindow("原画像");
            //imshow("原画像", src_image);

            //---------テンプレート画像を読み込む-------
            temp=cvLoadImage("temp.png",0);
            //temp=cvLoadImage("temp2.png",0);
            //temp=cvLoadImage("temp3.png",0);
            //temp=cvLoadImage("temp7.png",0);
            //temp=cvLoadImage("temp8.png",0);

            //グレー・スケールに変換して格納
            cvCvtColor(img,grey,CV_BGR2GRAY);

            //-------テンプレートマッチングを取る-----
            grey=cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
            dst =cvCreateImage(cvSize(img->width-temp->width+1,img->height-temp->height+1),IPL_DEPTH_32F,1);    
            cvMatchTemplate(img,temp,dst,CV_TM_CCOEFF_NORMED);

            //-----------マッチング点を求める---------
            cvMinMaxLoc(dst,&min_inter1inkage,&max_inter1inkage,
                    &min_point,&max_point,NULL);

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

            if(max_inter1inkage>0.75)
            {
                //座標を見やすく代入(直接代入でもよい)
                corner_point=cvPoint(max_point.x+temp->width,
                         max_point.y+temp->height);

                //マッチング箇所を四角で描画
                cvRectangle(img,max_point,corner_point,CV_RGB(255,0,0),2);
                printf("Detection\n");
            }

            else
            {
                printf("Lost\n");
            }

            int64 end = cv::getTickCount();
            double elapsedMsec = ( end - start )*1000/cv::getTickFrequency();

            std::cout << elapsedMsec <<"ms" <<std::endl;
        }
    }    

    //メモリ開放
    cvReleaseCapture(&capture);
    cvDestroyWindow("windowNameCapture");
    return 0;

}
コード
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正の依頼

  • 退会済みユーザー

    2016/06/23 21:25

    こちらの質問が他のユーザから「やってほしいことだけを記載した丸投げの質問」という指摘を受けました
    「質問を編集する」ボタンから編集を行い、調査したこと・試したことを記入していただくと、回答が得られやすくなります。

  • KoichiSugiyama

    2016/06/23 21:31

    やりたいことは判りますが、そのために何を調べて、どこがわからないかを明確にしたほうが、アドバイスする側も答えやすいと思います。

    キャンセル

  • yamata

    2016/06/24 12:04

    ありがとうございます。
    まずは、R6010の解決方法を教えていただけたらと思います。

    キャンセル

まだ回答がついていません

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

  • ただいまの回答率 89.63%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

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