2015-11-30 99 views
0

我在圖像處理中的新手,我瞭解模版匹配,並且我從OpenCV一些幫助,但我不明白的一些代碼行,這裏是代碼模板匹配使用的OpenCV + Python的

import cv2 
import numpy as np 
from matplotlib import pyplot as plt 
img_rgb = cv2.imread('mario.png') 
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY) 
template = cv2.imread('coin.png', 0) 
w, h = template.shape[::-1] 
count = 0 

res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED) 
threshold = 0.8 
loc = np.where(res >= threshold) 
for pt in zip(*loc[::-1]): 
    count += 1 
    cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0,0,255), 2) 

cv2.imwrite('res.png', img_rgb) 
print(count) 

的目標是模板匹配超級馬里奧地圖中的硬幣。
我的問題:
1.在循環for pt in zip(*loc[::-1]):我把計數器,當我打印的打印65,而硬幣只有19
2.什麼是可變threshold=0.8的功能,當我改變的價值,結果圖像是變化。

任何人都可以幫助我回答我的問題嗎? 預先感謝您。

+0

您是否閱讀過關於[matchTemplate'返回的內容的OpenCV文檔](http://docs.opencv.org/2.4/modules/imgproc/doc/object_detection.html)? – kmac

+0

是的,我有。但我不明白爲什麼櫃檯顯示65,而硬幣只有19 – Cesario

+0

這種方法不是魔術,所以你會得到一些誤報(非硬幣標記爲硬幣)和一些錯誤的否定(硬幣未標記作爲硬幣)。聽起來你有65個硬幣標籤,圖像中只有19個硬幣。按照Aditya的建議嘗試提高門檻。但是這種方法可能無法達到你所希望的效果。您也可以在之後應用過濾來改善您的結果。 – kmac

回答

1

閾值0.8表示匹配應至少爲模板圖像的80%以及感興趣的源區域。因此如果它大於805就是一枚硬幣。如果你降低門檻,假陽性結果即使不是硬幣也會增加。

對於Zip中的pt(* loc [:: - 1]):該命令適用於值大於閾值的點。拉鍊是所有這些點的容器,它將迭代到所有這些點,並圍繞此封閉實體繪製矩形,即硬幣在這裏。

希望這有助於根據您正在使用的圖像亮度明白:)

+0

感謝您的優秀解釋,但我仍不明白爲什麼計數器是65而不是19,當我將其更改爲1時,它顯示0 – Cesario

+0

您可以繪製直方圖來查看您在不同響應範圍內的命中率。 1正在刪除所有內容,請嘗試0.8和1之間的值。 – kmac

0

閾值= 0.8的作品。 如果圖像上的光線正確,則閾值> 0.8將起作用,但主要是在相機圖像中,亮度會有所不同,所以亮度> 0.65可以起作用。 要匹配更多點,您必須降低閾值。