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:
- This line executes:
print(f'Define the 4-sided polygon where the sketch resides:')
- We enter the loop
- I step over this line with the debugger:
print(f' Please click on point {i}: ', end='')
- Nothing happens as I step over the line at point 3. No text on the console, nothing.
- 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.
waitKey
seems to run forever. Like it enters its own loop ofwhile 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:
- What happens here? Why isn't waitKey returning in the for loop?
- What can be done to get the desired behaviour?