Why is my Y co-ordinate being drawn in the wrong location?

I’ve been using cv.rectangle to draw rectangles around the correct needle_img I’ve tried to swap to drawing crosses with cv.MARKER_CROSS

I’m storing (x, y, w, h) in an array.

Since swapping my method I’m getting very odd results.

Image one has correctly placed green rectangles on the arrows. In image two the crosses have been drawn in a diagonal line that intersects one image.

haystack_img = cv.imread('haystack.jpg', cv.IMREAD_UNCHANGED)
needle_img = cv.imread('needle.jpg', cv.IMREAD_UNCHANGED)
    
needle_w = needle_img.shape[1]
needle_h = needle_img.shape[0]

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

threshold = 0.22
locations = np.where(result <= threshold)
locations = list(zip(*locations[::-1]))

rectangles = []
for loc in locations:
    rect = [int(loc[0]), int(loc[1]), needle_w, needle_h]
    rectangles.append(rect)
    rectangles.append(rect)

rectangles, weights = cv.groupRectangles(rectangles, 1, 0.5)

if len(rectangles):
    print('Found Arrow.')

    line_color = (0, 255, 0)
    line_type = cv.LINE_4

# need to loop over all the locations and draw rectangles
    for (x, y, w, h) in rectangles:
        # determine the box positions
        top_left = (x, y)
        bottom_right = (x + w, y + h)
        # draw the box
        cv.rectangle(haystack_img, top_left, bottom_right, line_color, line_type)
else:
    print('No Arrows Found.')

cv.imshow('Matches', haystack_img)

I’m changing the for loop from the above to the below:

 for (x, y, w, h) in rectangles:
    center_x = x + int(w/2)
    center_y = x + int(h/2)
    cv.drawMarker(haystack_img, (center_x, center_y), marker_color, marker_type)

And defining marker_color and marker_type above the loop below line_type

marker_color = (255, 0, 255)
marker_type = cv.MARKER_CROSS

Both are still returning the same array values so it’s finding the correct images, it’s just drawing them oddly.

[[ 502  805   17   15]
 [ 632  805   17   15]
 [ 796  805   17   15]
 [ 912  805   17   15]
 [1072  805   17   15]]
Found Arrow.

And.

[[ 502  805   17   15]
 [ 632  805   17   15]
 [ 796  805   17   15]
 [ 912  805   17   15]
 [1072  805   17   15]]
Found Arrow.

I’d like to understand why they aren’t being drawn correctly rather than someone just fixing for me if possible! Many thanks!

enter image description here

enter image description here

Answer

Your center_y line is using the x value!

I guess as a more helpful answer for learning. Well established library functions are rarely at fault when something goes wrong (though it’s always possible of course and OpenCV does some unintuitive stuff sometimes). The crosshairs are being drawn correctly, but in the wrong place, so the draw function is probably being called correctly.

You might notice that they’re being drawn in about the right x position, but to be honest I didn’t notice that while looking through the code. It’s easy to slide past a small typo like that, especially if you’re the one who wrote the code. A surefire way to catch errors like this is to just print out all the variables and check through them by hand to see if they look weird. This takes a long time, but has a good chance of forcing the bug out into the open.

Leave a Reply

Your email address will not be published. Required fields are marked *