用OpenCV进行模板匹配

news2024/11/13 10:41:19

1. 引言

今天我们来研究一种传统图像处理领域中对象检测和跟踪不可或缺的方法——模板匹配,其主要目的是为了在图像上找到我们需要的图案,这听起来十分令人兴奋。

所以,事不宜迟,让我们直接开始吧!

2. 概念

模板匹配的算法的核心十分简单:它将模板与源图像中的每个部分进行比较,逐像素滑动。结果是一个相似度的图,该相似度图中每个像素值反映了模板与源图像中该位置的相似程度。

从本质上讲,它将模板在图像上进行卷积,类似于卷积神经网络中使用卷积核的方式。通过这个过程,创建了一个新的图像或矩阵,其中每个像素值表示模板与源图像中相应区域之间的相似性。通过分析该结果图像,我们可以识别峰值,这些峰值表示源图像中存在模板图像的精确位置。值得注意的是,模板匹配的实现可能会有所不同,主要是基于相似性的度量因方法各异而不同,这里不做扩展展开。

3. 举个栗子

巴拉巴拉讲了一堆概念性的文字,好多小伙伴会感觉到枯燥无味,基于此,我们来看我们的例子,首先我们引入我们需要的基础库,如下:

# Import libraries
import numpy as np
import matplotlib.pyplot as plt
from skimage.io import imread, imshow
from skimage.color import rgb2gray
from skimage.feature import match_template
from skimage.feature import peak_local_max

紧接着,我们来观察我们的用例图像,代码如下:

original_image = imread('emojis.png')
plt.figure(figsize=(20,20))
plt.imshow(original_image)
plt.title('Original Image', fontsize=20, weight='bold')
plt.axis('off')
plt.show()

显示图像如下:
在这里插入图片描述
假设我们的任务安排为通过基本的图像处理流程,从上图中找到我们需要的心动模板。弄清楚了具体的需求,我们直接开始编码吧!

4. 图像灰度化

虽然模板匹配适用于彩色图像,但让我们简化并将图像转换为灰度图来减少计算量。
灰度化代码如下:

# Convert the image to grayscale
gray_image = rgb2gray(original_image[:,:,:3])
plt.figure(figsize=(20,20))
plt.imshow(gray_image, cmap='gray')
plt.title('Grayscale Image', fontsize=20, weight='bold')
plt.axis('off')
plt.show()

结果如下:
在这里插入图片描述

5. 加载模板

现在,让我们从灰度图中截取一个心动的表情作为我们的目标模板,代码如下:

template = gray_image[1330:1850,625:1140]
plt.figure(figsize=(10,10))
plt.imshow(template, cmap='gray')
plt.title('Template Image', fontsize=20, weight='bold')
plt.axis('off')
plt.show();

结果如下:
在这里插入图片描述

6 模板匹配

通过使用 skimage 库中的match_template函数 , 我们可以得到衡量模板图和原图的相似度的热力图,如下:

result = match_template(gray_image, template)
plt.figure(figsize=(10,10))
imshow(result, cmap='viridis')
plt.show();

结果如下:
在这里插入图片描述
上图中颜色越鲜艳的区域显示了和我们的模板相似度越高的区域,你注意到图像中明亮的颜色区域形成的形状了吗?如果我们假设模板在源图像中只找到一次,那么我们可以通过寻找具有最高值(~1.00)的像素来找到它的位置。代码如下:

x, y = np.unravel_index(np.argmax(result), result.shape)
imshow(gray_image)
template_width, template_height = template.shape
rect = plt.Rectangle((y, x), template_height, template_width, color='y', 
                     fc='none')
plt.gca().add_patch(rect);

得到结果如下:
在这里插入图片描述

7. 设置容忍度

为了定位模板的多个匹配,我们可以通过设定相关性值的峰值的容忍度来实现,代码如下:

imshow(gray_image)
template_width, template_height = template.shape
for x, y in peak_local_max(result, threshold_abs=0.99):
    rect = plt.Rectangle((y, x), template_height, template_width, color='red', 
                         fc='none')
    plt.gca().add_patch(rect);

结果如下:
在这里插入图片描述

进而可以通过以下代码,将结果画到原图,如下所示:

