图像预处理-模板匹配

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

  • 不会边缘填充

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

  • 返回结果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()
相关推荐
格林威1 小时前
机器视觉检测的光源基础知识及光源选型
人工智能·深度学习·数码相机·yolo·计算机视觉·视觉检测
鹅毛在路上了2 小时前
C++, ffmpeg, libavcodec-RTSP拉流,opencv实时预览
c++·opencv·ffmpeg
研梦非凡4 小时前
CVPR 2025|基于视觉语言模型的零样本3D视觉定位
人工智能·深度学习·计算机视觉·3d·ai·语言模型·自然语言处理
Monkey的自我迭代4 小时前
多目标轮廓匹配
人工智能·opencv·计算机视觉
索迪迈科技5 小时前
安防芯片 ISP 的白平衡统计数据对图像质量有哪些影响?
人工智能·计算机视觉·白平衡
ViperL16 小时前
[优化算法]神经网络结构搜索(一)
深度学习·神经网络·计算机视觉
张子夜 iiii7 小时前
实战项目-----在图片 hua.png 中,用红色画出花的外部轮廓,用绿色画出其简化轮廓(ε=周长×0.005),并在同一窗口显示
人工智能·pytorch·python·opencv·计算机视觉
nenchoumi311910 小时前
全网首发!Realsense 全新 D555 相机开箱记录与 D435i、L515、D456 横向测评!
数码相机·计算机视觉·机器人·ros·realsense
小关会打代码11 小时前
计算机视觉之多模板匹配
人工智能·计算机视觉
AI 嗯啦11 小时前
计算机视觉----opencv----身份证号码识别案例
人工智能·opencv·计算机视觉