Reputation: 69
I am itertively performing operations on a list of images (for image in directory) and need to capture mouse position upon clicking for each separate image. This is not working. I have 2 options: omit the use of cv.namedWindow()/cv.setMouseCallback() or figure out how to use them within/symbiotically with a 'for loop' iterating over images in a directory. Currently, my code is such that a black window appears alongside my images of interest. Only mouse events over that black window are captured, but I want events for the windows displaying the images to be captured.
for image in images:
img = cv.imread(image)
cv.namedWindow("image")
cv.setMouseCallback("image", click)
...
cv.imshow('x',img)
k = cv.waitKey(0) & 0xFF
if k == 27:
cv.destroyAllWindows()
I have tried all combinations of namedWindow and setMouseCallback in and out of the for loop and none work. Does anybody know of a solution? Thanks.
Upvotes: 2
Views: 1886
Reputation: 21233
I worked on a complete example.
I had a path of images containing various formats (.png
, .jpg
, etc.) but only chose to loop over images of .jpg
format.
For every image in the given directory, upon clicking the left mouse button the corresponding point would be printed on the console. Now you can choose to do whatever you want store them in a list, or even write to a .txt
file.
Upon hitting any key other than ESC
key you can iterate over to the next image. The operation stops abruptly when you hit the ESC
key
Here is the code:
import cv2
import numpy as np
import os
path = 'C:/Users/Desktop/Cars/'
def draw_circle(event,x,y,flags,param):
if event == cv2.EVENT_LBUTTONDOWN:
cv2.circle(img, (x, y), 1, (255, 0, 0), -1)
print('Coordinates:', x, y)
if __name__ == '__main__':
for f in os.listdir(path):
if f.endswith('.jpg'):
img = cv2.imread(path + '/' + f, 1)
cv2.namedWindow('image')
cv2.setMouseCallback('image', draw_circle)
cv2.imshow('image', img)
k = cv2.waitKey(0) & 0xFF
if k == 27: #--- hit ESC key to stop abruptly ---
break
cv2.destroyAllWindows()
Upvotes: 1
Reputation: 1367
You can set the mouse callback and then handle whatever it outputs. Precisely, you can make it call a function only if the left mouse button is pressed, just like that:
# Define the function to be called on mouse click
def on_click(event, x, y, flags, param):
# Check if the mouse was actually clicked
if event == cv2.EVENT_LBUTTONDOWN:
# Do something
cv2.destroyAllWindows()
# Show the image
cv2.imshow("image", img)
# Listen to mouse events
cv2.setMouseCallback("image", on_click)
# Wait for action
cv2.waitKey(0)
Upvotes: 1