ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

18_模板匹配

2022-08-03 12:02:35  阅读:170  来源: 互联网

标签:loc 匹配 img 18 cv2 TM res print 模板


# 模板匹配

# 1. 模板匹配简介

# 2. 模板匹配单个对象

import cv2  # opencv的缩写为cv2
import matplotlib.pyplot as plt  # matplotlib库用于绘图展示
import numpy as np  # numpy数值计算工具包


template = cv2.imread('D:/pycharm/pycharm-cope/opencv/resource/photo/12_Face.jpg', 0)  # 0 表示以灰度图方式读取
img = cv2.imread('D:/pycharm/pycharm-cope/opencv/resource/photo/13_Lena.jpg', 0)
h, w = template.shape[:2]  # 获得模板的宽和高
print(img.shape)
print(template.shape)

methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR',
           'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']
res = cv2.matchTemplate(img, template, cv2.TM_SQDIFF)
print(res.shape)  # 返回的矩阵大小 (A-a+1)x(B-b+1)
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)  # 返回模板匹配后最小值、最大值的位置
print(min_val)  # cv2.TM_SQDIFF方法中,越小的值表示像素点的差异越小
print(max_val)
print(min_loc)  # 当获得最小值对应的模板左上角的位置,加上模板自身的长、宽,可以在原图像中画出最匹配的区域
print(max_loc)

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_SQDIFF_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)

    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()

# 3. 模板匹配多个对象

img_rgb = cv2.imread('D:/pycharm/pycharm-cope/opencv/resource/photo/14_Mario.jpg')
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY)
print('img_gray.shape:', img_gray.shape)
template = cv2.imread('D:/pycharm/pycharm-cope/opencv/resource/photo/15_Mario_coin.jpg', 0)
print('template.shape:', template.shape)
h, w = template.shape[:2]

# res 是 result 的简称
res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)  # res 是返回每一个小块窗口得到的结果值
print('res.shape:', res.shape)
threshold = 0.8

# 取匹配程度大于 80% 的坐标
loc = np.where(res >= threshold)  # np.where 使得返回 res 矩阵中值大于 0.8 的索引,即坐标
print('type(loc):', type(loc))  # loc 为元组类型
print('len(loc):', len(loc))  # loc 元组有两个值
print('len(loc[0]):', len(loc[0]), 'len(loc[1]):', len(loc[1]))  # loc 元组每个值 120 个元素
print('type(loc[0]):', type(loc[0]), 'type(loc[1]):', type(loc[1]))  # loc 元组每个值的类型为 numpy.array
print("loc[::-1]:", loc[::-1])  # loc[::-1] 表示顺序取反,即第二个 numpy.array 放在第一个 numpy.array 前面

i = 0
# zip函数为打包为元组的列表,例 a = [1,2,3] b = [4,5,6] zip(a,b) 为 [(1, 4), (2, 5), (3, 6)]
for pt in zip(*loc[::-1]):  # 当用 *b 作为传入参数时, b 可以为列表、元组、集合,zip使得元组中两个 numpy.array 进行配对
    bottom_right = (pt[0] + w, pt[1] + h)
    cv2.rectangle(img_rgb, pt, bottom_right, (0, 0, 255), 2)
    i = i + 1
print('i:', i)

cv2.imshow('img_rgb', img_rgb)
cv2.waitKey(0)

 

标签:loc,匹配,img,18,cv2,TM,res,print,模板
来源: https://www.cnblogs.com/tuyin/p/16546352.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有