opencv 模板匹配

模板匹配

  • [1. 模板匹配](#1. 模板匹配)
  • [2. 匹配方法(cv2.matchTemplate())](#2. 匹配方法(cv2.matchTemplate()))
    • [2.1 平方差匹配(cv2.TM_SQDIFF)](#2.1 平方差匹配(cv2.TM_SQDIFF))
    • [2.2 归一化平方差匹配(cv2.TM_SQDIFF_NORMED)](#2.2 归一化平方差匹配(cv2.TM_SQDIFF_NORMED))
    • [2.3 相关匹配(cv2.TM_CCORR)](#2.3 相关匹配(cv2.TM_CCORR))
    • [2.4 归一化相关匹配(cv2.TM_CCORR_NORMED)](#2.4 归一化相关匹配(cv2.TM_CCORR_NORMED))
    • [2.5 相关系数匹配(cv2.TM_CCOEFF)](#2.5 相关系数匹配(cv2.TM_CCOEFF))
    • [2.6 归一化相关系数匹配(cv2.TM_CCOEFF_NORMED)](#2.6 归一化相关系数匹配(cv2.TM_CCOEFF_NORMED))

1. 模板匹配

模板匹配就是用模板图(通常是一个小图)在目标图像(通常是一个比模板图大的图片)中不断的滑动比较,通过某种比较方法来判断是否匹配成功。

2. 匹配方法(cv2.matchTemplate())

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,表示匹配程度越好。最小值对应的最佳匹配位置。

    2. cv2.TM_CCORRcv2.TM_CCORR_NORMED

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

    3. cv2.TM_CCOEFFcv2.TM_CCOEFF_NORMED

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

2.1 平方差匹配(cv2.TM_SQDIFF)

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

注意:模板匹配过程皆不需要边缘填充,直接从目标图像的左上角开始计算。

绘制轮廓:

找的目标图像中匹配程度最高的点,我们可以设定一个匹配阈值来筛选出多个匹配程度高的区域。

loc=np.where(array > 0.8) #loc包含array中所有大于0.8的元素索引的数组

*zip(loc)

代码如下:

python 复制代码
'''平方差匹配'''
    img=cv2.imread("../15day4.10/src/game.png")
    temp=cv2.imread("../15day4.10/src/temp.png")
    h,w,c=temp.shape
    #获取匹配后的相似值cv2.matchTemplate(),
    # 平方差匹配cv2.TM_SQDIFF 值越小越相似
    res=cv2.matchTemplate(img,temp,cv2.TM_SQDIFF)
    #设置阈值筛选出非常相似的子图
    threshold=2000000
    # 找到满足要求的坐标
    loc=np.where(res<threshold)
    #用一个矩形框圈出符合要求的图像
    for el in zip(*loc):
        cv2.rectangle(img,el[::-1],(el[1]+w,el[0]+h),(255,0,255),2)
    cv2.imshow("img",img)
    cv2.imshow("temp",temp)
    cv2.waitKey(0)

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

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

代码如下:

python 复制代码
    '''归一化平方差匹配'''
    img=cv2.imread("../15day4.10/src/game.png")
    temp=cv2.imread("../15day4.10/src/temp.png")
    h,w,c=temp.shape
    #获取匹配后的相似值cv2.matchTemplate(),
    # 归一化平方差匹配cv2.TM_SQDIFF------MORMED 值越小越相似
    res=cv2.matchTemplate(img,temp,cv2.TM_SQDIFF_NORMED)
    #设置阈值筛选出非常相似的子图
    threshold=0.3
    # 找到满足要求的坐标
    loc=np.where(res<threshold)
    #用一个矩形框圈出符合要求的图像
    for el in zip(*loc):
        cv2.rectangle(img,el[::-1],(el[1]+w,el[0]+h),(255,0,255),2)
    cv2.imshow("img",img)
    cv2.imshow("temp",temp)
    cv2.waitKey(0)

2.3 相关匹配(cv2.TM_CCORR)

使用对应像素的乘积进行匹配 ,乘积的结果越大其匹配程度越高 ,计算过程举例如下。

代码如下:

python 复制代码
'''相关匹配'''
    img=cv2.imread("../15day4.10/src/game.png")
    temp=cv2.imread("../15day4.10/src/temp.png")
    h,w,c=temp.shape
    #获取匹配后的相似值cv2.matchTemplate(),
    # 相关匹配cv2.TM_CCORR 值越大越相似
    res=cv2.matchTemplate(img,temp,cv2.TM_CCORR)
    #设置阈值筛选出非常相似的子图
    threshold=7300000
    # 找到满足要求的坐标
    loc=np.where(res>threshold)
    #用一个矩形框圈出符合要求的图像
    for el in zip(*loc):
        cv2.rectangle(img,el[::-1],(el[1]+w,el[0]+h),(255,0,255),1)
    cv2.imshow("img",img)
    cv2.imshow("temp",temp)
    cv2.waitKey(0)

注意:

  • 越大越好的话,如果原图有一片区域为白色那么久会被匹配上

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

与相关匹配类似,只不过是将其值统一到0到1之间,值越大,代表匹配程度越高,计算过程举例如下

代码如下:

python 复制代码
'''归一化相关匹配'''
    img=cv2.imread("../15day4.10/src/game.png")
    temp=cv2.imread("../15day4.10/src/temp.png")
    h,w,c=temp.shape
    #获取匹配后的相似值cv2.matchTemplate(),
    # 相关匹配cv2.TM_CCORR_NORMDE 值越大越相似
    res=cv2.matchTemplate(img,temp,cv2.TM_CCORR_NORMED)
    #设置阈值筛选出非常相似的子图
    threshold=0.9
    # 找到满足要求的坐标
    loc=np.where(res>threshold)
    #用一个矩形框圈出符合要求的图像
    for el in zip(*loc):
        cv2.rectangle(img,el[::-1],(el[1]+w,el[0]+h),(255,0,255),1)
    cv2.imshow("img",img)
    cv2.imshow("temp",temp)
    cv2.waitKey(0)

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

需要先计算模板与目标图像的均值,然后通过每个像素与均值之间的差的乘积再求和来表示其匹配程度,越大越匹配,计算过程举例如下。

代码如下:

python 复制代码
'''相关系数匹配'''
    img=cv2.imread("../15day4.10/src/game.png")
    temp=cv2.imread("../15day4.10/src/temp.png")
    h,w,c=temp.shape
    #获取匹配后的相似值cv2.matchTemplate(),
    # 相关系数匹配cv2.TM_CCOEFF 值越大越相似
    res=cv2.matchTemplate(img,temp,cv2.TM_CCOEFF)
    #设置阈值筛选出非常相似的子图
    threshold=3000000
    # 找到满足要求的坐标
    loc=np.where(res>threshold)
    #用一个矩形框圈出符合要求的图像
    for el in zip(*loc):
        cv2.rectangle(img,el[::-1],(el[1]+w,el[0]+h),(255,0,255),1)
    cv2.imshow("img",img)
    cv2.imshow("temp",temp)
    cv2.waitKey(0)

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

也是将相关系数匹配的结果统一到0到1之间,值越接近1代表匹配程度越高,计算过程举例如下。

代码如下:

python 复制代码
'''归一化相关系数匹配'''
    img=cv2.imread("../15day4.10/src/game.png")
    temp=cv2.imread("../15day4.10/src/temp.png")
    h,w,c=temp.shape
    #获取匹配后的相似值cv2.matchTemplate(),
    # 相关系数匹配cv2.TM_CCOEFF_NORMED 值越大越相似
    res=cv2.matchTemplate(img,temp,cv2.TM_CCOEFF_NORMED)
    #设置阈值筛选出非常相似的子图
    threshold=0.8
    # 找到满足要求的坐标
    loc=np.where(res>threshold)
    #用一个矩形框圈出符合要求的图像
    for el in zip(*loc):
        cv2.rectangle(img,el[::-1],(el[1]+w,el[0]+h),(255,0,255),1)
    cv2.imshow("img",img)
    cv2.imshow("temp",temp)
    cv2.waitKey(0)
相关推荐
FL16238631291 分钟前
[C#][winform]基于yolov11的齿轮缺陷检测系统C#源码+onnx模型+评估指标曲线+精美GUI界面
人工智能·yolo
却道天凉_好个秋2 分钟前
OpenCV(四十三):分水岭法
人工智能·opencv·计算机视觉·图像分割·分水岭法
CoovallyAIHub2 分钟前
从空地对抗到空战:首个无人机间追踪百万级基准与时空语义基线MambaSTS深度解析
深度学习·算法·计算机视觉
爱笑的眼睛118 分钟前
TensorFlow Hub:解锁预训练模型的无限可能,超越基础分类任务
java·人工智能·python·ai
GodGump9 分钟前
AI 竞争正在进入什么阶段?
人工智能
万俟淋曦13 分钟前
【论文速递】2025年第41周(Oct-05-11)(Robotics/Embodied AI/LLM)
人工智能·深度学习·机器人·大模型·论文·robotics·具身智能
落羽的落羽15 分钟前
【C++】深入浅出“图”——图的基本概念与存储结构
服务器·开发语言·数据结构·c++·人工智能·机器学习·图搜索算法
DatGuy18 分钟前
Week 30: 机器学习补遗:时序信号处理与数学特征工程
人工智能·机器学习·信号处理
摸鱼仙人~21 分钟前
大语言模型微调中的数据分布不均与长尾任务优化策略
人工智能·深度学习·机器学习
LeeZhao@26 分钟前
【狂飙全模态】狂飙AGI-Wan2.1文生视频实战部署-Gradio篇
人工智能·语言模型·音视频·agi