对于模板匹配我在java中使用TM_CCOEFF_NORMED
,直到现在我总是得到非常准确和有意义的结果,但是使用这个特定的模板图像我有错误的匹配分数。模板图像故意不属于输入(源)图像,因此我希望匹配得分较差,最差,但它给了我最好的; " 1.0"并始终在左上角的同一位置找到模板图像。
这是我的模板图片:
带有红色云输入图像的示例输出:(根据程序,绿色突出显示是最佳匹配)
带有黑暗城市输入图像的示例输出:
MinMaxLocResult mmr = Core.minMaxLoc(result);
matchScore = mmr.maxVal;
对于特定的浅绿色模板图像, matchScore
变量始终为1.0,尽管红色和暗图像根本不与绿色相似。我很高兴你的建议和评论有待改进,因为TM_CCOEFF_NORMED
始终将第一个搜索到的正方形/矩形与得分1.0最佳匹配,这是不正确的,另一方面我也尝试了TM_CCORR_NORMED
和TM_SQDIFF_NORMED
他们给出了不同的比赛得分,这很有希望,但仍然TM_CCORR_NORMED
给出了良好的匹配分数,这仍然是我的意外。如果有人可以向我解释匹配方法之间的区别,或者给出已经讨论过这些方法的现有页面的链接,我会很高兴,在opencv docs / tutorials上,只有公式可用但没有详细解释。最后,我想知道何时使用哪种匹配方法来获得最佳效果。
以下是一些代码:
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);
答案 0 :(得分:0)
它不起作用,因为当图片以灰度转换时,它们可能看起来很相似。
cv :: minMaxLoc并不适用于这种情况。
您应该使用其他功能,例如特征提取器或边缘检测器,并使用马哈拉诺比斯距离等指标进行比较
答案 1 :(得分:0)
对于SQDIFF和SQDIFF_NORMED,最佳匹配值较低,其余方法的最佳匹配值较高。
建议:在找到最大或最小位置之前规范化结果图像
希望这会有所帮助。
答案 2 :(得分:0)
我有同样的问题。
似乎模板不能是纯色(所有具有相同值的像素)。
如果模板具有相同的值,则结果的分数必须为1(TM_CCOEFF_NORMED
)。
也许您可以将模板匹配方法更改为TM_CcorrNormed
MinMaxLocResult mmr = Core.minMaxLoc(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])
}
}
}