18_模板匹配
作者:互联网
# 模板匹配 # 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