OpenCV: Template Matching
使用 OpenCV模板匹配实现对象检测,刷新游戏记录。哔哩哔哩bilibili
第51讲 模板匹配 小宅博客网 (bilibili996.com)
【OpenCv基础】第五十一讲 模板匹配哔哩哔哩bilibili
模板匹配是一种在较大图像中搜索和查找模板图像位置的方法。为此,OpenCV附带了一个函数cv.matchTemplate()。它简单地将模板图像滑动到输入图像上(如在2D卷积中),并比较模板图像下的模板和输入图像的补丁。OpenCV中实现了几种比较方法。(您可以查看文档以了解更多详细信息)。它返回一个灰度图像,其中每个像素表示该像素的邻域与模板匹配的程度。
如果输入图像的大小为(WxH),而模板图像的大小是(WxH),则输出图像的大小将为(W-W+1,H-H+1)。得到结果后,可以使用cv.minMaxLoc()函数来查找最大值/最小值。将其作为矩形的左上角,并将(w,h)作为矩形的宽度和高度。那个矩形是你的模板区域。
代码:
import cv2
import numpy as np
# matchTemplate()一共有五种匹配方法
# 方法【0】- 平方差匹配法(SQDIFF)
# 方法【1】- 归一化平方差匹配法(SQDIFF NORMED)
# 方法【2】- 相关匹配法(TM CCORR)
# 方法【3】- 归一化相关匹配法(TM CCORR NORMED)
# 方法【4】- 相关系数匹配法(TM COEFF)
# 方法【5】- 归一化相关系数匹配法(TM COEFF NORMED)
def one_Rectangle():
# 加载图片
srcImage = cv2.imread("./TestPic/OriginPic//farm.png", cv2.IMREAD_UNCHANGED)
templateImage = cv2.imread("./TestPic/OriginPic//needle.png", cv2.IMREAD_UNCHANGED)
width = templateImage.shape[1]
height = templateImage.shape[0]
# 进行匹配 保存匹配图片
resultImage = cv2.matchTemplate(srcImage, templateImage, cv2.TM_CCOEFF_NORMED)
cv2.imwrite("./TestPic/Results/resultImage.png", resultImage * 255)
# cv2.imshow('Result', resultImage)
# cv2.waitKey()
# cv2.destroyAllWindows()
# 通过函数 minMaxLoc 定位最匹配的位置:minValue:最小匹配值、maxValue:最大匹配值、minLoc:最小匹配位置、maxLoc:最大匹配位置
# 对于方法 SQDIFF 和 SQDIFF_NORMED, 越小的数值有着更高的匹配结果. 而其余的方法, 数值越大匹配效果越好
minValue, maxValue, minLoc, maxLoc = cv2.minMaxLoc(resultImage)
# 将搜索到的矩形区域裁处来,并保存为图片
rectangleImage = srcImage[int(maxLoc[1]):int(maxLoc[1] + height),int(maxLoc[0]):int(maxLoc[0] + width)]
cv2.imwrite("./TestPic/Results/rectangleImage.png", rectangleImage)
# 在原图中绘制矩形区域黄色框线,并保存原图
resultImage_rectangle = cv2.rectangle(srcImage, maxLoc, (maxLoc[0] + width, maxLoc[1] + height), (0, 255, 255), 1)
cv2.imwrite("./TestPic/Results/resultImage_rectangle.png", resultImage_rectangle)
one_Rectangle()
结果:
匹配结果图像-resultImage
矩形区域裁剪图片-rectangleImage
原图中展现匹配结果-resultImage_rectangle
代码:
import cv2
import numpy as np
# 日后使用时要设置相机 位深度为24bit、格式为png
# matchTemplate()一共有五种匹配方法
# 方法【0】- 平方差匹配法(SQDIFF)
# 方法【1】- 归一化平方差匹配法(SQDIFF NORMED)
# 方法【2】- 相关匹配法(TM CCORR)
# 方法【3】- 归一化相关匹配法(TM CCORR NORMED)
# 方法【4】- 相关系数匹配法(TM COEFF)
# 方法【5】- 归一化相关系数匹配法(TM COEFF NORMED)
def mul_Rectangle():
# 加载图片
srcImage = cv2.imread("./TestPic/OriginPic//farm.png", cv2.IMREAD_UNCHANGED)
templateImage = cv2.imread("./TestPic/OriginPic//needle.png", cv2.IMREAD_UNCHANGED)
width = templateImage.shape[1]
height = templateImage.shape[0]
# 进行匹配 保存匹配图片
resultImage = cv2.matchTemplate(srcImage, templateImage, cv2.TM_CCOEFF_NORMED)
cv2.imwrite("./TestPic/ResultsMul/resultImage.png", resultImage * 255)
# 设置匹配阈值,越小要求越低
threshold = 0.6
# 将大于匹配阈值的点的坐标都筛选出来
yloc, xloc = np.where(resultImage >= threshold)
rectangles = []
for (x, y) in zip(xloc, yloc):
rectangles.append([int(x), int(y), int(width), int(height)])
# rectangles.append([int(x), int(y), int(width), int(height)])
# 将搜索到的矩形区域裁出来,并保存为图片
rectangleImage = srcImage[int(y):int(y + height),int(x):int(x + width)]
cv2.imwrite("./TestPic/ResultsMul/rectangleImage_" + str(x) + "_" + str(y) + ".png", rectangleImage)
# 在原图中绘制矩形区域黄色框线
resultImage_rectangle = 0
for (x, y) in zip(xloc, yloc):
resultImage_rectangle = cv2.rectangle(srcImage, (x, y), (x + width, y + height), (0, 255, 255), 1)
# 并保存原图
cv2.imwrite("./TestPic/ResultsMul/resultImage_rectangle.png", resultImage_rectangle)
mul_Rectangle()
结果:
匹配结果图像-resultImage
矩形区域裁剪图片-rectangleImage-多个
原图中展现匹配结果-resultImage_rectangle-有匹配重叠区域