Какими должны быть аргументы cv2.setMouseCallback ()

Я работал над opencv и прошел через cv2.setMouseCallback (). Ниже приведен код для рисования кругов щелчком мыши.
import cv2 import numpy as np

def draw_circle(event,x,y,flags,param):
if event == cv2.EVENT_LBUTTONDBLCLK:
    cv2.circle(image,(x,y),(100,100),(255,0,0),-1)
img = np.zeros((512,512,3), np.uint8)
cv2.namedWindow("image")
cv2.setMouseCallback("image",draw_circle)

while True:
    cv2.imshow("image",image)
    if cv2.waitKey(1) & 0xFF == ord("q"):
        break
cv2.destroyAllWindows()`

пожалуйста, объясни

  1. Как можно вызвать функцию draw_circle без передачи всех его аргументов
  2. в функции пять аргументов, и есть только две переменные, которым можно присвоить значения
  3. какова цель создания cv2. namedWindow ("изображение")

БЛАГОДАРНОСТЬ!


person Muhammad Abdullah    schedule 04.11.2017    source источник
comment
после использования setMouseCallback используемая функция вызывается всякий раз, когда перемещается мышь или используется кнопка. При вызове setMouseCallback вы не ВЫЗЫВАете draw_circle, но вы указываете setMouseCallback, какая функция должна быть вызвана при событии мыши (это называется функцией обратного вызова). С помощью функции namedWindow вы создаете новое окно с этим именем и заголовком.   -  person Micka    schedule 04.11.2017


Ответы (1)


  1. Вы не вызываете draw_circle, openCV вызовет его для вас при событии мыши с правильным событием и координатами, вы просто указываете, какая функция должна быть вызвана для какого окна в setMouseCallback

  2. если вам нужны дополнительные переменные, вы можете отправить их через param

  3. У вас может быть несколько окон с разными действиями мыши, установленными для каждого из них.

Надеюсь, этот пример может быть полезен тем, кто наткнется на:

import cv2
import numpy as np
from math import sqrt

def calc_distance(p1, p2):
    (x1, y1) = p1
    (x2, y2) = p2
    return round(sqrt((x1-x2)**2 + (y1-y2)**2))

# param contains the center and the color of the circle 
def draw_red_circle(event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDBLCLK:
        center = param[0]
        radius = calc_distance((x, y), center)
        cv2.circle(img, center, radius, param[1], 2)


def draw_blue_circle(event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDBLCLK:
        center = (100,100)
        radius = calc_distance((x, y), center)     
        cv2.circle(img, center, radius, (255, 0, 0), 2)

img = np.zeros((512,512,3), np.uint8)

# create 2 windows
cv2.namedWindow("img_red")
cv2.namedWindow("img_blue")

# different doubleClick action for each window
# you can send center and color to draw_red_circle via param
param = [(200,200),(0,0,255)]
cv2.setMouseCallback("img_red", draw_red_circle, param)
cv2.setMouseCallback("img_blue", draw_blue_circle) # param = None


while True:
    # both windows are displaying the same img
    cv2.imshow("img_red", img)
    cv2.imshow("img_blue", img)
    if cv2.waitKey(1) & 0xFF == ord("q"):
        break
cv2.destroyAllWindows()
person Dani    schedule 05.05.2018
comment
Хороший ответ! Спасибо! - person Dude156; 26.05.2020