简体   繁体   English

OpenCV模板匹配错误匹配分数/区域

[英]OpenCV Template Matching Wrong Match Score / Area

For template matching Im using TM_CCOEFF_NORMED in java and until now I always had pretty accurate and meaningful results but with this specific template image I'm having wrong match scores. 对于在Java中使用TM_CCOEFF_NORMED进行模板匹配的即时TM_CCOEFF_NORMED ,直到现在我一直都得到非常准确和有意义的结果,但是使用此特定模板图像时,我的匹配分数不正确。 The template image doesnt belong to input(source) image on purpose, so Im expecting to have bad matching scores, the worst, but it gives me the best; 模板图像并非故意属于输入(源)图像,因此Im期望匹配分数不好,最差,但它给了我最好的; "1.0" and always finds the template image at the same place top left corner. “ 1.0”,并始终在左上角的同一位置找到模板图像。

Here is my template image: 这是我的模板图片:

在此处输入图片说明

Example output with a red cloud input image: (the green highlight is the best match according to the program) 输出带有红色云输入图像的示例:(根据程序,绿色突出显示是最佳匹配)

在此处输入图片说明

Example output with a dark city input image: 带有黑暗城市输入图像的示例输出:

在此处输入图片说明

MinMaxLocResult mmr = Core.minMaxLoc(result);
matchScore = mmr.maxVal;

matchScore variable is always 1.0 for the specific light green template image although the red and the dark images are not similar to green at all. 对于特定的浅绿色模板图像, matchScore变量始终为1.0,尽管红色和深色图像与绿色完全不相似。 I would be glad for your suggestions and comments for improvement because TM_CCOEFF_NORMED gives always the first searched square/rectangle as best match with score 1.0, this cant be correct, on the other hand I also tried TM_CCORR_NORMED and TM_SQDIFF_NORMED they gave different match scores, this is promising but still TM_CCORR_NORMED gave good matching score which is still unexpected from my side. 我很高兴收到您的改进建议和建议,因为TM_CCOEFF_NORMED始终将第一个搜索到的正方形/矩形作为最佳匹配,得分为1.0,这不能正确,另一方面,我也尝试过TM_CCORR_NORMEDTM_SQDIFF_NORMED他们给出了不同的匹配分数,这很有前途,但TM_CCORR_NORMED仍然TM_CCORR_NORMED了不错的匹配分数,这在我看来仍然是意料之外的。 I would be glad if someone can explain me the difference between the matching methods or give a link to already an existing page where these methods are being discussed, on opencv docs/tutorials there are only the formulas available but no detailed explanation. 如果有人可以向我解释匹配方法之间的区别,或者提供一个链接到已经讨论这些方法的现有页面,我会很高兴。在opencv docs / tutorials上,只有可用的公式,而没有详细的解释。 In the end I would like to know when to use which match method for what kind of image to get the best results. 最后,我想知道何时对哪种类型的图像使用哪种匹配方法以获得最佳效果。

Here is some more code: 这是更多代码:

    Mat img = Highgui.imread(inFile);
    Mat templ = Highgui.imread(templateFile);

    // / Create the result matrix
    int result_cols = img.cols() - templ.cols() + 1;
    int result_rows = img.rows() - templ.rows() + 1;
    Mat result = new Mat(result_rows, result_cols, CvType.CV_32FC1);

    // / Do the Matching 
    Imgproc.matchTemplate(img, templ, result, match_method);
    // / Localizing the best match with minMaxLoc
    MinMaxLocResult mmr = Core.minMaxLoc(result);

It doesn't work because when pictures are converted in grayscale, they might look similar. 这是行不通的,因为当图片以灰度转换时,它们看起来可能很相似。

cv::minMaxLoc doesn't work for this kind of situations. cv :: minMaxLoc在这种情况下不起作用。

You should use something else, such as Feature extractor or edge detector and compare it using a metric such as Mahalanobis distance 您应该使用其他东西,例如特征提取器或边缘检测器,并使用度量值(例如马氏距离)进行比较

For SQDIFF and SQDIFF_NORMED the best matches are lower values and for rest of the methods the higher is the best match. 对于SQDIFF和SQDIFF_NORMED,最佳匹配是较低的值,而对于其他方法,较高的是最佳匹配。

Suggestion : normalize the result image before finding for max or min locations 建议:在找到最大或最小位置之前对结果图像进行归一化

Hope this helps. 希望这可以帮助。

I have the same problem. 我也有同样的问题。 It seems that the template could't be pure color(all pixels with same value). 看来模板不能是纯色(所有像素都具有相同的值)。 If the template with same value, the score of result must to be 1( TM_CCOEFF_NORMED ). 如果模板的值相同,则结果的分数必须为1( TM_CCOEFF_NORMED )。 Maybe you could change the method of template matching to TM_CcorrNormed 也许您可以将模板匹配的方法更改为TM_CcorrNormed

MinMaxLocResult mmr = Core.minMaxLoc(result);

This method will give you the best match in the result, no matter what it is correct.So in my experience, I used the two loop for finding the best match in result. 无论正确与否,该方法都会为您提供最佳匹配结果。因此,根据我的经验,我使用了两个循环来找到最佳匹配结果。

int threshold = 0.95; // for TM_CCOEFF_NORMED and TM_CCORR_NORMED
List<Rect> recognizedRects;
List<double> recognizedScores;
for(int i=0;i<result.height;i++) {
    for(int j=0;j<result.width;j++) {
        if(result.data[i,j,0] > threshold) {
            recognizedRects.add(new Rectangle(j,i,template.width,template.height);
            recognizedScores.add(result.data[i,j,0])
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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