2015-11-30 65 views
0

我在图像处理中的新手,我了解模版匹配,并且我从OpenCV一些帮助,但我不明白的一些代码行,这里是代码模板匹配使用的OpenCV + Python的

import cv2 
import numpy as np 
from matplotlib import pyplot as plt 
img_rgb = cv2.imread('mario.png') 
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY) 
template = cv2.imread('coin.png', 0) 
w, h = template.shape[::-1] 
count = 0 

res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED) 
threshold = 0.8 
loc = np.where(res >= threshold) 
for pt in zip(*loc[::-1]): 
    count += 1 
    cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2) 

cv2.imwrite('res.png', img_rgb) 
print(count) 

的目标是模板匹配超级马里奥地图中的硬币。
我的问题:
1.在循环for pt in zip(*loc[::-1]):我把计数器,当我打印的打印65,而硬币只有19
2.什么是可变threshold=0.8的功能,当我改变的价值,结果图像是变化。

任何人都可以帮助我回答我的问题吗? 预先感谢您。

+0

您是否阅读过关于[matchTemplate'返回的内容的OpenCV文档](http://docs.opencv.org/2.4/modules/imgproc/doc/object_detection.html)? – kmac

+0

是的,我有。但我不明白为什么柜台显示65,而硬币只有19 – Cesario

+0

这种方法不是魔术,所以你会得到一些误报(非硬币标记为硬币)和一些错误的否定(硬币未标记作为硬币)。听起来你有65个硬币标签,图像中只有19个硬币。按照Aditya的建议尝试提高门槛。但是这种方法可能无法达到你所希望的效果。您也可以在之后应用过滤来改善您的结果。 – kmac

回答

1

阈值0.8表示匹配应至少为模板图像的80%以及感兴趣的源区域。因此如果它大于805就是一枚硬币。如果你降低门槛,假阳性结果即使不是硬币也会增加。

对于Zip中的pt(* loc [:: - 1]):该命令适用于值大于阈值的点。拉链是所有这些点的容器,它将迭代到所有这些点,并围绕此封闭实体绘制矩形,即硬币在这里。

希望这有助于根据您正在使用的图像亮度明白:)

+0

感谢您的优秀解释,但我仍不明白为什么计数器是65而不是19,当我将其更改为1时,它显示0 – Cesario

+0

您可以绘制直方图来查看您在不同响应范围内的命中率。 1正在删除所有内容,请尝试0.8和1之间的值。 – kmac

0

阈值= 0.8的作品。 如果图像上的光线正确,则阈值> 0.8将起作用,但主要是在相机图像中,亮度会有所不同,所以亮度> 0.65可以起作用。 要匹配更多点,您必须降低阈值。