3

I am a newbie in Image Processing and learning about Template Matching by getting some help from OpenCV documentation, but I didn't understand some lines of the code.
Here is the code:

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)

The objective is to template match the coin in the super mario map.
My Questions :
1. In the loop for pt in zip(*loc[::-1]): I put a counter and when I print it, it prints 65, whereas the number of coins is only 19.
2. What is the function of the variable threshold=0.8, when I change its value, the resulting image is changed.

Can anyone help me to answer my question? Thank you in advance.

Mukul
  • 310
  • 1
  • 6
  • 13
Cesario
  • 75
  • 1
  • 9
  • Have you read the [OpenCV documentation on what `matchTemplate` returns](http://docs.opencv.org/2.4/modules/imgproc/doc/object_detection.html)? – kmac Nov 30 '15 at 05:41
  • Yes,I have. but i dont understand why the counter show 65, whereas the coins only 19 – Cesario Dec 01 '15 at 03:45
  • 1
    This method isn't magic, so you're going to get some false positives (non-coins labelled as coins), and some false negatives (coins not labelled as coins). It sounds like you have 65 coin labels, and only 19 coins in the image. Try increasing the threshold as Aditya suggested. But the method might not do as well as you hope. You can also apply filtering afterwards to improve your result. – kmac Dec 01 '15 at 04:53

2 Answers2

4

The threshold 0.8 means the match should be at least 80% of template image and the source region of interest. Thus if it is greater than 80%, it is a coin. If you reduce the threshold the false positive results would increase even if it is not a coin.

for pt in zip(*loc[::-1]): is for the points which have values greater than threshold. zip is a container of all such points and it will iterate to all such points and draw rectangle around this closed entity i.e. coins here.

rayryeng
  • 102,964
  • 22
  • 184
  • 193
AdityaIntwala
  • 2,536
  • 1
  • 17
  • 17
  • thanks for the excellent explanation, but I still dont understand why the counter is 65 not 19, when I change that to 1, it shows 0 – Cesario Dec 01 '15 at 03:47
  • You can plot a histogram to see how hits you have in different response ranges. 1 is removing everything, try values between 0.8 and 1. – kmac Dec 01 '15 at 04:56
1

Threshold = 0.8 works according to lightness on the image you are working on. If lights are proper on your image then threshold > 0.8 will work but mostly in camera images brightness varies so lightness > 0.65 can work. To match more points you have to reduce your threshold value.

Nathan Tuggy
  • 2,237
  • 27
  • 30
  • 38