Trying to use OpenCV's template matching for localization and detection

1. OpenCV's template matching function:

CV_EXPORTS_W void matchTemplate( InputArray image, InputArray templ, OutputArray result, int method );

How template matching works:
It is basically the same as the back projection of the histogram, and the general process is as follows: by sliding the image block on the input image image, the actual image block and the template image templ are matched.
Suppose we have a 100x100 input image image and a 10x10 template image templ, the search process is as follows:
(1) Starting from the upper left corner (0,0) of the input image image, cut a block (0,0) to The temporary image of (10,10);
(2) Compare the temporary image and the template image templ, the comparison result is recorded as c, and stored at (0,0) of the result image result, that is, the result is at (0,0)
(3) Slide to the right to cut the image block, repeat the steps (1)~(2), and record it in the result image result; until the lower right corner of the input image image .
It can be seen that the histogram backprojection compares the histogram, while the template matching compares the pixel values ​​of the image; template matching is faster than histogram backprojection, but some people think that the robustness of histogram backprojection will be better.
The matching method of template matching:
CV_TM_SQDIFF Squared difference matching method: This method uses the squared difference to match; the best matching value is 0; the worse the matching, the greater the matching value.
CV_TM_CCORR Correlation matching method: This method adopts multiplication operation; the larger the value, the better the matching degree.
CV_TM_CCOEFF Correlation coefficient matching method: 1 means perfect match; -1 means worst match.
CV_TM_SQDIFF_NORMED Normalized squared difference matching method
CV_TM_CCORR_NORMED Normalized correlation matching method
CV_TM_CCOEFF_NORMED Normalized correlation coefficient matching method

enum { TM_SQDIFF=0, TM_SQDIFF_NORMED=1, TM_CCORR=2, TM_CCORR_NORMED=3, TM_CCOEFF=4, TM_CCOEFF_NORMED=5 };

2. OpenCV's function of locating extreme values:

CV_EXPORTS_W void minMaxLoc(InputArray src, CV_OUT double* minVal, CV_OUT double* maxVal=0, CV_OUT Point* minLoc=0, CV_OUT Point* maxLoc=0, InputArray mask=noArray());

Brief description:
(1) minMaxLoc finds the minimum value minVal and its position minLoc in the matrix src; the maximum value maxVal and its position maxLoc.
(2) If the above parameters do not need to be solved, they can be set to NULL or 0.
(3) The parameter mask does not know how to use it and can be ignored.

3. Sample program:

#include<iostream>
#include<opencv.hpp>

using namespace cv;
using namespace std;

vector<float> Match(const Mat& src, const Mat& obj, vector<Rect>& rect, int type, int num = 1);

void main()
{
    Mat src = imread("F:\\Test\\LaLa.png");
    Mat obj = imread("F:\\Test\\LaLa0.png");
    namedWindow("Match");   imshow("Match", obj);

    Mat src0 = src.clone(), dst;
    //cvtColor(src, src, CV_BGR2GRAY);
    //cvtColor(obj, obj, CV_BGR2GRAY);
    //normalize(src, src, 0, 255, NORM_MINMAX);
    //normalize(obj, obj, 0, 255, NORM_MINMAX);

    namedWindow("Result");  int type = 0, num = 1;
    createTrackbar("Type", "Result", &type, 5);
    createTrackbar("Number", "Result", &num, 5);

    vector<Rect> rect;  vector<float> pro;
    while ((waitKey(500) & 255) != 13)
    {
        dst = src0.clone();
        pro = Match(src, obj, rect, type, num);
        for (int i = 0; i < num; ++i)
        {
            rectangle(dst, rect[i], Scalar(0,255,0), 2);
            cout << i << "\t" << rect[i] << "\t" << pro[i] << endl;
            Point center(rect[i].x + rect[i].width/2, rect[i].y + rect[i].height/2);
            circle(dst, center, 4, Scalar(0, 255, 0), -1);
        }//end for
        imshow("Result", dst);  cout << endl;
    }//end while
}//end main

vector<float> Match(const Mat& src, const Mat& obj, vector<Rect>& rect, int type, int num)
{
    Mat dst;
    matchTemplate(src, obj, dst, type);
    normalize(dst, dst, 0, 255, NORM_MINMAX);

    vector<float> pro;  rect.clear();
    double mx = 0;  Point loc, pre(-1, -1);
    for (int i = 0; i < num;)
    {
        minMaxLoc(dst, NULL, &mx, NULL, &loc);
        if (abs(loc.x - pre.x) > 10 && abs(loc.y - pre.y) > 10)
        {
            rect.push_back(Rect(loc.x, loc.y, obj.cols, obj.rows));
            pro.push_back(mx/255);  pre = loc;  ++i;
        }//end if
        dst.at<float>(loc.y, loc.x) = 0;    mx = 0;
    }//end for
    return pro;
}//end Match

write picture description here

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325339996&siteId=291194637