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

Java OpenCV模板匹配错误的匹配分数/区域,java,image,opencv,image-processing,computer-vision,Java,Image,Opencv,Image Processing,Computer Vision,对于模板匹配,我在java中使用TM\u CCOEFF\u NORMED,到目前为止,我一直有非常准确和有意义的结果,但对于这个特定的模板图像,我的匹配分数是错误的。模板图像不属于输入(源)图像的目的,所以我希望有不好的匹配分数,最差的,但它给了我最好的;“1.0”,并始终在左上角的同一位置找到模板图像 这是我的模板图像: 带有红云输入图像的输出示例:(根据程序,绿色高光是最佳匹配) 暗城市输入图像的输出示例: MinMaxLocResult mmr = Core.minMaxLoc(res

对于模板匹配,我在java中使用
TM\u CCOEFF\u NORMED
,到目前为止,我一直有非常准确和有意义的结果,但对于这个特定的模板图像,我的匹配分数是错误的。模板图像不属于输入(源)图像的目的,所以我希望有不好的匹配分数,最差的,但它给了我最好的;“1.0”,并始终在左上角的同一位置找到模板图像

这是我的模板图像:

带有红云输入图像的输出示例:(根据程序,绿色高光是最佳匹配)

暗城市输入图像的输出示例:

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

matchScore
对于特定的浅绿色模板图像,变量始终为1.0,尽管红色和黑色图像与绿色完全不同。我很高兴收到您的改进建议和意见,因为
TM\u ccour\u NORMED
始终将第一个搜索的正方形/矩形作为分数为1.0的最佳匹配,这不可能是正确的,另一方面,我也尝试了
TM\u CCORR\u NORMED
TM\u SQDIFF\u NORMED
他们给出了不同的匹配分数,这是有希望的,但仍然
TM\u CCORR\u NORMED
给出了很好的匹配分数,这在我这边仍然是出乎意料的。如果有人能给我解释一下匹配方法之间的区别,或者给我一个链接到已经存在的讨论这些方法的页面,我会很高兴。在opencv文档/教程中,只有公式可用,但没有详细的解释。最后我想知道什么时候使用哪种匹配方法对什么样的图像获得最佳效果

下面是更多的代码:

    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);

这不起作用,因为当图片转换为灰度时,它们可能看起来很相似

cv::minMaxLoc不适用于这种情况


您应该使用其他工具,如特征提取器或边缘检测器,并使用马氏距离等度量对其进行比较。对于SQDIFF和SQDIFF_NORMED,最佳匹配值较低,而对于其他方法,较高值为最佳匹配

建议:在查找最大或最小位置之前,对结果图像进行规格化

希望这有帮助

我也有同样的问题。 似乎模板不能是纯色的(所有像素值相同)。 如果模板具有相同的值,则结果分数必须为1(
TM\u CCOEFF\u NORMED
)。 也许您可以将模板匹配的方法更改为
TM\u ccornormed

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])
        }
    }
}
int阈值=0.95;//对于TM_CCOEFF_标准化和TM_CCORR_标准化
列出认可的项目;
列出认可的核心;

对于(int i=0;iI等待合适的答案,但没有结果……您能给出一些建议的示例吗?您可以使用类似SURF/ORB/FAST的工具。在OpenCV示例文件夹中,您可以找到一些很好的教程和示例。此外,请查看OpenCV CookBook,它也包含有关此主题的示例。OpenCV CookBook只有1个查看amazon,那个家伙说无论如何都不要买它,我现在正在检查你给出的示例,但我需要java语言:(好的,在java中,只要查看JavaCV的文档,了解类似的函数命名!