1. 引言
今天我們來研究一種傳統(tǒng)圖像處理領域中對象檢測和跟蹤不可或缺的方法——模板匹配,其主要目的是為了在圖像上找到我們需要的圖案,這聽起來十分令人興奮。
所以,事不宜遲,讓我們直接開始吧!
2. 概念
模板匹配的算法的核心十分簡單:它將模板與源圖像中的每個部分進行比較,逐像素滑動。結(jié)果是一個相似度的圖,該相似度圖中每個像素值反映了模板與源圖像中該位置的相似程度。
從本質(zhì)上講,它將模板在圖像上進行卷積,類似于卷積神經(jīng)網(wǎng)絡中使用卷積核的方式。通過這個過程,創(chuàng)建了一個新的圖像或矩陣,其中每個像素值表示模板與源圖像中相應區(qū)域之間的相似性。通過分析該結(jié)果圖像,我們可以識別峰值,這些峰值表示源圖像中存在模板圖像的精確位置。值得注意的是,模板匹配的實現(xiàn)可能會有所不同,主要是基于相似性的度量因方法各異而不同,這里不做擴展展開。
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. 圖像灰度化
雖然模板匹配適用于彩色圖像,但讓我們簡化并將圖像轉(zhuǎn)換為灰度圖來減少計算量。
灰度化代碼如下:
# 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()
結(jié)果如下:
5. 加載模板
現(xiàn)在,讓我們從灰度圖中截取一個心動的表情作為我們的目標模板,代碼如下:
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();
結(jié)果如下:
6 模板匹配
通過使用 skimage
庫中的match_template
函數(shù) , 我們可以得到衡量模板圖和原圖的相似度的熱力圖,如下:
result = match_template(gray_image, template)
plt.figure(figsize=(10,10))
imshow(result, cmap='viridis')
plt.show();
結(jié)果如下:
上圖中顏色越鮮艷的區(qū)域顯示了和我們的模板相似度越高的區(qū)域,你注意到圖像中明亮的顏色區(qū)域形成的形狀了嗎?如果我們假設模板在源圖像中只找到一次,那么我們可以通過尋找具有最高值(~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);
得到結(jié)果如下:
7. 設置容忍度
為了定位模板的多個匹配,我們可以通過設定相關性值的峰值的容忍度來實現(xiàn),代碼如下:
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);
結(jié)果如下:
進而可以通過以下代碼,將結(jié)果畫到原圖,如下所示:
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);
最終結(jié)果如下:文章來源:http://www.zghlxwxcb.cn/news/detail-497449.html
8. 問題思考
- 如果我們改變閾值會發(fā)生什么?降低閾值將給我們更多的匹配(但也會有更多的誤報),而提高閾值將使匹配更少,但可能更準確。
- 放大模板怎么樣?模板越大,我們得到的匹配項就越少。這是因為匹配的大小必須與模板的大小幾乎相同。
- 水平翻轉(zhuǎn)模板?這可能會導致沒有匹配,因為模板匹配對方向很敏感。
- 更改圖像對比度?只要模板和原圖像發(fā)生相同的更改,匹配項就應該保持有效。然而,劇烈的變化可能會改變結(jié)果。
9. 總結(jié)
本文重點介紹了在傳統(tǒng)圖像處理中,如何利用模板匹配的方法來進行從表情包圖像中尋找心動表情模板的樣例,并給出了相應的代碼實現(xiàn)。由于是傳統(tǒng)方案,該方法的閾值選擇和泛化能力都有一定的局限性,但是學習其背后的原理可以幫助我們更好的理解相關理論概念。文章來源地址http://www.zghlxwxcb.cn/news/detail-497449.html
到了這里,關于用OpenCV進行模板匹配的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!