Im new to coding i was following a multi object detection tut in python and ran in to a error

Viewed 49

I've been looking for answers but i just don't know know how to apply them to my use case yet. hope i can get some help :)

import cv2 as cv
import numpy as np

haystack_img = cv.imread('pokemon_tempv2.png', cv.IMREAD_UNCHANGED)
needle_img = cv.imread('pokestopv4.png', cv.IMREAD_UNCHANGED)

result = cv.matchTemplate(haystack_img, needle_img, cv.TM_SQDIFF_NORMED)
print(result)

threshold = 25
locations = np.where(result <= threshold)
print(locations)

if locations:
    print('Found needle.')

    needle_w = needle_img.shape[1]
    needle_h = needle_img.shape[0]
    line_color = (0, 255, 0)
    line_type = cv.LINE_4

    # Loop over all the locations and draw their rectangle
    for loc in locations:
        # Determine the box positions
        top_left = loc
        bottom_right = (top_left[0] + needle_w, top_left[1] + needle_h)
        # Draw the box
        cv.rectangle(haystack_img, top_left, bottom_right, line_color, line_type)

    cv.imshow('Matches', haystack_img)
    cv.waitKey()
    #cv.imwrite('result.jpg', haystack_img)

else:
    print('Needle not found.')
Error
Traceback (most recent call last):
  File "C:\Users\Toastys\PycharmProjects\PokemonTraining\venv\main.py", line 31, in <module>
    cv.rectangle(haystack_img, top_left, bottom_right, (line_color == 0, 255, 0), (line_type == cv.LINE_4))
cv2.error: OpenCV(4.6.0) :-1: error: (-5:Bad argument) in function 'rectangle'
> Overload resolution failed:
>  - Can't parse 'pt1'. Expected sequence length 2, got 142970
>  - Can't parse 'pt1'. Expected sequence length 2, got 142970
>  - Can't parse 'rec'. Expected sequence length 4, got 142970
>  - Can't parse 'rec'. Expected sequence length 4, got 142970
1 Answers

To make your code run properly I had to do some adjustments. First of them was to switch to grayscale for matching image pattern. Next one was changing the flag in matchTemplate and the threshold for np.where. With this changes done the code finds the right block within other blocks. Notice that in the loop for pY, pX in zip(*locations): you need to transpose locations with zip() to get the right coordinates for drawing the bounding box.

Here the haystack: Blocks

Here the needle: Block

And here the result: Blocks Bbox

import cv2 as cv
import numpy as np

haystack_img = cv.imread('tetris_blocks.png')
haystack_gry = cv.cvtColor(haystack_img, cv.COLOR_BGR2GRAY)
needle_img   = cv.imread('tetris_block.png')
needle_gry   = cv.cvtColor(needle_img  , cv.COLOR_BGR2GRAY)

result = cv.matchTemplate(haystack_gry, needle_gry, cv.TM_CCOEFF_NORMED)
threshold = 0.9
locations = np.where(result >= threshold)

if locations:
    print('Found needle.')
    n_h, n_w = needle_gry.shape
    line_color = (0, 255, 0)
    line_type = cv.LINE_4

    # Loop over all the locations and draw their rectangle
    for pY, pX in zip(*locations):
        cv.rectangle(haystack_img, (pX,pY), (pX+n_w, pY+n_h), line_color, 3)

    cv.imshow(' Needle ',   needle_img)
    cv.imshow('Haystack', haystack_img)
    cv.waitKey()
    cv.destroyAllWindows()

    #cv.imwrite('result.jpg', haystack_img)
else:
    print('Needle not found.')
Related