Opencv 模糊模板匹配?
我正试图把我的头脑集中在简历的基本知识上。最初让我感兴趣的是模板匹配(在Pycon的一次与CV无关的演讲中提到过),所以我想从这里开始 我从这张图片开始: 我想从中找出马里奥。所以我把他删掉了: 我理解在图像周围滑动模板以查看最佳匹配的概念,并且根据教程,我能够使用以下代码找到mario:Opencv 模糊模板匹配?,opencv,computer-vision,Opencv,Computer Vision,我正试图把我的头脑集中在简历的基本知识上。最初让我感兴趣的是模板匹配(在Pycon的一次与CV无关的演讲中提到过),所以我想从这里开始 我从这张图片开始: 我想从中找出马里奥。所以我把他删掉了: 我理解在图像周围滑动模板以查看最佳匹配的概念,并且根据教程,我能够使用以下代码找到mario: def match_template(img, template): s = time.time() img_size = cv.GetSize(img) template_siz
def match_template(img, template):
s = time.time()
img_size = cv.GetSize(img)
template_size = cv.GetSize(template)
img_result = cv.CreateImage((img_size[0] - template_size[0] + 1,
img_size[1] - template_size[1] + 1), cv.IPL_DEPTH_32F, 1)
cv.Zero(img_result)
cv.MatchTemplate(img, template, img_result, cv.CV_TM_CCORR_NORMED)
min_val, max_val, min_loc, max_loc = cv.MinMaxLoc(img_result)
# inspect.getargspec(cv.MinMaxLoc)
print min_val
print max_val
print min_loc
print max_loc
cv.Rectangle(img, max_loc, (max_loc[0] + template.width, max_loc[1] + template.height), cv.Scalar(120.), 2)
print time.time() - s
cv.NamedWindow("Result")
cv.ShowImage("Result", img)
cv.WaitKey(0)
cv.DestroyAllWindows()
到目前为止还不错,但后来我意识到这是难以置信的脆弱。它只会在特定的背景下找到马里奥,并显示特定的动画帧
所以我很好奇,考虑到马里奥总是有着同样的马里奥气质(大小、颜色),有没有一种技术可以让我找到他,不管他现在的身体是静止的,还是各种跑步循环精灵中的一个?有点像模糊匹配,你可以在字符串上做,但图像
也许因为他是唯一的红色物体,有没有一种方法可以简单地跟踪红色像素
另一个问题是从模板中删除背景。也许这会帮助MatchTemplate函数找到Mario,即使他与tempate不完全匹配?到目前为止,我还不完全确定这将如何工作(我看到MatchTemplate中有一个掩码参数,但我必须进一步研究)
我的主要问题是,模板匹配是否是检测基本相同但变化(比如他走路时)的图像的方法,还是我应该研究其他技术
更新:
尝试匹配其他马里奥人
根据mmgp的建议,它应该适用于匹配其他东西,我运行了两个测试 我使用此作为模板来匹配: 然后拍了几张屏幕截图来测试匹配情况 首先,我成功地找到了Mario,并获得了最大值1 然而,试图找到跳跃马里奥的结果是完全失火 现在可以肯定的是,模板中的马里奥和场景中的马里奥面向相反的方向,并且是不同的动画帧,但我认为它们仍然比图像中的任何其他帧匹配得多——如果仅仅是颜色的话。但它将平台定位为与模板最匹配的平台 请注意,此项的最大值为
0.728053808212
接下来,我尝试了一个没有马里奥的场景,看看会发生什么
但奇怪的是,我得到了准确的结果,就像跳转马里奥的图像一样——一直到相似度值:0.728053808212
。马里奥在照片中和他不在照片中一样准确
真奇怪!我不知道底层算法的实际细节,但我可以想象,从标准偏差的角度来看,场景中至少与Mario套装中红色模板匹配的框会比蓝色平台更接近平均距离,对吗?所以,特别令人困惑的是,它甚至不在我所期望的一般领域
我猜这是我这边的用户错误,或者只是一个误会
为什么有类似马里奥的场景与没有马里奥的场景具有同样多的匹配?模板匹配并不总是给出很好的结果。您应该研究关键点匹配 步骤1:找到关键点 让我们假设您成功地删除了Mario或获得了Mario的ROI图像。将此图像作为模板图像。现在,在主图像和模板中查找关键点。现在有两组关键点。一个用于图像,另一个用于Mario(模板) 您可以使用,具体取决于您的首选项 [编辑]: 这就是我用这种方法得到的基于SIFT和flann的knn匹配。我还没有完成边界框部分 由于模板非常小,所以SIFT和SURF不会给出很多关键点。但要获得大量的特征点,可以尝试使用Harris角点检测器。我在图片上应用了哈里斯角,我在马里奥身上得到了很好的分数 步骤2:匹配关键点 如果您使用了SIFT或SURF,那么您将拥有图像和模板的描述符。使用KNN或其他有效的匹配算法匹配这些关键点。如果您使用的是OpenCV,我建议您查看基于法兰的matcher。匹配关键点后,您可能希望过滤掉不正确的匹配。您可以通过K-最近邻来实现这一点,并且根据最近匹配的距离,您可以进一步过滤掉关键点。您可以使用向前向后错误进一步筛选匹配项 前后误差估计:
import sys
import cv2
import numpy
img = cv2.imread(sys.argv[1])
img2 = img[:,:,2]
img2 = img2 - cv2.erode(img2, None)
template = cv2.imread(sys.argv[2])[:,:,2]
template = template - cv2.erode(template, None)
ccnorm = cv2.matchTemplate(img2, template, cv2.TM_CCORR_NORMED)
print ccnorm.max()
loc = numpy.where(ccnorm == ccnorm.max())
threshold = 0.4
th, tw = template.shape[:2]
for pt in zip(*loc[::-1]):
if ccnorm[pt[::-1]] < threshold:
continue
cv2.rectangle(img, pt, (pt[0] + tw, pt[1] + th),
(0, 0, 255), 2)
cv2.imwrite(sys.argv[2], img)