简体   繁体   中英

Live camera template matching using opencv

I'm having some trouble identifying an image (Template) using the code provided on the OpenCV website . I've been using it with some images captured using the Camera application on my PC (Win10 64bit) and it works really good, but when I try to get the image to compare from the camera, it just shows me a black window with the Track bars:

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

using namespace std;
using namespace cv;

/// Global Variables
Mat img;
Mat templ;
Mat result;
char* image_window = "Source Image";
char* result_window = "Result window";

int match_method;
int i=0;
int max_Trackbar = 5;

/// Function Headers
void MatchingMethod( int, void* );

/** @function main enter code heren */
int main( int argc, char** argv )
{
VideoCapture cap(0); // open the default camera
if(!cap.isOpened()) // check if we succeeded
    return -1;
for(;;)
{
    Mat frame;
    cap >> frame;
    /// Load image and template
    img=frame.clone();
    templ = imread( "Template.jpg", 1 );

    /// Create windows
    namedWindow( image_window, CV_WINDOW_AUTOSIZE );
    namedWindow( result_window, CV_WINDOW_AUTOSIZE );

    /// Create Trackbar
    char* trackbar_label = "Method: \n 0: SQDIFF \n 1: SQDIFF NORMED \n 2: TM CCORR \n 3: TM CCORR NORMED \n 4: TM COEFF \n 5: TM COEFF NORMED";
    createTrackbar( trackbar_label, image_window, &match_method, max_Trackbar, MatchingMethod );

    MatchingMethod( 0, 0 );

    waitKey(0);
    return 0;
}
}

/**
 * @function MatchingMethod
 * @brief Trackbar callback
 */
void MatchingMethod( int, void* )
{
/// Source image to display
Mat img_display;
img.copyTo( img_display );

/// Create the result matrix
int result_cols =  img.cols - templ.cols + 1;
int result_rows = img.rows - templ.rows + 1;

result.create( result_rows, result_cols, CV_32FC1 );

/// Do the Matching and Normalize
matchTemplate( img, templ, result, match_method );
normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );

/// Localizing the best match with minMaxLoc
double minVal;
double maxVal;
Point minLoc;
Point maxLoc;
Point matchLoc;

minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );

/// For SQDIFF and SQDIFF_NORMED, the best matches are lower values. For all the other methods, the higher the better
if( match_method  == CV_TM_SQDIFF || match_method == CV_TM_SQDIFF_NORMED )
{
    matchLoc = minLoc;
}
else
{
    matchLoc = maxLoc;
}

/// Show me what you got
rectangle( img_display, matchLoc, Point( matchLoc.x + templ.cols, matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );
rectangle( result, matchLoc, Point( matchLoc.x + templ.cols, matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );

imshow( image_window, img_display );
imshow( result_window, result );

return;
}

The way I think it should work is taking the frame captured on cap>>frame; and copying it on the variable img img=frame.clone(); . Then, it sends it to do the processing each time on the MatchingMethod until any key is pressed.

Me and my project mates would really appreciate anything that makes us solve this problem.

PS:
If there's any doubt about the IDE I'm using, I'm working with Codeblocks.
Also, I'll attach some links with the results I'm getting: Link to Imgur

Thanks to the user api55 I was able to do the live matching, but after consulting I found out that this isn't the best method to track a robot, but at least is a small step towards the final solution. I'll be posting updates on the code so it will be helpful to anyone who needs it.

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

using namespace std;
using namespace cv;

/// Global Variables
Mat img;
Mat templ;
Mat result;
char* image_window = "Source Image";
char* result_window = "Result window";

int match_method;
int i=0;
int max_Trackbar = 5;

/// Function Headers
void MatchingMethod( int, void* );
void delay();

/** @function main */
int main( int argc, char** argv )
{
    VideoCapture cap(0); // open the default camera
if(!cap.isOpened())  // check if we succeeded
{
    return -1;
}
templ = imread( "template3.jpg", 1 );
for(;;)
{
    Mat frame;
    cap >> frame; // get a new frame from camera
    if(waitKey(30) >= 0) break;
    while(frame.empty())
    {
        std::cout<<"Frame Vacio"<<std::endl;
    }
    // do any processing
    /// Load image and template
    img=frame.clone();
    //frame.clone();

    /// Create windows
    namedWindow( image_window, CV_WINDOW_AUTOSIZE );
    namedWindow( result_window, CV_WINDOW_AUTOSIZE );

    /// Create Trackbar
    //char* trackbar_label = "Method: \n 0: SQDIFF \n 1: SQDIFF NORMED \n 2: TM CCORR \n 3: TM CCORR NORMED \n 4: TM COEFF \n 5: TM COEFF NORMED";
    //createTrackbar( trackbar_label, image_window, &match_method, max_Trackbar, MatchingMethod );


    MatchingMethod( 0, 0 );

    waitKey(30);

}
return 0;
}

/**
 * @function MatchingMethod
 * @brief Trackbar callback
 */
void MatchingMethod( int, void* )
{
/// Source image to display
Mat img_display;
img.copyTo( img_display );

/// Create the result matrix
int result_cols =  img.cols - templ.cols + 1;
int result_rows = img.rows - templ.rows + 1;

result.create( result_rows, result_cols, CV_32FC1 );

/// Do the Matching and Normalize
matchTemplate( img, templ, result, match_method );
normalize( result, result, 0, 1, NORM_MINMAX, -1, Mat() );

/// Localizing the best match with minMaxLoc
double minVal;
double maxVal;
Point minLoc;
Point maxLoc;
Point matchLoc;

minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, Mat() );

/// For SQDIFF and SQDIFF_NORMED, the best matches are lower values. For all the other methods, the higher the better
if( match_method  == CV_TM_SQDIFF || match_method == CV_TM_SQDIFF_NORMED )
{
    matchLoc = minLoc;
}
else
{
    matchLoc = maxLoc;
}

/// Show me what you got
rectangle( img_display, matchLoc, Point( matchLoc.x + templ.cols, matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );
rectangle( result, matchLoc, Point( matchLoc.x + templ.cols, matchLoc.y + templ.rows ), Scalar::all(0), 2, 8, 0 );

imshow( image_window, img_display );
imshow( result_window, result );

return;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM