1

I was testing out OpenCV's mouse callback function with pynput.mouse and I realised the coordinates of the cursor are different. Here is the output from the code below. Does anyone know what the offset is as it does not seem to be consistent in the output

import cv2
cap = cv2.VideoCapture(0)

from pynput.mouse import Controller
mouse = Controller()

def on_mouse(event, x, y, flags, param):
    '''
    Mouse callback function
    '''
    global x1, y1
    if event == cv2.EVENT_MOUSEMOVE:
        x1, y1 = x, y
        print("opencv: ", str((x1, y1)))
        print("pynput: ", str(mouse.position))

cv2.namedWindow("Image", cv2.WND_PROP_FULLSCREEN)
cv2.setWindowProperty("Image", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
cv2.setMouseCallback("Image", on_mouse)

while cap.isOpened():
    success, image = cap.read()

    cv2.imshow("Image", image)

    if cv2.waitKey(1) & 0xFF == 27:
      break


cv2.destroyAllWindows()
cap.release()
  • I think it's because Pynput gives the coordinates to the global screen, and OpenCV uses the resolution of the image used in imshow, even in FullScreen. So if you have for example a 1280x720 image, and a 1920x1080 screen, in the bottom right corner of the screen (1920, 1080) by Pynput, and (1280, 720) by OpenCV. – Jay Jan 12 '23 at 08:34

1 Answers1

2

I just tested my theory, and it seems to be the case.

Small piece of code used:

import cv2
import numpy as np

from pynput.mouse import Controller

mouse = Controller()

f1 = np.zeros((1080, 1920))
f2 = np.zeros((720, 1280))


def on_mouse(event, x, y, flags, param):
    if event == cv2.EVENT_MOUSEMOVE:
        print(f"{param} - opencv: {x, y}")
        print(f"{param} - pynput: {mouse.position}")


cv2.namedWindow("1080x1920", cv2.WND_PROP_FULLSCREEN)
cv2.namedWindow("720x1280", cv2.WND_PROP_FULLSCREEN)
cv2.setWindowProperty("1080x1920", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
cv2.setWindowProperty("720x1280", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)

cv2.setMouseCallback("1080x1920", on_mouse, "1080x1920")
cv2.setMouseCallback("720x1280", on_mouse, "720x1280")

while True:
    cv2.imshow("1080x1920", f1)
    cv2.imshow("720x1280", f2)

    cv2.waitKey()

The results obtained for the bottom right corner:

1080x1920 - opencv: (1919, 1079)
1080x1920 - pynput: (1919, 1079)

720x1280 - opencv: (1279, 719)
720x1280 - pynput: (1919, 1079)
Jay
  • 305
  • 2
  • 11