Opencv matchTemplate不匹配

4
我正在使用OpenCV 3.0.0来将一张图片定位到另一张图片中。理论上,matchTemplate函数是我需要使用的,但是看到结果后,我不再确定了。
问题在于,根据输入的图片不同,结果可能完全准确或者完全不准确。
例如1:
主图像 Simple 模板 Simple 结果 Simple 这里没有任何抱怨。在这种情况下匹配是完美的。但是现在我替换了我想要使用的图片,然后...
主图像 Complex 模板 Complex 结果 enter image description here 所以,根本不起作用(结果矩形在图像右上角)。在此示例中的任何方法(例如CORR NORMED)都会打印出模板所在的矩形。所有的结果都远远不准确。
因此,我的问题是,matchTemplate的结果是否取决于主图像具有多少不同的颜色/形状? SURF或SIFT能帮助我吗? 你们知道任何可以帮助我将模板定位到另一张图片中的函数吗?
提前感谢!
PS:我没有添加任何代码,因为我认为这不是那种问题,因为第一个示例效果很好。

下载完您的图像后,我相当确定您的模板大小已被缩小?模板匹配不是尺度不变的! - Micka
1个回答

13

你的问题可能是,模板匹配不具有尺度不变性,而你的模板大小不适合物体的大小。

使用此输入和代码,我获得以下输出:

输入图像:

enter image description here

输入模板:

enter image description here

代码:基本上取自opencv教程:http://docs.opencv.org/doc/tutorials/imgproc/histograms/template_matching/template_matching.html

int main()
{
    cv::Mat input = cv::imread("../inputData/TemplateMatch.jpg");

    cv::Mat gray;
    cv::cvtColor(input,gray,CV_BGR2GRAY);

    cv::Mat templ = cv::imread("../inputData/Template2.jpg");

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

    result.create( result_cols, result_rows, CV_32FC1 );

    int match_method = CV_TM_SQDIFF;

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

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

    minMaxLoc( result, &minVal, &maxVal, &minLoc, &maxLoc, cv::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
    cv::rectangle( input, matchLoc, cv::Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), cv::Scalar::all(0), 2, 8, 0 );
    cv::rectangle( result, matchLoc, cv::Point( matchLoc.x + templ.cols , matchLoc.y + templ.rows ), cv::Scalar::all(0), 2, 8, 0 );


    cv::imshow("input", input);
    cv::imshow("template", templ);

    cv::imwrite("../outputData/TemplateMatch.jpg", input);
    cv::waitKey(0);
    return 0;
}

输出:

在此输入图片描述


2
哦,原来是这个问题。非常感谢你,Micka。非常感激^^ - Miguel Cantó Bataller

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接