OpenCV 模板匹配教程

devtools/2024/9/29 7:58:55/

OpenCV 模板匹配教程

模板匹配是一种计算机视觉技术,用于在更大的图像(源图像)中查找较小的子图像(模板图像)。OpenCV 提供了多种模板匹配的方法,允许我们检测源图像中与模板最相似的位置。在本教程中,我们将介绍如何使用 OpenCV 实现模板匹配。

官方文档链接

OpenCV 模板匹配文档

1. 安装 OpenCV

首先,确保你的 Python 环境中已经安装了 OpenCV。如果还没有安装,可以使用 pip 进行安装:

pip install opencv-python

2. 基本模板匹配

模板匹配的基本思想是滑动模板图像(子图像)并计算每个位置的匹配度。OpenCV 提供了 cv2.matchTemplate() 方法进行匹配,以及 cv2.minMaxLoc() 方法获取匹配结果的最小值和最大值。

2.1 基本模板匹配示例
import cv2
import numpy as np# 读取源图像和模板图像
source_image = cv2.imread('source.jpg', 0)
template_image = cv2.imread('template.jpg', 0)# 获取模板的宽度和高度
w, h = template_image.shape[::-1]# 执行模板匹配
result = cv2.matchTemplate(source_image, template_image, cv2.TM_CCOEFF_NORMED)# 获取匹配结果中最值的位置
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)# 画出匹配结果矩形
top_left = max_loc  # 对于TM_CCOEFF_NORMED, 最优匹配位置在max_loc
bottom_right = (top_left[0] + w, top_left[1] + h)
cv2.rectangle(source_image, top_left, bottom_right, 255, 2)# 显示结果
cv2.imshow('Detected', source_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
2.2 代码解释
  1. 读取图像: 使用 cv2.imread() 读取源图像和模板图像。0 表示以灰度模式加载图像。

  2. 获取模板尺寸: 使用 shape[::-1] 获取模板图像的宽度和高度。

  3. 执行模板匹配: 使用 cv2.matchTemplate() 方法执行模板匹配。此方法有多种匹配算法可选,本例使用 cv2.TM_CCOEFF_NORMED,它是一种归一化方法,适合在不同亮度和对比度下的匹配。

  4. 获取最优匹配位置: 使用 cv2.minMaxLoc() 获取匹配结果中最小值和最大值的位置。对于 cv2.TM_CCOEFF_NORMED 方法,最佳匹配位置在 max_loc

  5. 绘制匹配结果: 使用 cv2.rectangle() 在源图像中绘制一个矩形,表示最佳匹配位置。

  6. 显示结果: 使用 cv2.imshow() 显示匹配结果。

3. 模板匹配方法

OpenCV 提供了几种不同的模板匹配方法,你可以根据应用场景选择合适的方法:

  • cv2.TM_SQDIFF:平方差匹配,结果越小越好。
  • cv2.TM_SQDIFF_NORMED:归一化平方差匹配,结果越小越好。
  • cv2.TM_CCORR:互相关匹配,结果越大越好。
  • cv2.TM_CCORR_NORMED:归一化互相关匹配,结果越大越好。
  • cv2.TM_CCOEFF:相关系数匹配,结果越大越好。
  • cv2.TM_CCOEFF_NORMED:归一化相关系数匹配,结果越大越好。

你可以在 cv2.matchTemplate() 中尝试不同的方法,观察结果如何变化。

methods = ['cv2.TM_CCOEFF', 'cv2.TM_CCOEFF_NORMED', 'cv2.TM_CCORR', 'cv2.TM_CCORR_NORMED', 'cv2.TM_SQDIFF', 'cv2.TM_SQDIFF_NORMED']for meth in methods:img = source_image.copy()method = eval(meth)# 模板匹配result = cv2.matchTemplate(img, template_image, method)min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)if method in [cv2.TM_SQDIFF, cv2.TM_SQDIFF_NORMED]:top_left = min_locelse:top_left = max_locbottom_right = (top_left[0] + w, top_left[1] + h)cv2.rectangle(img, top_left, bottom_right, 255, 2)cv2.imshow(meth, img)cv2.waitKey(0)cv2.destroyAllWindows()

4. 多重对象检测

如果要检测图像中多个匹配的对象,可以设置一个阈值来过滤匹配结果,使用 np.where() 找到所有满足条件的位置。

4.1 多重对象检测示例
# 定义阈值
threshold = 0.8# 获取匹配结果的所有位置
loc = np.where(result >= threshold)# 画出所有匹配结果
for pt in zip(*loc[::-1]):bottom_right = (pt[0] + w, pt[1] + h)cv2.rectangle(source_image, pt, bottom_right, 255, 2)# 显示结果
cv2.imshow('Detected Multiple Objects', source_image)
cv2.waitKey(0)
cv2.destroyAllWindows()

5. 高级技巧:金字塔图像模板匹配

在一些应用场景中,模板和待匹配对象在尺寸上可能不完全相同,这时可以使用金字塔图像技术(Pyramid Image)进行多尺度模板匹配。

5.1 金字塔图像模板匹配示例
# 金字塔图像模板匹配
for scale in np.linspace(0.5, 1.5, 20)[::-1]:resized = cv2.resize(source_image, (int(source_image.shape[1] * scale), int(source_image.shape[0] * scale)))result = cv2.matchTemplate(resized, template_image, cv2.TM_CCOEFF_NORMED)min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)if max_val >= threshold:print(f"Match found at scale {scale}")# 计算缩放后的位置top_left = (int(max_loc[0] / scale), int(max_loc[1] / scale))bottom_right = (int((max_loc[0] + w) / scale), int((max_loc[1] + h) / scale))cv2.rectangle(source_image, top_left, bottom_right, 255, 2)# 显示结果cv2.imshow('Detected with Pyramid', source_image)cv2.waitKey(0)breakcv2.destroyAllWindows()

