PythonOpenCV-模板匹配-模板匹配
0. 简介
模板匹配是让模板图像在输入图像中滑动,逐像素遍历整个图像进行比较,查找出与模板图像最匹配的部分。
1. 单目标匹配
单目标匹配是指输入图像中只存在一个可能匹配结果。
OpenCV 中的 cv2.matchTemplate()函数用于执行匹配操作,其基本格式如下:
result = cv2.matchTemplate(image, templ, method)
参数说明:
image:输入图像,必须是 8 位或32 位浮点类型
templ:模板图像,不能大于 image,且数据类型要和 image 相同
method:匹配方法,匹配方法不同,返回结果会有所不同。可用的匹配方法如下
- cv2.TM_SQDIFF:以方差结果为依据进行匹配。完全匹配时结果为 0,否则为一个很大的值
- CV2.TM SQDIFF_NORMED:标准(归一化)方差匹配
- cv2TM_CCORR:相关匹配,将输入图像与模板图像相乘,乘积越大匹配度越高,乘积为 0 时匹配度最低
- cv2.TM_CCORR_NORMED:标准(归一化)相关匹配
- cv2.TM CCOEFF:相关系数匹配,将输入图像与其均值的相关值和模板图像与其均值的相关值进行匹配;结果为 1 表示完美匹配,-1 表示糟糕匹配 表示没有任何相关性。
- cv2.TM_CCOEFF_NORMED:标准(归一化)相关系数匹配
result:返回结果,它是一个 numpy.ndarray 对象。若输入图像的大小为 W * H,模板图像大小为 w * h,则result 的大小为(W - w + 1) x (H - h + 1),其中的每个值都表示对应位置的匹配结果。当匹配方法为CV2.TM_SQDIFF 或 CV2.TM_SQDIFF_NORMED 时,匹配结果值越小说明匹配度越高,反之则说明匹配度越低。当匹配方法为 CV2.TM_CCORR、CV2.TM_CCORR_NORMED、CV2.TM_CCOEFF 或 CV2TM_CCOEFF_NORMED时,匹配结果值越小说明匹配度越低,反之则说明匹配度越高。
OpenCV中的 cv2.minMaxLoc()函数用于处理匹配结果,其基本格式如下:
minVal, maxVal, minLoc, maxLoc = cV2,minMaxLoc(src)
参数说明:
src:函数的返回结果
minVal: src 中的最小值,不存在时可以为 NULL
maxVal:sre 中的最大值,不存在时可以为 NULL
minLoc:src 中最小值的位置,不存在时可以为 NULL
maxLoc:src 中最大值的位置,不存在时可以为 NULL
代码示例:
import cv2 as cv import numpy as np import matplotlib.pyplot as plt img_src = cv.imread('../Image/bee.jpg') cv.imshow('src', img_src) img_temp = cv.imread('../Image/template.png') cv.imshow('templte', img_temp) gray_src = cv.cvtColor(img_src, cv.COLOR_BGR2GRAY, dstCn=1) # 转为单通道灰度图 gray_temp = cv.cvtColor(img_temp, cv.COLOR_BGR2GRAY, dstCn=1) # 转为单通道灰度图 h, w = gray_temp.shape # 模板宽度和高度 res = cv.matchTemplate(gray_src, gray_temp, cv.TM_SQDIFF) # 执行匹配 min_val, max_val, min_loc, max_loc = cv.minMaxLoc(res) # 返回最值和位置 top_left = min_loc # 最小值为最佳匹配(获取位置) bottom_right = (top_left[0] + w, top_left[1] + h) # 获取右下角位置 cv.rectangle(img_src, top_left, bottom_right, (255, 0, 0), 2) # 绘制边框 cv.imshow('Delected Range', img_src) cv.waitKey(0)
运行结果:
2. 多目标匹配
多目标匹配是指输入图像中存在多个可能的匹配结果。
在使用 CV2natcTemplate()函数执行了匹配操作后,根据匹配方法设置阈值,匹配结果中低于或者高于阈值的就是符合条件的匹配目标。
代码示例:
import cv2 as cv import numpy as np img_src = cv.imread('../Image/lena_more.jpg') cv.imshow('src', img_src) img_temp = cv.imread('../Image/lena_face.png') cv.imshow('templte', img_temp) gray_src = cv.cvtColor(img_src, cv.COLOR_BGR2GRAY, dstCn=1) # 转为单通道灰度图 gray_temp = cv.cvtColor(img_temp, cv.COLOR_BGR2GRAY, dstCn=1) # 转为单通道灰度图 temp_h, temp_w = gray_temp.shape # 模板宽度和高度 src_h, src_w = gray_src.shape res = cv.matchTemplate(gray_src, gray_temp, cv.TM_SQDIFF_NORMED) # 执行匹配 mloc = [] threshold = 0.64 for i in range(src_h - temp_h): for j in range(src_w - temp_w): if res[i][j] <= threshold: mloc.append((j, i)) for pt in mloc: cv.rectangle(img_src, pt, (pt[0] + temp_w, pt[1] + temp_h), (0, 0, 255), 3) # 标注匹配位置 cv.imshow('Matching Result', img_src) cv.waitKey(0)
注:本例图找的不是很好,所以匹配结果欠佳
/*-------------------------------------------------------------------------------------------------------
笔者说明:
该笔记来源于本人学习Python + OpenCv时的资料,
分享出来只是为了供大家学习,并且为了自己以后想要用的时候方便寻找。
时间:2023年8月24日
------------------------------------------------------------------------------------------------------------*/