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

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

ただいまの
回答率

90.50%

  • C++

    3455questions

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

  • OpenCV

    1079questions

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

opencvでの背景差分

解決済

回答 1

投稿

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

yamata

score 28

opencvで背景差分を行った後にテンプレートマッチングを行いたいです。

背景差分で動作確認を行ったプログラム、テンプレートマッチングで動作確認を行ったプログラム(両者ともに正常な動作確認済み)
を合わせてプログラムの作成を行ったのですが、画像のようなエラーが出ました。

チャンネル数によるエラーだと考えるのですが、特におかしい部分がないと思います(多分)。

エラー箇所を教えていただけたらと思います。

opencv2.4.9、VC++2010expresを使用しています。

イメージ説明

int main( int argc , char** argv)
{
    int counter = 0;
    char str[99];

    #define LINE_THICKNESS    1
    #define LINE_TYPE    8
    #define SHIFT    0

    #define SCALE_X 0.4
    #define SCALE_Y 0.4

    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 * temp1 = NULL;
    IplImage * temp2 = NULL;
    IplImage * haikei = NULL;
    IplImage * scale_haikei = NULL;
    IplImage * grey_temp1 = NULL;
    IplImage * grey_temp2 = NULL;
    IplImage * grey_haikei_up = NULL;
    IplImage * grey_haikei_side = NULL;
    IplImage * haikei_img1 = NULL;
    IplImage * haikei_img2 = NULL;
    IplImage * haikei_up = NULL;
    IplImage * haikei_side = NULL;

    FILE *file;
    file=fopen("C:\\opencv_ICImage\\2017-1-12\\銀小ネジ\\ver2\\結果\\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;

    int i = 1;      
    int top = 0;
    double sum = 0;
    double sum1 = 0;
    int before = 0;
    int after =0;
    int threshold = 0;

    //---------テンプレート画像を読み込む-------
    temp1=cvLoadImage("C:\\opencv_ICImage\\2017-1-12\\銀小ネジ\\ver2\\temp_up.bmp",CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);    //カラー読み込み
    temp2=cvLoadImage("C:\\opencv_ICImage\\2017-1-12\\銀小ネジ\\ver2\\temp_side.bmp",CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);    //カラー読み込み
    haikei=cvLoadImage("C:\\opencv_ICImage\\2017-1-12\\銀小ネジ\\ver2\\静止画\\img1.bmp",CV_LOAD_IMAGE_ANYDEPTH | CV_LOAD_IMAGE_ANYCOLOR);

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

    haikei_up=cvCloneImage(scale_haikei);
    haikei_side=cvCloneImage(scale_haikei);

    //-----------------ROIの設定----------------------
        CvRect rect1;
        rect1.x = 112;
        rect1.y = 68;
        rect1.width = 39;
        rect1.height = 60;
        cvSetImageROI(haikei_up,rect1);

        CvRect rect2;
        rect2.x = 218;
        rect2.y = 70;
        rect2.width = 40;
        rect2.height = 55;
        cvSetImageROI(haikei_side,rect2);//左上、幅、高さ
    //----------------------------------------------------

    grey_temp1=cvCreateImage(cvGetSize(temp1),IPL_DEPTH_8U,1);        //1チャンネル8ビットのIplImage作成(元画像)
    grey_temp2=cvCreateImage(cvGetSize(temp2),IPL_DEPTH_8U,1);        //1チャンネル8ビットのIplImage作成(元画像)
    grey_haikei_up=cvCreateImage(cvGetSize(haikei_up),IPL_DEPTH_8U,1);        //1チャンネル8ビットのIplImage作成(元画像)
    grey_haikei_side=cvCreateImage(cvGetSize(haikei_side),IPL_DEPTH_8U,1);        //1チャンネル8ビットのIplImage作成(元画像)

    cvCvtColor(temp1,grey_temp1,CV_BGR2GRAY);
    cvCvtColor(temp2,grey_temp2,CV_BGR2GRAY);
    cvCvtColor(haikei_up,grey_haikei_up,CV_BGR2GRAY);    
    cvCvtColor(haikei_side,grey_haikei_side,CV_BGR2GRAY);    

    temp_up = cvCreateImage( cvGetSize(grey_temp1), IPL_DEPTH_8U, 1 );    //    差分画像用IplImage
    temp_side = cvCreateImage( cvGetSize(grey_temp2), IPL_DEPTH_8U, 1 );    //    差分画像用IplImage

    //    greyと背景画像との差分をとる
    cvAbsDiff( grey_temp1, grey_haikei_up, temp_up );
    cvAbsDiff( grey_temp2, grey_haikei_side, temp_side );

    cvNamedWindow("haikei_temp_up_window",CV_WINDOW_AUTOSIZE);  
    cvShowImage("haikei_temp_up_window",temp_up);

    cvNamedWindow("haikei_temp_side_window",CV_WINDOW_AUTOSIZE);  
    cvShowImage("haikei_temp_side_window",temp_side);

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

            //------------------------原画像読み込み-------------------------------
            std::stringstream filename;
            filename << "C:\\opencv_ICImage\\2017-1-12\\銀小ネジ\\ver2\\静止画\\img"  << number << ".bmp";
            std::cout << "filename=" << filename.str() << std::endl;
            IplImage* img=cvLoadImage(filename.str().c_str());
            //--------------------------------------------------------------------------

            //変換画像用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(112,68),cvPoint(151,128),CV_RGB(255,0,0),LINE_THICKNESS,LINE_TYPE,SHIFT);
            cvRectangle(scale_img,cvPoint(218,70),cvPoint(258,125),CV_RGB(255,0,0),LINE_THICKNESS,LINE_TYPE,SHIFT);//左上、右下

            //-----------------ROIの設定----------------------
            CvRect rect3;
            rect3.x = 112;
            rect3.y = 68;
            rect3.width = 39;
            rect3.height = 60;
            cvSetImageROI(copy_img1,rect3);

            CvRect rect4;
            rect4.x = 218;
            rect4.y = 70;
            rect4.width = 40;
            rect4.height = 55;
            cvSetImageROI(copy_img2,rect4);//左上、幅、高さ
            //----------------------------------------------------

            //テンプレート・マッチングに用いる相関値データを格納する画像の領域確保
            //グレー・スケール画像用に領域確保
            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作成(元画像)

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

            //背景差分-------------------------------------------------------------------------    
            haikei_img1 = cvCreateImage( cvGetSize(copy_img1), IPL_DEPTH_8U, 1 );    //    差分画像用IplImage
            haikei_img2 = cvCreateImage( cvGetSize(copy_img2), IPL_DEPTH_8U, 1 );    //    差分画像用IplImage

            //    grayImageと背景画像との差分をとる
            cvAbsDiff( grey_img1, grey_haikei_up, haikei_img1 );
            cvAbsDiff( grey_img2, grey_haikei_side, haikei_img2 );
            //---------------------------------------------------------------------------------------


            dst1=cvCreateImage(cvSize(abs(rect3.width-temp_up->width)+1,abs(rect3.height-temp_up->height)+1),IPL_DEPTH_32F,1);    //領域確保
            dst2=cvCreateImage(cvSize(abs(rect4.width-temp_side->width)+1,abs(rect4.height-temp_side->height)+1),IPL_DEPTH_32F,1);    //領域確保

            cvMatchTemplate(haikei_img1,temp_up,dst1,CV_TM_CCOEFF_NORMED);    //テンプレートマッチング
            cvMatchTemplate(haikei_img2,temp_side,dst2,CV_TM_CCOEFF_NORMED);    //テンプレートマッチング


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

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

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


            sprintf_s(str, "C:\\opencv_ICImage\\2017-1-12\\銀小ネジ\\ver2\\結果\\result_%04d.bmp", number);
            cvSaveImage(str, scale_img );

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

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

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

            cvWaitKey(0);

            //メモリ解放
            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);

    //メモリ開放
    cvDestroyWindow("img_window");
    return 0;
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 1

check解決した方法

0

背景差分を行う際に同じROIのサイズでなければいけないということを知りませんでした。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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

  • C++

    3455questions

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

  • OpenCV

    1079questions

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