hellou

opencv学习笔记(九)

模板匹配:
在模板匹配中,我们引入函数cv2.matchTemplate()函数来执行模板匹配的操作

res = cv2.matchTemplate(image, template, method, result=None, mask=None)

  • image: 输入的源图像,可以是灰度图像或彩色图像。
  • template: 要匹配的模板图像,必须与源图像具有相同的数据类型和通道数。
  • method: 模板匹配方法,用于指定匹配的算法。常见的方法有:
    • cv2.TM_SQDIFF: 平方差匹配法,计算平方不同,计算出来的值越小就越相关;
    • cv2.TM_SQDIFF_NORMED: 归一化平方差匹配法,计算归一化平方不同,计算出来的值越靠近0,越相关;
    • cv2.TM_CCORR: 相关性匹配法,计算相关性,计算出来的值越大,越相关;
    • cv2.TM_CCORR_NORMED: 归一化相关性匹配法,计算归一化相关性,计算出来的值越接近1,越相关;
    • cv2.TM_CCOEFF: 相关系数匹配法,计算出来的值越大,越相关;
    • cv2.TM_CCOEFF_NORMED: 归一化相关系数匹配法,计算归一化相关系数,计算出来的值越接近1,越相关。
  • result (可选): 输出的匹配结果图像,与源图像大小相同,数据类型为浮点型。
  • mask (可选): 掩码图像,指定要匹配的图像区域。

函数返回一个包含匹配结果的浮点型数组(或图像)。可以通过 cv2.minMaxLoc() 函数找到结果数组中的最大值和最小值,以及对应的位置。

#模板匹配
#假设原图的大小是A*B,而模板大小是a*b,那么输出结果的矩阵是(A-a+1)*(B-b+1)
import cv2
import  numpy as np
from matplotlib import  pyplot as plt

img = cv2.imread('C:/Users/hellou/Desktop/self-image.jpg', 0)
template = cv2.imread('C:/Users/hellou/Desktop/face-imge.jpg', 0)
h, w = template.shape[:2]#取图片的长和宽
print(img.shape)
print(template.shape)

"""TM_SQDIFF:计算平方不同,计算出来的值越小,越相关
TM_CCORR:计算相关性,计算出来的值越大,越相关
TM_CCOEFF:计算相关系数,计算出来的值越大,越相关
TM_SQDIFF_NORMED:计算归一化平方不同,计算出来的值越接近0,越相关
TM_CCORR_NORMED:计算归一化相关性,计算出来的值越接近1,越相关
TM_CCOEFF_NORMED:计算归一化相关系数,计算出来的值越接近1,越相关
建议使用带有归一化的方法"""

methods = ['cv2.TM_SQDIFF','cv2.TM_CCORR','cv2.TM_CCOEFF','cv2.TM_SQDIFF_NORMED','cv2.TM_CCORR_NORMED','cv2.TM_CCOEFF_NORMED']
res = cv2.matchTemplate(img, template, 1)

min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

for meth in methods:
    img2 = img.copy()

    #匹配方法的真值
    method = eval(meth)#将字符串转变为符号的赋值
    print(method)
    res = cv2.matchTemplate(img, template, method)
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)

    #如果是平方差匹配TM_SQDIFF或归一化平方差匹配TM_SQIDFF_NORMED,取最小值
    if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:
        top_left = min_loc
    else:
        top_left = max_loc
    bottom_right = (top_left[0] + w, top_left[1] + h)

    #画矩形
    cv2.rectangle(img2, top_left, bottom_right, 255, 2)
    #OpenCV 中的 rectangle 函数可以在一幅图像上绘制矩形。该函数的格式如下:
#cv2.rectangle(image, start_point, end_point, color, thickness)

#参数解释:

    #image:要在其上绘制矩形的图像
    #start_point:矩形的左上角坐标
    #end_point:矩形的右下角坐标
    #color:矩形的颜色,可以是 BGR 或者 RGB 的三通道元组
    #thickness:线条的粗细,如果设置为 -1,表示矩形是填充的"""

    plt.subplot(121), plt.imshow(res, cmap='gray')
    plt.xticks([]),plt.yticks([]) #隐藏坐标轴
    plt.subplot(122), plt.imshow(img2, cmap='gray')
    plt.xticks([]),plt.yticks([])
    plt.suptitle(meth)
    plt.show()

匹配多个对象:

import cv2

# 读取源图像和模板图像
image = cv2.imread('image.png')
template1 = cv2.imread('template1.png')
template2 = cv2.imread('template2.png')

# 定义匹配方法
method = cv2.TM_CCOEFF_NORMED

# 执行模板匹配
result1 = cv2.matchTemplate(image, template1, method)
result2 = cv2.matchTemplate(image, template2, method)

# 设置阈值
threshold = 0.8

# 寻找满足阈值条件的匹配结果
locations1 = np.where(result1 >= threshold)
locations2 = np.where(result2 >= threshold)

# 绘制矩形框标记匹配位置
w1, h1 = template1.shape[::-1]
w2, h2 = template2.shape[::-1]

for pt in zip(*locations1[::-1]):
    cv2.rectangle(image, pt, (pt[0] + w1, pt[1] + h1), (0, 255, 0), 2)

for pt in zip(*locations2[::-1]):
    cv2.rectangle(image, pt, (pt[0] + w2, pt[1] + h2), (0, 0, 255), 2)

# 显示匹配结果
cv2.imshow('Matched Image', image)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

posted on 2023-06-24 10:24  云上u  阅读(17)  评论(0编辑  收藏  举报

导航