plt.figure(figsize=(20, 20))
plt.imshow(original_image)
plt.title('We found our heart eyes emojis!', fontsize=20, weight='bold', color='red')
template_width, template_height = template.shape
for x, y in peak_local_max(result, threshold_abs=0.99):
    rect = plt.Rectangle((y, x), template_height, template_width, color='red', 
                         fc='none')
    plt.gca().add_patch(rect);

最终结果如下:
在这里插入图片描述

8. 问题思考

  • 如果我们改变阈值会发生什么?降低阈值将给我们更多的匹配(但也会有更多的误报),而提高阈值将使匹配更少,但可能更准确。
  • 放大模板怎么样?模板越大,我们得到的匹配项就越少。这是因为匹配的大小必须与模板的大小几乎相同。
  • 水平翻转模板?这可能会导致没有匹配,因为模板匹配对方向很敏感。
  • 更改图像对比度?只要模板和原图像发生相同的更改,匹配项就应该保持有效。然而,剧烈的变化可能会改变结果。

9. 总结

本文重点介绍了在传统图像处理中,如何利用模板匹配的方法来进行从表情包图像中寻找心动表情模板的样例,并给出了相应的代码实现。由于是传统方案,该方法的阈值选择和泛化能力都有一定的局限性,但是学习其背后的原理可以帮助我们更好的理解相关理论概念。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/676006.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

哈夫曼树——数组实现

构造n个给定值节点构成的森林; 选择权值最小的两个构成叶子节点,根节点权值为两叶子节点之和, 删除原有的两棵树,将这棵树加入森林中; 重复这两部直到只有一棵树为止,此树就是哈夫曼树; #pr…

警惕这些“挂羊头卖狗肉”的高科技培训!

最近真的被误人子弟的教育骗子给气到! 事情是这样的,6月11号,我在2023 开放原子全球开源峰会上,遇到了一位从广东来北京参会的老师。 这位老师透露,他来自一所职业技术学院,学校师资挺不错的,可…

Spring Boot 如何配置日志级别和输出格式

Spring Boot 如何配置日志级别和输出格式 在开发一个应用程序时,日志记录是非常重要的一环。Spring Boot 提供了多种日志输出方式和配置选项,本文将介绍如何在 Spring Boot 应用程序中配置日志级别和输出格式。 配置日志级别 在 Spring Boot 应用程序中…

【知识点随笔分享 | 第一篇】避不开的浮点误差

引入: 各位在大一初入C语言的时候,老师肯定说过浮点数之间的比较要用做差法,当二者的差值特别小甚至于接近0的时候,这两个数就相等,不知道各位是否会有疑惑?为什么浮点数不可以直接进行比较呢? …

Nacos-手写配置中心基本原理

本文已收录于专栏 《中间件合集》 目录 概念说明Nacos配置中心Naocs配置项Naocs配置集Naocs配置快照 需求分析核心功能代码实现AService模块BService模块NacosService模块NacosSDK模块 注意事项总结提升 概念说明 Nacos注册中心:https://blog.csdn.net/weixin_4549…

vs中运行时库简要说明

vs中右键单击工程 -->属性–>c/c->代码生成,进入如下菜单中: 可以看出有如下几个选项: 多线程(/MT):链接目标库为libcmt.lib 多线程调试(/MTd):链接目标库为libcmtd.lib 多线程DLL(/MD):链接目标…

02.GLM-130B

文章目录 前言泛读相关知识GPTBERTT5小结 背景介绍主要贡献和创新点GLM 6B 精读自定义Mask模型量化1TB 的中英双语指令微调RLHFPEFT训练策略 实验分析与讨论模型参数六个指标其他测评结果 代码复现(6B)环境准备运行调用代码调用网页服务命令行调用 模型微…

在 Python 中生成随机 4 位数字