6. 总结

模板匹配是 OpenCV 提供的强大功能,可以用于对象检测和图像分析。通过本文的教程,我们学习了如何使用 OpenCV 实现模板匹配、选择不同的匹配方法、检测多个对象以及使用金字塔技术进行多尺度匹配。根据不同的应用需求,可以调整匹配方法和参数以达到最佳效果。

更多关于 OpenCV 模板匹配的详细信息和高级用法,请参考 OpenCV 官方文档。


http://www.ppmy.cn/devtools/104940.html

相关文章

【3.6】贪心算法-解救生艇问题

一、题目 第 i 个人的体重为 people[i],每艘船可以承载的最大重量为 limit。 每艘船最多可同时载两人,但条件是这些人的重量之和最多为 limit 。 返回载到每一个人所需的最小船数。(保证每个人都能被船载)。 二、解题思路 题目要求每艘船最多能载两人&…

单窗口IP代理设置指南:轻松搞定

在现代互联网生活中,IP代理已经成为了许多人日常上网的必备工具。单窗口IP代理是一种非常实用的代理方式,它允许你在同一个浏览器中为不同的窗口设置不同的IP地址,从而更好地保护隐私和实现多任务处理。今天,我们就来详细讲解一下…

AI引领,驱动未来:零售企业的新质生产力革命

在这个快节奏的零售世界里,每一天都充满了变数。但你是否想象过,当AI(人工智能)、驱动技术、商品计划软件以及新质生产力携手并进时,零售企业将如何焕发新生,轻松应对挑战,引领行业潮流&#xf…

数字芯片中I/O单元及电源domain布局中SIPI的考虑

芯片设计的物理实施过程通常也简称为布局布线(P&R,Place-and-Route),布局一般被分为布局规划(Floorplan)和标准单元摆放(Place)两个过程。而其中的布局规划是芯片后端物理实现过…

数学基础 -- 线性代数之酉矩阵

酉矩阵(Unitary Matrix) 酉矩阵是线性代数中一种重要的矩阵类型,特别在量子力学和信号处理等领域有广泛的应用。以下是酉矩阵的定义、性质以及使用和计算的例子。 1. 定义 酉矩阵是一个复矩阵 U U U ,满足以下条件&#xff1a…

如何把钓鱼邮件“拒之门外”?试试U-Mail邮件安全网关

在当今信息化时代,互联网的发展使得人与人之间的沟通变得更加便捷和频繁,通过互联网,人们可以随时与远在他处的朋友或者业务伙伴进行交流。同时也给不法之徒利用互联网进行欺诈和违法犯罪提供了可乘之机。钓鱼邮件就是不法之徒利用网络实施不…

OceanbaseV4模拟题解析

使用 Docker 部署的 OceanBase 可以作为MetaDB,供OceanBase相关产品作为元数据数据库来使用。以下哪类产品需要MetaDB?(AD) ​ A OCP ​ B OBProxy ​ C OAT ​ D OMS MetaDB:基于容器部署的 OceanBase 数据库服务,可…

uniapp二维码生成

uniapp二维码生成 参考文档依赖引入代码html部分生成代码&#xff08;vue3 hook&#xff09;使用 参考文档 【博主&#xff1a;ChoneyLove】uniapp中生成二维码及解决微信小程序端问题总结 依赖引入 npm i uqrcodejs代码 html部分 <canvas type"2d" id"…