Ask Your Question

Revision history [back]

Template matching on camera capture

Hi I am new to opencv and was trying to see if I can match a template with a frame from a camera capture. The trouble is my template images seems to change even when I do not press 's'. How do I fix this?

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <cv.h>

using namespace std;
using namespace cv;

#define  TPL_WIDTH       40      /* template width       */
#define  TPL_HEIGHT      40      /* template height      */

bool template_selected=FALSE;
int ROIx,ROIy;
Mat frame,templateimage,templatematch;

static void onMouse( int event, int x, int y, int, void* );

int main ( int argc, char **argv )
{
    int c=0;
    Point minloc, maxloc;
    double  minval, maxval;

    VideoCapture cap(0);            // open the default camera
    if(!cap.isOpened()) return -1;      // Check if camera opened

    namedWindow( "FrameWin", CV_WINDOW_AUTOSIZE);
    namedWindow( "template", CV_WINDOW_AUTOSIZE);

    setMouseCallback("FrameWin",onMouse,0);


    // Open the template image 
    templateimage = imread("./template.jpg");

    if(!templateimage.empty()) {
        printf ( "Read template image: Rows = %i \t Cols = %i \n",templateimage.rows,templateimage.cols); 
        template_selected=TRUE;
    } else { printf ( "No template image found. Left click to define template\n"); }


    while (c != 'q') {
        cap >> frame;

        if (template_selected) {
            matchTemplate(frame,templateimage,templatematch, CV_TM_SQDIFF_NORMED );
            normalize(templatematch,templatematch , 0, 1, NORM_MINMAX, -1, Mat() );
            minMaxLoc(templatematch,&minval, &maxval, &minloc, &maxloc, Mat() );
            rectangle(frame,minloc,Point( minloc.x + TPL_WIDTH , minloc.y + TPL_HEIGHT ), Scalar::all(0), 2, 8, 0 );
        }

        imshow("FrameWin",frame);
        imshow("template",templateimage);

        c = cvWaitKey(100);

        if (c=='s') {
            imwrite("template.jpg", templateimage);
            cout << "Left button of the mouse is clicked - position (" << ROIx << ", " << ROIy << ")" << endl;
            cout << "Saved the template to template.jpg" << endl;
        }
    }
    destroyWindow("FrameWin");
    destroyWindow("template");
    return 0;
}

static void onMouse( int event, int x, int y, int, void* ){
    if  ( event == EVENT_LBUTTONDOWN )
    {
        ROIx = x - ( TPL_WIDTH  / 2 );
        ROIy = y - ( TPL_HEIGHT / 2 );

        // Copy the ROI to the template image 
        templateimage = frame(cvRect( ROIx,ROIy,TPL_WIDTH,TPL_HEIGHT ));
        //frame.copyTo(templateimage(Rect( ROIx,ROIy,TPL_WIDTH,TPL_HEIGHT)));


        template_selected=TRUE;
    }
}

Many thanks.

Template matching on camera capture

Hi I am new to opencv and was trying to see if I can match a template with a frame from a camera capture. The trouble is my template images seems to change even when I do not press 's'. How do I fix this?

#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <iostream>
#include <cv.h>

using namespace std;
using namespace cv;

#define  TPL_WIDTH       40      /* template width       */
#define  TPL_HEIGHT      40      /* template height      */

bool template_selected=FALSE;
int ROIx,ROIy;
Mat frame,templateimage,templatematch;

static void onMouse( int event, int x, int y, int, void* );

int main ( int argc, char **argv )
{
    int c=0;
    Point minloc, maxloc;
    double  minval, maxval;

    VideoCapture cap(0);            // open the default camera
    if(!cap.isOpened()) return -1;      // Check if camera opened

    namedWindow( "FrameWin", CV_WINDOW_AUTOSIZE);
    namedWindow( "template", CV_WINDOW_AUTOSIZE);

    setMouseCallback("FrameWin",onMouse,0);


    // Open the template image 
    templateimage = imread("./template.jpg");

    if(!templateimage.empty()) {
        printf ( "Read template image: Rows = %i \t Cols = %i \n",templateimage.rows,templateimage.cols); 
        template_selected=TRUE;
    } else { printf ( "No template image found. Left click to define template\n"); }


    while (c != 'q') {
        cap >> frame;

        if (template_selected) {
            matchTemplate(frame,templateimage,templatematch, CV_TM_SQDIFF_NORMED );
            normalize(templatematch,templatematch , 0, 1, NORM_MINMAX, -1, Mat() );
            minMaxLoc(templatematch,&minval, &maxval, &minloc, &maxloc, Mat() );
            rectangle(frame,minloc,Point( minloc.x + TPL_WIDTH , minloc.y + TPL_HEIGHT ), Scalar::all(0), 2, 8, 0 );
        }

        imshow("FrameWin",frame);
        imshow("template",templateimage);

        c = cvWaitKey(100);

        if (c=='s') {
            imwrite("template.jpg", templateimage);
            cout << "Left button of the mouse is clicked - position (" << ROIx << ", " << ROIy << ")" << endl;
            cout << "Saved the template to template.jpg" << endl;
        }
    }
    destroyWindow("FrameWin");
    destroyWindow("template");
    return 0;
}

static void onMouse( int event, int x, int y, int, void* ){
    if  ( event == EVENT_LBUTTONDOWN )
    {
        ROIx = x - ( TPL_WIDTH  / 2 );
        ROIy = y - ( TPL_HEIGHT / 2 );

        // Copy the ROI to the template image 
        templateimage = frame(cvRect( ROIx,ROIy,TPL_WIDTH,TPL_HEIGHT ));
        //frame.copyTo(templateimage(Rect( ROIx,ROIy,TPL_WIDTH,TPL_HEIGHT)));


        template_selected=TRUE;
    }
}

Many thanks.thanks. Even the example here : http://docs.opencv.org/doc/tutorials/imgproc/histograms/template_matching/template_matching.html

does not work. It compiles, and runs but the result window has the wrong regions highlighted. The closest if TM COEFF NORMED but even that is off.

I am running opencv-2.4.8