图像预处理-模板匹配

就是用模板图目标图像 中不断的滑动比较,通过某种比较方法来判断是否匹配成功,找到模板图所在的位置。

  • 不会边缘填充

  • 类似于卷积,滑动比较,挨个比较象素。

  • 返回结果res 大小是:目标图大小-模板图大小+1**(H-h+1,W-w+1)**。

一.匹配方法

res=cv2.matchTemplate(image, templ, method)

  • image:原图像,这是一个灰度图像或彩色图像(在这种情况下,匹配将在每个通道上独立进行)。

  • templ:模板图像,也是灰度图像或与原图像相同通道数的彩色图像。

  • method:匹配方法,可以是以下之一:

  • cv2.TM_CCOEFF

  • cv2.TM_CCOEFF_NORMED

  • cv2.TM_CCORR

  • cv2.TM_CCORR_NORMED

  • cv2.TM_SQDIFF

  • cv2.TM_SQDIFF_NORMED

  • 返回值res ,每个元素 表示原图像中相应位置与模板图像匹配的相似度 ,而每个元素的位置 其实就是对应匹配位置左上角元素位置。匹配方法不同,返回矩阵的值的含义也会有所区别。以下是几种常用的匹配方法及其返回值含义:

  1. cv2.TM_SQDIFFcv2.TM_SQDIFF_NORMED

返回值越接近0 ,表示匹配程度越好。最小值对应的最佳匹配位置。

  1. cv2.TM_CCORRcv2.TM_CCORR_NORMED

返回值越大 ,表示匹配程度越好。最大值对应的最佳匹配位置。

  1. cv2.TM_CCOEFFcv2.TM_CCOEFF_NORMED

返回值越大 ,表示匹配程度越好。最大值对应的最佳匹配位置。

1.1 平方差匹配(cv2.TM_SQDIFF)

以模板图与目标图所对应的像素值使用平方差公式 来计算,其结果越小 ,代表匹配程度越高。如图:

1.2 归一化平方差匹配(cv2.TM_SQDIFF_NORMED)

与平方差匹配类似,只不过需要将值统一到0到1 ,计算结果越小 ,代表匹配程度越高。如图:

1.3 相关匹配(cv2.TM_CCORR)

使用对应像素的乘积 进行匹配,乘积的结果越大 其匹配程度越高。如图:

1.4 归一化相关匹配(cv2.TM_CCORR_NORMED)

与相关匹配类似,只不过是将其值统一到0到1 之间,值越大 ,代表匹配程度越高。如图:

1.5 相关系数匹配(cv2.TM_CCOEFF)

先计算模板目标图像均值 ,然后通过每个像素与均值之间的差的乘积求和 来表示其匹配程度,1表示完美 的匹配,-1表示最差的匹配。如图:

1.6 归一化相关系数匹配(cv2.TM_CCOEFF_NORMED)

将相关系数匹配的结果统一到0到1 之间,值越接近1 代表匹配程度越高。如图:

二.绘制轮廓

设定一个匹配阈值 来筛选出多个匹配程度高的区域,找出数组中所有大于0.8的元素索引:

loc=np.where(array > 0.8)

获取轮廓点

zip(*loc)

  • *loc 是解包操作,将 loc 中的多个数组拆开,作为单独的参数传递给 zip

  • zip 将这些数组 按元素一一配对,生成一个迭代器 ,每个元素是一个元组 ,表示一个坐标点

python 复制代码
import cv2 as cv
import numpy as np

# 导入目标图
img = cv.imread('../images/game.png')
# 导入模板图
temp = cv.imread('../images/temp.png')

# 使用归一化相关系数匹配拿到所有匹配结果的数组
res = cv.matchTemplate(img, temp, cv.TM_CCORR_NORMED)
# 用布尔索引查找满足实际要求的匹配结果
loc = np.where(res >= 0.8)
print(loc)

