0

I'm using OpenCV 3.4.1.

I recently restarted one of my projects I was working on and did a lot of code changes. While testing the new code I ran into a problem which I have no idea how to wrap my head around.


My modified function looks like this (I'm using the cvtColor() function on the Template because it has an alpha channel and it fails assertion when I try to do a matchtemplate):

bool matchCoverSprite(cv::Mat Original, cv::Mat Template, int match_method = CV_TM_CCORR, double Tolerance = 0.3) {
cv::cvtColor(Template, Template, CV_BGRA2BGR);

cv::Mat result;

try {
    cv::matchTemplate(Original, Template, result, match_method, cv::Mat());
}
catch (cv::Exception &e) {
    std::cout << e.msg << std::endl;
}

double minVal; double maxVal; cv::Point minLoc; cv::Point maxLoc;
cv::Point matchLoc;
minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc);

if (match_method == CV_TM_SQDIFF || match_method == CV_TM_SQDIFF_NORMED)
{
    std::cout << "Tolerance was: " << minVal << std::endl;
    matchLoc = minLoc;

    if (minVal < 0.0 + Tolerance || Tolerance == -1.0) {

        /// Show me what you got
        rectangle(Original, matchLoc, cv::Point(matchLoc.x + Template.cols, matchLoc.y + Template.rows), cv::Scalar(255, 0, 0), 2, 8, 0);
        rectangle(result, matchLoc, cv::Point(matchLoc.x + Template.cols, matchLoc.y + Template.rows), cv::Scalar::all(0), 2, 8, 0);
        std::cout << "PASSED" << std::endl;
        return true;
    }
    else {
        return false;
    }
}
else
{
    std::cout << "Tolerance was: " << maxVal << std::endl;
    matchLoc = maxLoc;

    if (maxVal > 1.0 - Tolerance || Tolerance == -1.0) {

        /// Show me what you got
        rectangle(Original, matchLoc, cv::Point(matchLoc.x + Template.cols, matchLoc.y + Template.rows), cv::Scalar(255, 0, 0), 2, 8, 0);
        rectangle(result, matchLoc, cv::Point(matchLoc.x + Template.cols, matchLoc.y + Template.rows), cv::Scalar::all(0), 2, 8, 0);
        std::cout << "PASSED" << std::endl;
        return true;
    }
    else {
        return false;
    }
}


}

To give a bit of context of what I'm doing and using:

I have a bunch of images saved into a binary file (written and read using the follow function here) and I'm reading the images from the said binary file while comparing them to a template.

This is the first image that is in the binary file (template on the left and the image I'm matching it to on the right) Source and template image

However this ends up producing a match: The match


When going over why this shows up as a match I found out that the value of maxVal is way too big (last time I remember doing this the value was always betwen 0 - 1):

big number

And this is the way I call the function above:

if (matchCoverSprite(image, Sprite, CV_TM_CCOEFF, 0.02)) {
    found = true;
}

I've tried using different matching methods but all of them produce strange maxVal and minVal values.

I'm at a loss here so any help is appreciated

  • You're using an un-normalized matching function with `CV_TM_CCOEFF`. Look at [the documentation](https://docs.opencv.org/2.4/doc/tutorials/imgproc/histograms/template_matching/template_matching.html) to see the different possibilities. The high value is not surprising here. Try experimenting with the different matching methods to see which one gives the best results. Also, remember that even though some matches may seem surprising for your eye that looks at objects in the image, OpenCV only looks at raw numerical values and those strange matches may indeed be the best. – Sunreef Jul 09 '18 at 08:12
  • @Sunreef I'm now using CV_TM_CCOEFF_NORMED and it's giving me maxVal and minVal values between 1 and 0. However I'm confused now since I have another function using an un-normalized matching method that does have maxVal/minVal values between 1 and 0 –  Jul 09 '18 at 09:37

0 Answers0