第十五章: 模板匹配
模板匹配就是在給定的圖片中查找和模板最相似的區(qū)域。
實(shí)現(xiàn)的方法是:將模板在圖片上滑動(dòng)(從左向右,從上向下),遍歷所有滑窗,計(jì)算匹配度,將所有計(jì)算結(jié)果保存在一個(gè)矩陣種,并將矩陣中匹配度最高的值作為匹配結(jié)果。
一、單模板匹配
-
1、匹配函數(shù):result = cv2.matchTemplate(img, temp, method[, mask])
img:要進(jìn)行匹配的圖像,必須是8位或者32位的浮點(diǎn)型圖像
tem:模板圖像,尺寸要要小于原圖,數(shù)據(jù)類型要和原圖一樣。
method:匹配方法,也就是相似度計(jì)算方法,opencv提供了6種計(jì)算方法(主要是下面三種,另外三種是下面三種方式的歸一化結(jié)果):
平方差匹配cv2.TM_SQDIFF:以方差為依據(jù)進(jìn)行匹配。如果完全匹配,匹配值為0,匹配值越大,越不匹配。
相關(guān)匹配cv2.TM_CCORR:將模板圖像和輸入圖像相乘,如果匹配值越大,表示匹配程度越高,如果乘積等于0,則表示完全不匹配。
相關(guān)系數(shù)匹配cv2.TM_CCOEFF:將模板圖像與其均值的相對(duì)值,和輸入圖像與其均值的相對(duì)值,進(jìn)行匹配。1表示完美匹配,-1表示糟糕匹配,0表示沒有任何相關(guān)性,是隨機(jī)序列。
函數(shù)返回值result是一個(gè)矩陣,大小是(W-w+1, H-h+1),其中W,H是原圖的寬高,w,h是模板的寬高。矩陣?yán)锩娴拿總€(gè)元素表示的是寬高和模型一樣大小的矩形的頂點(diǎn)。 -
2、查找最佳匹配的位置坐標(biāo):minval, maxval, minloc, maxloc = cv2.minMaxLoc(array[, mask])
為什么要返回這么多對(duì)象,因?yàn)槠ヅ浜瘮?shù)cv2.matchTemplate()由于參數(shù)method設(shè)定的不同,其返回值值result中表示最佳匹配的結(jié)果不同,比如參數(shù)method=cv2.TM_SQDIFF,那我們想直到最佳匹配區(qū)域的坐標(biāo)值就是return對(duì)象里面的最小值以及最小值對(duì)應(yīng)的坐標(biāo)值。如果method=cv2.TM_CCORR,或者cv2.TM_CCOEFF,那我們要找的最佳匹配區(qū)域就是return中的最大值及最大值對(duì)應(yīng)的坐標(biāo)值。
minval1、maxval1是array中的最值,minloc1、maxloc1是array中最值對(duì)應(yīng)的坐標(biāo)點(diǎn),但是這個(gè)坐標(biāo)點(diǎn)是(列,行)的形式?。。?/p> -
3、用矩形框把最佳匹配區(qū)域框出來:img = cv2.rectangle(img, pt1, pt2, color, thickness)
說明:pt1和pt2都是(列,行)的形式
?#例15.1 使用cv2.matchTemplate()函數(shù)的不同計(jì)算方法進(jìn)行模板匹配 import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread(r'C:\Users\25584\Desktop\lena.bmp',0) #img.shape返回(512, 512) template = cv2.imread(r'C:\Users\25584\Desktop\temp.bmp',0) #template.shape返回(40, 200) result1 = cv2.matchTemplate(img, template, cv2.TM_SQDIFF) #result1.shape返回(473, 313) result2 = cv2.matchTemplate(img, template, cv2.TM_CCORR_NORMED) #如果是cv2.TM_CCORR匹配出來的效果非常差!為什么???? result3 = cv2.matchTemplate(img, template, cv2.TM_CCOEFF) minval1, maxval1, minloc1, maxloc1 = cv2.minMaxLoc(result1) #minval1和result1.min()返回值一樣 minval2, maxval2, minloc2, maxloc2 = cv2.minMaxLoc(result2) minval3, maxval3, minloc3, maxloc3 = cv2.minMaxLoc(result3) img1 = img.copy() img1 = cv2.rectangle(img1, minloc1, (minloc1[0]+200, minloc1[1]+40), 255, 2) img2 = img.copy() img2 = cv2.rectangle(img2, maxloc2, (maxloc2[0]+200, maxloc2[1]+40), 255, 2) img3 = img.copy() img3 = cv2.rectangle(img3, maxloc3, (maxloc3[0]+200, maxloc3[1]+40), 255, 2) #可視化: plt.figure(figsize=(16,6)) plt.subplot(161), plt.imshow(img, cmap='gray') #原圖 plt.subplot(162), plt.imshow(template, cmap='gray') #模板 plt.subplot(163), plt.imshow(result1, cmap='gray') #匹配的返回值 plt.subplot(164), plt.imshow(img1, cmap='gray') # plt.subplot(165), plt.imshow(img2, cmap='gray') # plt.subplot(166), plt.imshow(img3, cmap='gray') # plt.show()
說明:模板匹配不適用尺度變換、視角變換后的圖像?。?!
如果非要匹配,我們就要使用關(guān)鍵點(diǎn)匹配算法,比較經(jīng)典的關(guān)鍵點(diǎn)檢測(cè)算法包括SIFT和SURF等,主要思路是先通過關(guān)鍵點(diǎn)檢測(cè)算法獲取模板和檢測(cè)圖像中的關(guān)鍵點(diǎn),然后使用關(guān)鍵點(diǎn)匹配算法處理。因?yàn)檫@些關(guān)鍵點(diǎn)可以很好的處理尺度變換、視角變換、旋轉(zhuǎn)變化、光照變化等,具有很好的不變性。二、多模板匹配
當(dāng)要匹配的圖像中有多個(gè)模板圖像時(shí),就是模板圖像在原圖中出現(xiàn)多次時(shí),這時(shí)就要找出多個(gè)匹配結(jié)果。文章來源:http://www.zghlxwxcb.cn/news/detail-787844.html
- 1、匹配函數(shù):result = cv2.matchTemplate(img, temp, method[, mask])的返回對(duì)象result里面就會(huì)有多個(gè)符合條件的點(diǎn)
- 2、找出result中的多個(gè)符合條件的點(diǎn):因?yàn)閞esult是一個(gè)二維array,在二維array中值大于閾值0.99(因?yàn)槲覀冞@里假設(shè)匹配方法是cv2.TM_CCOEFF_NORMED,是相關(guān)系數(shù)匹配),所以要用:loc = np.where(result>=0.99),這樣就把result里面大于0.99的值的橫縱坐標(biāo)找出來了。loc返回值是一個(gè)元組,元組的第一個(gè)元素是一個(gè)array,這個(gè)array是索引出來的所有符合條件的點(diǎn)的橫坐標(biāo)索引,元組的第二個(gè)元素是所有符合條件的點(diǎn)的列索引。
- 3、用for循環(huán)畫圖。循環(huán)的時(shí)候是循環(huán)zip(*loc),這樣循環(huán)的時(shí)候就是把loc中的每個(gè)元素對(duì)應(yīng)位置進(jìn)行遍歷。
但是這里要注意的是畫圖的時(shí)候是(列,行)索引來畫的,但是循環(huán)的時(shí)候循環(huán)的是最值的(行,列)坐標(biāo),所以畫圖的時(shí)候要行列翻轉(zhuǎn)一下。#例15.2 練習(xí)多模板匹配 import cv2 import numpy as np import matplotlib.pyplot as plt img = cv2.imread(r'C:\Users\25584\Desktop\lena4.bmp',0) #img.shape返回(540, 700) template = cv2.imread(r'C:\Users\25584\Desktop\lena4Temp.bmp',0) #template.shape返回(51, 103) result = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED) #result.shape返回(490, 598) plt.figure(figsize=(16,8)) plt.subplot(131), plt.imshow(img, cmap='gray') #原圖 plt.subplot(132), plt.imshow(template, cmap='gray') #模板 plt.subplot(133), plt.imshow(result, cmap='gray') #匹配的返回值 loc = np.where(result >= 0.99) img1 = img.copy() for pt in zip(*loc): cv2.rectangle(img1, pt[::-1], (pt[::-1][0]+103, pt[::-1][1]+51), 255,1) #可視化: plt.figure(figsize=(16,8)) plt.imshow(img1, cmap='gray') # plt.show()
文章來源地址http://www.zghlxwxcb.cn/news/detail-787844.html
到了這里,關(guān)于【OpenCV】第十五章: 模板匹配的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!