# 循环获取匹配结果并绘制矩形框
for pt in zip(*loc):
    # 因为where函数是对数组操作,先返回行索引再返回列索引,返回的坐标是(y,x)形式,所以需要反转
    pt = pt[::-1]
    # 绘制矩形框,已经知道loc中坐标是匹配区域左上角的坐标,右下角的坐标用模板图的尺寸加上左上角坐标即可
    cv.rectangle(img, pt, (pt[0]  + temp.shape[1], pt[1] + temp.shape[0]), (0, 0, 255), 2)

cv.imshow('result', img)
cv.imshow('temp', temp)
cv.waitKey(0)
cv.destroyAllWindows()

(array([ 61, 61, 61, 61, 61, 61, 61, 61, 61, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 67, 68, 68, 68, 68, 99, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 100, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 101, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 102, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 103, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 104, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 105, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 106, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 139, 139, 139, 139, 139, 139, 139, 139, 139,

...

139, 140, 154, 155, 156, 157, 171, 172, 173, 174, 70, 71, 72, 87, 88, 89, 104, 105, 106, 121, 122, 123, 138, 139, 140, 155, 156, 171, 172, 173, 71, 88, 105, 122, 138, 139, 155, 156, 172, 173, 32, 30, 31, 32, 30, 31, 32, 30, 31]))

这里有一个注意点,那就是将原图灰度化后,是不能使用(b,g,r)三通道颜色赋值的,而黑色很难看出来,所以使用白色(255,255,255)绘制矩形。

python 复制代码
import cv2 as cv
import numpy as np

# 导入目标图并灰度化
img = cv.imread('../images/game.png', cv.IMREAD_GRAYSCALE)
# 导入模板图并灰度化
temp = cv.imread('../images/temp.png', cv.IMREAD_GRAYSCALE)

# 使用归一化相关系数匹配拿到所有匹配结果的数组
res = cv.matchTemplate(img, temp, cv.TM_CCORR_NORMED)
# 用布尔索引查找满足实际要求的匹配结果
loc = np.where(res >= 0.8)

# 循环获取匹配结果并绘制矩形框
for pt in zip(*loc):
    # 因为where函数是对数组操作,先返回行索引再返回列索引,返回的坐标是(y,x)形式,所以需要反转
    pt = pt[::-1]
    # 绘制矩形框,这里使用了原来的红色框,实际显示为黑色
    cv.rectangle(img, pt, (pt[0] + temp.shape[1], pt[1] + temp.shape[0]), (0, 0, 255), 2)

cv.imshow('result', img)
cv.imshow('temp', temp)
cv.waitKey(0)
cv.destroyAllWindows()
相关推荐
滨HI01 小时前
opencv 计算面积、周长
人工智能·opencv·计算机视觉
格林威2 小时前
AOI在风电行业制造领域中的应用
人工智能·数码相机·计算机视觉·视觉检测·制造·机器视觉·aoi
禁默4 小时前
第四届图像处理、计算机视觉与机器学习国际学术会议(ICICML 2025)
图像处理·机器学习·计算机视觉
唯道行4 小时前
计算机图形学·9 几何学
人工智能·线性代数·计算机视觉·矩阵·几何学·计算机图形学
Antonio9154 小时前
【图像处理】tiff格式介绍
图像处理·人工智能
Antonio9154 小时前
【图像处理】png 格式详解
图像处理
AndrewHZ4 小时前
【图像处理基石】什么是alpha matting?
图像处理·人工智能·计算机视觉·matting·发丝分割·trimap·人像模式
这张生成的图像能检测吗6 小时前
(综述)基于深度学习的制造业表面缺陷检测图像合成方法综述
人工智能·计算机视觉·图像生成·工业检测·计算机图像学
AI纪元故事会14 小时前
【计算机视觉目标检测算法对比:R-CNN、YOLO与SSD全面解析】
人工智能·算法·目标检测·计算机视觉
音视频牛哥15 小时前
SmartMediaKit:如何让智能系统早人一步“跟上现实”的时间架构--从实时流媒体到系统智能的演进
人工智能·计算机视觉·音视频·音视频开发·具身智能·十五五规划具身智能·smartmediakit