0

I have the following code that should let the user select a 4-sided area (not necessarily a rectangle) by clicking on 4 points on an image:

import os
import cv2



FILE_PATH = r'.\img.jpg'
IMAGE_RESIZE_FACTOR = 2

WINDOW_NAME = 'RemoveBG'


img = cv2.imread(FILE_PATH)

print(f'File: "{os.path.abspath(FILE_PATH)}"')

h, w, *_ = img.shape
cv2.imshow(WINDOW_NAME, cv2.resize(img, (w // IMAGE_RESIZE_FACTOR, h // IMAGE_RESIZE_FACTOR)))

print(f'Image size (h x w): {h} x {w}')


def mark_point(event, x, y, flags, param):
    global img
    global marked_points
    if event == cv2.EVENT_LBUTTONDBLCLK:
        x *= IMAGE_RESIZE_FACTOR
        y *= IMAGE_RESIZE_FACTOR

        print(f'({x}, {y})')

        img = cv2.circle(img, (x, y), 100, (0, 0, 0), -1)
        marked_points += [(x, y)]


marked_points = []

cv2.setMouseCallback(WINDOW_NAME, mark_point)


print(f'Define the 4-sided polygon where the sketch resides:')
for i in range(1, 4+1):
    print(f'  Please click on point {i}: ', end='')
    cv2.waitKey()
    cv2.imshow(WINDOW_NAME, cv2.resize(img, (w // IMAGE_RESIZE_FACTOR, h // IMAGE_RESIZE_FACTOR)))


print(marked_points)


cv2.waitKey()
cv2.destroyAllWindows()

The problem I am having is this:

  1. This line executes: print(f'Define the 4-sided polygon where the sketch resides:')
  2. We enter the loop
  3. I step over this line with the debugger: print(f' Please click on point {i}: ', end='')
  4. Nothing happens as I step over the line at point 3. No text on the console, nothing.
  5. I double click on the image, the callback works correctly, now both the print from step 3 and the print from the callback execute at once.
  6. waitKey seems to run forever. Like it enters its own loop of while True: waitKey(), because no matter how many times I click, I do not get to the 2nd iteration of the for loop. My output on the console looks like this:
Image size (h x w): 2048 x 1532
Define the 4-sided polygon where the sketch resides:
  Please click on point 1: (280, 598)
(544, 692)
(794, 902)
(916, 1052)
(1130, 1174)

I am trying to simply get the coordinates of 4 points.

I have tried looking up if there is anything weird in how opencv processes callbacks but the documentation is notoriously vague in details. Also I have tried returning True from the callback as some libraries need you to explicitly say that the event is "consumed" before it will be let go.

My questions are:

  1. What happens here? Why isn't waitKey returning in the for loop?
  2. What can be done to get the desired behaviour?
6
  • you may want to take a look here on how waitkey works Commented Feb 28, 2022 at 11:47
  • also, print(..., end='') will not flush because there's no newline character. you should also pass flush=True to see that text immediately Commented Feb 28, 2022 at 12:11
  • 1
    there is no "infinite loop". you simply don't satisfy the condition for waitKey to return. Commented Feb 28, 2022 at 12:12
  • @ChristophRackwitz so a mouse click is not seen by waitkey as a key press? Commented Feb 28, 2022 at 15:25
  • Yeah wait key doesn't recognize mouse clicks, there is a workaround here which counts mouse clicks with the param and uses that as the while loop. stackoverflow.com/questions/64807196/… Commented Feb 28, 2022 at 15:35

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.