如何在模板匹配代码中获得结果?
Posted
技术标签:
【中文标题】如何在模板匹配代码中获得结果?【英文标题】:how to get the result in template matching code? 【发布时间】:2015-05-13 21:33:12 【问题描述】:我是计算机视觉的初学者。我目前正在做一个项目,在 ios 中使用 matchTemplate 查找两个图像之间的匹配。我面临的问题是找到一种方法来确定两个图像是否匹配或不是,虽然 matchTemplate 运行良好。我想采用结果矩阵的百分比,但我不知道如何也找不到方法。MinMaxLoc 也不适用于我。 如果有人可以帮助我或给我一个想法,我将非常感激,因为我现在处于绝望的境地。 这是代码: `
UIImage* image1 = [UIImage imageNamed:@"1.png"]; UIImage* image2 = [UIImage imageNamed:@"Image002.png"];
// Convert UIImage* to cv::Mat
UIImageToMat(image1, MatImage1);
UIImageToMat(image2, MatImage2);
MatImage1.resize(100 , 180);
MatImage2.resize(100 , 180);
if (!MatImage1.empty())
// Convert the image to grayscale
//we can also use BGRA2GRAY : Blue , Green , Red and Alpha(Opacity)
cv::cvtColor(MatImage1, grayImage1, cv::COLOR_BGRA2GRAY );
cv::cvtColor(MatImage2, grayImage2, cv::COLOR_BGRA2GRAY);
/// Create the result matrix
int result_cols = grayImage1.cols ;
int result_rows = grayImage1.rows ;
result.create( result_cols, result_rows, CV_32FC1 );
/// Do the Matching and Normalize
matchTemplate( grayImage1 , grayImage2 , result , CV_TM_SQDIFF_NORMED);
//Normalize
normalize( result, result, 0, 100, cv::NORM_MINMAX, -1 );
//Threshold
cv::threshold(result , result , 30, 0, CV_THRESH_TOZERO);`
【问题讨论】:
【参考方案1】:matchTemplate(...)
的意图是模板通常比图片小。然后模板作为滑动窗口在图像上移动,并以某种方式计算“匹配分数”,例如使用互相关或平方差。
因此,如果输入图像为 10x10 且模板为 3x3,则模板的位置使左上角位于图像的左上角(模板的中心位于像素 (1,1) 处,假设我们从 0 开始索引)。计算匹配分数,然后模板滑动到(1,2),我们再次匹配。当模板的中间像素位于 (8,1) 时,我们将其向下滑动到下一行 (1,2) 并重复。
此过程的输出结果是一个 8x8 矩阵,其中每个位置的值表示模板在该点时的匹配分数。输出图像的大小为 W-w+1 x H-h+1,其中 WxH 是图像的大小,wxh 是模板的大小。
然后您可以使用 minMaxLoc 计算出输出矩阵中的最高和最低分数,根据您使用的匹配分数,其中之一将最有可能与图像中的模板匹配。
现在您将模板和图像的大小调整为相同的大小:
MatImage1.resize(100 , 180);
MatImage2.resize(100 , 180);
这意味着模板只能在图像中放置一个位置,并且您的输出矩阵应该是 1x1 网格。
你也在使用
CV_TM_SQDIFF_NORMED
这是归一化的平方差。对于这个分数,匹配分数越低越好。即 1x1 输出矩阵中的值越接近 0,模板和图像之间的匹配就越接近。
假设模板和图像的大小为 100x180,那么您可以轻松计算出此匹配分数的最大值为 100x180x255,如果整个图像为黑色,模板为白色,反之亦然。这应该可以帮助您计算出一个合理的阈值,低于该阈值您会说 t=您的模板与图像匹配。
由于您只有 1x1 的输出,但对结果进行标准化或阈值化几乎没有价值。
【讨论】:
以上是关于如何在模板匹配代码中获得结果?的主要内容,如果未能解决你的问题,请参考以下文章