【opencv学习】【模板匹配】

今天学习模板匹配
模板图片
请添加图片描述
目标图像
请添加图片描述

import cv2
import matplotlib.pyplot as plt


# 模板匹配的原理:
# 一个模板图像在目标图像上机芯从左到右从上到下进行滑动,每滑动一个位置就计算匹配度(均方差或者是相关系数等)
# 遍历完目标图像后,求出最匹配的未知区域来。

# 展示图像,封装成函数
def cv_show_image(name, img):
    cv2.imshow(name, img)
    cv2.waitKey(0)  # 等待时间,单位是毫秒,0代表任意键终止
    cv2.destroyAllWindows()


# 读取模板
template = cv2.imread('images/template.jpg')  # 转成灰度图
print('template图像维度是:', template.shape)
h, w, c = template.shape
print(h)
print(w)
cv_show_image('template', template)

# 读取目标图像
dst_img = cv2.imread('images/saoge2.jpg')  # 转成灰度图
print('目标图像维度是:', dst_img.shape)
cv_show_image('dst_img', dst_img)

# 匹配度的度量方法
methords = ['cv2.TM_SQDIFF',  # 计算每个像素点的均方差,值越小越相关
            'cv2.TM_CCORR',  # 计算相关性,值越大越相关
            'cv2.TM_CCOEFF',  # 计算相关性系数,值越大越相关
            'cv2.TM_SQDIFF_NORMED',  # 计算每个像素点的均方差,值越小越相关,带有归一化
            'cv2.TM_CCORR_NORMED',  # 计算相关性,值越大越相关,带有归一化
            'cv2.TM_CCOEFF_NORMED'  # 计算相关性系数,值越大越相关,带有归一化
            ]

colors = [(255, 0, 0), (0, 255, 0), (0, 0, 255), (255, 255, 0), (0, 255, 255), (255, 0, 255)]
thickness = [12, 10, 8, 6, 4, 2]

img_result = dst_img.copy()
for i in range(len(methords)):
    img_tmp = dst_img.copy()  # 临时展示当前的框框
    methord = eval(methords[i])  # 拿到具体的模板匹配方法
    print('current methord is: {}'.format(methords[i]))

    # 实际进行模板匹配
    res = cv2.matchTemplate(dst_img, template, methord)  # 传入目标图像、模板图像、匹配度量方法
    print(res.shape)  # 得到的是 (dst_img.H - template.H + 1, dst_img.W - template.W + 1)的维度数据
    print(type(res))  # <class 'numpy.ndarray'>
    print(res.dtype)  # 每个元素的类型是 float32

    # 解析结果,分别获得匹配过程中度量值的最大最小值,以及其分布像素点的位置,根据methord不同,去取适当的值
    min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
    if methord 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)
    print('模板匹配到的位置信息是', top_left, bottom_right)

    # 在图像上画出矩形表示这个匹配的位置
    cv2.rectangle(img_result, top_left, bottom_right, colors[i], thickness[i])
    cv2.rectangle(img_tmp, top_left, bottom_right, colors[i], thickness[i])

    plt.subplot(1, 2, 1), plt.imshow(res, 'gray')  # 画出各个像素点(代表一个(h, w)的区域)的匹配度
    plt.xticks([]), plt.yticks([])  # 隐藏坐标轴
    plt.subplot(1, 2, 2), plt.imshow(img_tmp, 'gray')  # 在原始图像上画出匹配的位置
    plt.xticks([]), plt.yticks([])  # 隐藏坐标轴
    plt.title(methords[i])
    plt.show()

# 最后把所有的框框都核在一起
cv_show_image('img_result', img_result)

效果如下:
‘cv2.TM_SQDIFF’, # 计算每个像素点的均方差,值越小越相关
请添加图片描述

‘cv2.TM_CCORR’, # 计算相关性,值越大越相关
请添加图片描述

‘cv2.TM_CCOEFF’, # 计算相关性系数,值越大越相关
请添加图片描述

‘cv2.TM_SQDIFF_NORMED’, # 计算每个像素点的均方差,值越小越相关,带有归一化
请添加图片描述

‘cv2.TM_CCORR_NORMED’, # 计算相关性,值越大越相关,带有归一化
请添加图片描述

‘cv2.TM_CCOEFF_NORMED’ # 计算相关性系数,值越大越相关,带有归一化
请添加图片描述

最后汇总的结果就是
请添加图片描述

猜你喜欢

转载自blog.csdn.net/qq_29367075/article/details/122916535