OpenCV模板匹配教程:理论与实践
创作时间:
作者:
@小白创作中心
OpenCV模板匹配教程:理论与实践
引用
1
来源
1.
https://docs.opencv.org/4.x/d4/dc6/tutorial_py_template_matching.html
目标
本章将学习如何使用模板匹配在图像中查找对象,具体包括:
- 使用模板匹配在图像中查找对象
- 了解cv.matchTemplate()和cv.minMaxLoc()函数的使用
理论
模板匹配是一种在大图像中搜索和定位模板图像位置的方法。OpenCV提供了cv.matchTemplate()函数来实现这一功能。该函数通过在输入图像上滑动模板图像(类似于2D卷积),比较模板图像与输入图像中模板大小的区域。OpenCV实现了多种比较方法(更多细节请参考官方文档)。该函数返回一个灰度图像,其中每个像素表示其邻域与模板的匹配程度。
如果输入图像大小为(WxH),模板图像大小为(wxh),则输出图像大小为(W-w+1, H-h+1)。获取结果后,可以使用cv.minMaxLoc()函数找到最大/最小值的位置。将该位置作为矩形的左上角,将(w,h)作为矩形的宽度和高度,该矩形即为模板所在区域。
注意:如果使用cv.TM_SQDIFF作为比较方法,最小值表示最佳匹配。
OpenCV中的模板匹配
以梅西的照片为例,我们将搜索梅西的脸部。为此,我们创建了一个模板图像:
我们将尝试所有比较方法,以便了解它们的结果:
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img = cv.imread('messi5.jpg', cv.IMREAD_GRAYSCALE)
assert img is not None, "file could not be read, check with os.path.exists()"
img2 = img.copy()
template = cv.imread('template.jpg', cv.IMREAD_GRAYSCALE)
assert template is not None, "file could not be read, check with os.path.exists()"
w, h = template.shape[::-1]
# 所有6种比较方法的列表
methods = ['TM_CCOEFF', 'TM_CCOEFF_NORMED', 'TM_CCORR',
'TM_CCORR_NORMED', 'TM_SQDIFF', 'TM_SQDIFF_NORMED']
for meth in methods:
img = img2.copy()
method = getattr(cv, meth)
# 应用模板匹配
res = cv.matchTemplate(img, template, method)
min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res)
# 如果方法是TM_SQDIFF或TM_SQDIFF_NORMED,取最小值
if method in [cv.TM_SQDIFF, cv.TM_SQDIFF_NORMED]:
top_left = min_loc
else:
top_left = max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
cv.rectangle(img, top_left, bottom_right, 255, 2)
plt.subplot(121), plt.imshow(res, cmap='gray')
plt.title('Matching Result'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(img, cmap='gray')
plt.title('Detected Point'), plt.xticks([]), plt.yticks([])
plt.suptitle(meth)
plt.show()
以下是使用不同方法的结果:
cv.TM_CCOEFF
cv.TM_CCOEFF_NORMED
cv.TM_CCORR
cv.TM_CCORR_NORMED
cv.TM_SQDIFF
cv.TM_SQDIFF_NORMED
可以看出,使用cv.TM_CCORR的结果并不理想。
多个对象的模板匹配
在上一节中,我们在图像中搜索了梅西的脸部,这在图像中只出现一次。如果要搜索在图像中多次出现的对象,cv.minMaxLoc()将无法提供所有位置。在这种情况下,我们将使用阈值处理。因此,在这个例子中,我们将使用著名的马里奥游戏截图,并查找其中的硬币。
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img_rgb = cv.imread('mario.png')
assert img_rgb is not None, "file could not be read, check with os.path.exists()"
img_gray = cv.cvtColor(img_rgb, cv.COLOR_BGR2GRAY)
template = cv.imread('mario_coin.png', cv.IMREAD_GRAYSCALE)
assert template is not None, "file could not be read, check with os.path.exists()"
w, h = template.shape[::-1]
res = cv.matchTemplate(img_gray, template, cv.TM_CCOEFF_NORMED)
threshold = 0.8
loc = np.where(res >= threshold)
for pt in zip(*loc[::-1]):
cv.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0, 0, 255), 2)
cv.imwrite('res.png', img_rgb)
结果如下:
热门推荐
春节前高效时间管理指南
2024年9月发射的哨兵2C卫星,已捕捉加州野火和伯利兹蓝洞影像
路由器WiFi信号一会有一会无?六大原因及解决方案全解析
2025年财运爆棚!属龙人必看投资秘籍
十二生肖消费大比拼:谁最会花钱?
《大城主战略版》VS《太古神王2》:谁才是策略王者?
四川蜀道集团举办智能交通论坛,推进高速运营数字化转型
豆浆豆腐到大豆油:一文详解大豆的营养与食用指南
飞行模式不止是关信号,这些隐藏功能你知道吗?
晖致中国启动“心路公益活动”,助力空巢老人心脑血管疾病防治
飞行模式:现代人的数字排毒工具
美国预防心脏病学会推荐:得舒饮食预防心脑血管梗死
湄洲岛、南少林寺、九鲤湖,莆田旅游三大宝藏打卡地
烤羊排:从古希腊贵族餐桌到现代健康饮食新宠
湄洲岛:福建莆田的自然瑰宝
莆田:妈祖文化与闽越文明的千年交融
当心!骗子冒充云闪付客服实施诈骗,这样做能保资金安全
雪莲归芪口服液:调理亚健康的中药良方
冬季养生神器:雪莲归芪口服液
直肠癌高发,直肠指诊真能救命?
昆明医大研究团队发现结直肠癌关键代谢物,无创筛查迎来新突破
富氢水杯真能美容养颜?揭秘真相
王者荣耀典韦出装攻略:疯狗模式全面解析
股市123法则:趋势判断与实战应用指南
宏观经济波动下的股市风云
南通支云迎来新援:张雨浩从皇马B队归来,柳烨晋升一线队
吉利远景车主必看:这些故障坑太大了!
吉利远景车主必学:自诊汽车故障技巧
南通支云牵手英超狼队,共建青训体系培养足球人才
最快选手为何跑第三棒?田径接力棒次安排有讲究