(纯新手教学)计算机视觉(opencv)实战十四——模板与多个对象匹配
图片旋转、图片镜像相关教学:
(纯新手教学)计算机视觉(opencv)实战十三——图片旋转、图片镜像 的几种常用方法-CSDN博客https://blog.csdn.net/2302_78022640/article/details/151356600?spm=1011.2415.3001.5331
模板与多个对象匹配
在计算机视觉中,模板匹配(Template Matching)是一种常见的图像处理方法,能够在大图像中寻找与小模板相似的区域。很多时候,模板在目标图像中可能不止出现一次,并且还可能存在旋转的情况。因此,模板与多个对象的匹配技术就显得非常重要。
下面的代码演示了如何使用 OpenCV 进行模板匹配,并支持在目标图像中同时查找多个方向的模板对象。
核心函数:cv2.matchTemplate
OpenCV 提供了 cv2.matchTemplate
函数来实现模板匹配。
cv2.matchTemplate(image, templ, method, result=None, mask=None)
参数说明:
-
image:待搜索的图像(通常比模板大)。
-
templ:模板图像,需要在大图中被搜索的目标。
-
method:匹配方法,用来衡量相似度。
-
result:存放匹配结果的矩阵,一般不用手动传入,函数会自动生成。
-
mask:掩膜,可选参数,某些方法不支持。
常见匹配方法
模板匹配的效果依赖于所选择的计算方式。OpenCV 提供了六种主要方法:
-
TM_SQDIFF(平方差匹配法)
-
使用平方差衡量误差。
-
匹配越好,结果值越小。
-
-
TM_CCORR(相关匹配法)
-
采用乘法运算,计算图像与模板的相关性。
-
数值越大表示匹配程度越高。
-
-
TM_CCOEFF(相关系数匹配法)
-
通过相关系数计算相似度,排除了亮度影响。
-
数值越大说明匹配效果越好。
-
-
TM_SQDIFF_NORMED(归一化平方差匹配法)
-
与 TM_SQDIFF 类似,但结果被归一化。
-
匹配越好,值越小。
-
-
TM_CCORR_NORMED(归一化相关匹配法)
-
在 TM_CCORR 的基础上进行归一化,结果范围更稳定。
-
数值越大,匹配越好。
-
-
TM_CCOEFF_NORMED(归一化相关系数匹配法)
-
在 TM_CCOEFF 的基础上进行归一化,最常用的一种方法。
-
结果范围通常在 -1 到 1 之间,越接近 1 匹配越好。
-
图片准备:
arrow.jpg
arrows.jpg
运行结果图:
代码解析
import cv2
import numpy as npimg_rgb = cv2.imread('arrows.jpg')
cv2.imshow('img_gray', img_rgb)
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)template1=cv2.imread('./arrow.jpg', flags=0)
# 旋转 90 度,k=-1 表示顺时针旋转 90 度
template2 = np.rot90(template1, k=-1)
# 旋转 90 度,k=1 表示逆时针旋转 90 度
template3 = np.rot90(template1, k=1)
template4 = np.rot90(template1, k=2)
cv2.imshow('template1', template1)
cv2.imshow('template2', template2)
cv2.imshow('template3', template3)
cv2.imshow('template4', template4)
cv2.waitKey(0)templates=[template1,template2,template3,template4]for template in templates:h, w = template.shape[:2]# 使用模板匹配方法 cv2.matchTemplate 进行模板匹配res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)threshold = 0.9 # 设定匹配阈值# 获取匹配结果中所有符合阈值的点的坐标loc = np.where(res >= threshold) # 符合条件的行,符合条件的列# print(loc)# 遍历所有匹配点for pt in zip(*loc[::-1]):# 在原图上绘制匹配区域的矩形框cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), color=(0, 0, 255), thickness=1)cv2.imshow('result', img_rgb)
cv2.waitKey(0)
核心步骤讲解
-
读取图像并灰度化
-
使用
cv2.imread
读取原始图像arrows.jpg
,并转换为灰度图。 -
灰度图可以减少计算量,同时保留了模板匹配所需的主要信息。
-
-
加载模板并进行旋转
-
模板
arrow.jpg
作为基本形状。 -
使用
np.rot90
对模板进行旋转,生成 4 个方向的模板(0°、90°、180°、270°)。 -
这样就能应对目标图像中箭头方向不一致的情况。
-
-
模板匹配
-
cv2.matchTemplate
用于计算模板与目标图像各个位置的匹配程度。 -
选择
cv2.TM_CCOEFF_NORMED
方法,该方法会输出归一化相关系数,值越接近 1 表示越相似。
-
-
匹配阈值设定
-
设置
threshold = 0.9
,即相似度大于等于 0.9 的区域才认为是有效匹配。 -
阈值过低可能引入误检,过高可能漏检。
-
-
定位与绘制
-
np.where(res >= threshold)
找到所有符合条件的点。 -
使用
cv2.rectangle
在原图img_rgb
上绘制矩形框,标记出匹配区域。
-
-
结果展示
-
使用
cv2.imshow
显示最终带有标记的图像。
-
应用场景
-
目标检测
在工厂生产线上检测零件是否存在、方向是否正确。 -
游戏自动化
在屏幕截图中查找某个按钮或图标的位置,实现自动点击。 -
文档处理
在扫描件中查找特定的标志或符号。 -
视频监控
在实时视频中检测特定物体的出现与方向。
方法优缺点
-
优点
-
实现简单,代码量少。
-
适合已知模板的精确匹配任务。
-
可以通过旋转模板来解决方向差异。
-
-
缺点
-
对尺度变化不敏感(如果模板大小与目标图像中对象大小不同,效果不好)。
-
对光照、噪声等变化敏感。
-
计算效率在大规模匹配时较低。
-
总结
通过这段代码,可以看到如何使用 OpenCV 的模板匹配方法,结合旋转操作,在图像中查找多个方向的相同目标对象。该方法在简单场景下效果显著,尤其适合对象外形固定、尺寸不变的任务。