1

I need someone to explain to me these four lines of code:

res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)    
threshhold = 0.70
loc = np.where( res >= threshhold)
for pt in zip(*loc[:: -1]):

I kind of know what the first two mean. But the loop part drives me crazy.

  • What zip() does in this situation?
  • Why did we reverse the list
  • what does "*loc" mean? I mean the asteriks
  • Whats pt at all?

Rest of the code (the part that matters):

while True:
    for i in range(4):
        img_gray = cv2.cvtColor(imageGrab(), cv2.COLOR_BGR2GRAY)
        f = str(files[i])
        template = cv2.imread(f, 0)

        w, h = template.shape[:: -1]

        res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)
        threshhold = 0.70
        loc = np.where( res >= threshhold)
        for pt in zip(*loc[:: -1]):

            x=pt[0]
            y=pt[1]
            center_x = (x + 0.5 * w) + 415
            center_y = (y + 0.5 * h) + 287

            pyautogui.click(center_x , center_y)
            time.sleep(4)
            count = count + 1
            break

I put the break at the end because I only want to use the loop once (Do you think there is any better way to do this?)

I will be very thankfull for all the people that answer. You dont have to answer all my questions, if you only know an answer to one then share. Thanks <3

Stasiek
  • 161
  • 2
  • 8

1 Answers1

4

res = cv2.matchTemplate(img_gray, template, cv2.TM_CCOEFF_NORMED)

matchTemplate calculates for every pixel how well the template matches the image at that location. It returns a 2d array with these values. The method you use is TM_CCOEFF_NORMED, the NORMED means the results get normalized, so the values are mapped between 0 and 1. You can display res, the best match will be white. This image is taken from docs here where you can find some more info.

enter image description here

threshhold = 0.70
loc = np.where( res >= threshhold)

np.where returns the indices where the value of res/quality of match is greater or equal than the threshold - which is set at 0.70. The indices correspondent to x and y values of the image. The indices are returned as a tuple of 2 arrays - one for the x, one for y. Nice examples

for pt in zip(*loc[:: -1]):
A few separete thing happen here:
*loc[:: -1] An * allows an arbitrary number of arguments. It is used to unpack the loc-tuple. example
zip(loc[1],loc[0]) does the same as zip(*loc[:: -1])

The reversal of the list seems arbitrary and is not necessary, so long as you account for it in the rest of the code.

for pt in zip()
zip() returns an iterable, an object that can be used to loop over. It creates tuples of the input arguments and using for pt in it returns these one by one. In this case the input is an array of x-values and an array of y-values, so it will return an (x,y) tuple. The tuple is stored in pt.

Try displaying/printing out some of the steps, it will help you understand.

===

if you only want the loop once, I suppose you want the best match. You can use the following:

min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(res)
max_loc will hold the x,y of the best match. (the top left corner)

J.D.
  • 4,511
  • 2
  • 7
  • 20