文章目录 在 Python 中生成随机数使用 random 模块在 Python 中生成随机数使用 random.randint() 方法使用 random.randrange() 方法 使用替代方法在 Python 中生成随机数总结 Python 是一种高级解释型编程语言,全球大多数程序员都在使用它。 它在面向对象编程 (OOP…

SpringCloud Alibaba入门5之Hystrix的使用

我们继续在前一章的基础上进行学习。 SpringCloud Alibaba入门5之使用OpenFegin调用服务_qinxun2008081的博客-CSDN博客 上一节我们已经使用OpenFeign完成了服务间的调用,如果现在存在大量的服务,每个服务有若干个节点,其中一个节点发生故障…

Word技巧之【文档自动保存】

打工人的噩梦—电脑突然坏掉,文档还没保存!你是否遇到这种情况? 如果Word文档设置了自动保存,就不用太过担心了,只需要几个简单的操作就能设置好。还不知道的小伙伴,跟着小编一起看看吧。 设置Word文档自动…

一起来学R编程把—do.call 函数的应用

R语言由一个个基础函数组成,熟练灵活应用这些基础函数,有助于我们更好的学习R包及编程,这个专栏可能很多人不感兴趣,但是对提升自己很有帮助,感兴趣的朋友一起来学习。今天我们来介绍一下do.call函数的用法. do.call函数是一个非…

ChatGLM-6B阿里云部署

机器配置 重点关注指标:CPU、内存、GPU、GPU驱动 类型CPU内存GPU机器配置16核125GNVIDIA A100 80G # 查看显卡安装状态 nvidia-smi 安装必要的软件 git sudo apt-get update sudo apt-get install git git-lfs(大文件管理) sudo apt-get install git-lfs py…

从零开始手搓一个STM32与机智云的小项目——GPIO模拟时序控制外设1

文章目录 前言WS2812B1.模块简介2.时序介绍3.硬件介绍4.传输速率,以及帧数要求 代码1.初始化2.模拟时序1.复位函数2.发送0、1码3.封装发送函数 总结 前言 上一篇文章中介绍了整个板子的最基本功能模块——使用GPIO的通用输入输出实现简单的按键输入以及推挽输出控制…

基于Java+Swing+Mysql实现图书管理系统V2.0

基于JavaSwingMysql实现图书管理系统V2.0 一、系统介绍二、功能展示1.项目内容2.项目骨架3.数据库表4.主界面5.添加6、修改7、查询8、删除 四、其它1.其他系统实现五.获取源码 一、系统介绍 本系统主要有对图书信息的增删改查操作功能。 项目类型:Java SE项目&…

到底还有谁学不会 MySQL 中的视图?

文章目录 MySQL中的视图视图的概念视图的用法简化查询操作提高查询效率保护数据的安全性 视图的代码示例总结 MySQL中的视图 在MySQL中,视图是一种虚拟表,它是由一个或多个基本表的行或列组成的。视图并不实际存储数据,而是根据定义的查询语…

6-端午练习

目录标题 6_221. 进程和线程2. 数据7>>1 6_231. 用户相关指令2. 创建用户(1. 查看id(2. 查看当前用户(3. 创建用户(4. 给新用户添加sudo权限>1 修改sudoers文件 2. 删除用户3. 修改用户名2. 磁盘1. 保证ubuntu链接上U盘(1. VM弹窗,选择链接到虚拟机(2. 虚拟…

DELL的交换机PowerSwitch学习手册-ONIE篇

下面是最近学习DELL的网络交换机PowerSwitch的一些笔记,供朋友们参考。如果还有问题,可以add wechat at StorageExpert。 在具体学习产品之前,先来了解下DELL的ONIE,什么是ONIE?和如何使用ONIE? ONIE是 O…

关于Nginx网站服务

目录 一、首先搭建Nginx服务 二、授权的访问控制 第一步 安装依赖包 第二步 生成用户密码认证文件 第三步 修改文件属性和权限 第四步 修改配置文件 第五步 用浏览器测试网站 三、基于IP地址进行限制 第一步 修改配置文件 第二步 用两台设备进行访问测试 四、基于域…

Linux - 内存、swap、内存回收机制

参考 2023年6月22日 https://zhuanlan.zhihu.com/p/107350459 —— 讨论的swap基于Linux4.4内核代码 内存深度科普: 从堆内存到虚拟内存管理 2023年6月22日 qbittorrent swap 问题 https://github.com/qbittorrent/qBittorrent/issues/12947 massif valgrind --toolmassif qb…

taro实现小程序地图打点

使用taro的map标签&#xff0c;往markers里放入点位&#xff1a; <map v-if"mapLoading" id"mapId":longitude"userPosition.x":latitude"userPosition.y":show-location"false":markers"markerList":scale&q…