用OpenCV进行模板匹配

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. 总结

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

  • 1
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Python中使用OpenCV进行模板匹配可以通过matchTemplate函数来实现。该函数的原型为:matchTemplate(image, templ, method\[, result\[, mask\]\]) -> result。\[3\]其中,image是待搜索的图像,templ是要匹配的模板图像,method是匹配方法,result是输出的匹配结果,mask是可选的掩码图像。\[3\] 下面是一个使用OpenCV进行多对象模板匹配的示例代码: ```python import cv2 import numpy as np img_rgb = cv2.imread('Coins.jpg') img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY) template = cv2.imread('Coin.jpg', 0) w, h = template.shape\[::-1\] res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED) threshold = 0.4 loc = np.where(res >= threshold) for pt in zip(*loc\[::-1\]): cv2.rectangle(img_rgb, pt, (pt\[0\] + w, pt\[1\] + h), (0, 0, 255), 1) cv2.imshow("img", img_rgb) cv2.waitKey(0) cv2.destroyAllWindows() ``` 在这个示例中,我们首先读取了待搜索的图像和要匹配的模板图像,并将待搜索图像转换为灰度图像。然后,我们使用matchTemplate函数进行模板匹配,并设置了匹配阈值为0.4。最后,我们使用cv2.rectangle函数在匹配到的位置上绘制矩形框,将结果显示出来。\[1\] 希望这个示例能帮助到你进行OpenCV Python模板匹配。 #### 引用[.reference_title] - *1* [OpenCV - 模板匹配Python实现)](https://blog.csdn.net/qq_40344307/article/details/95111626)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* *3* [【OpenCV + Python模板匹配](https://blog.csdn.net/zhouzongzong/article/details/93761729)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

赵卓不凡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值