ویژگی‌های رابط کاربری در OpenCV

ماوس به عنوان قلم‌مو

۳ دقیقه مطالعهOpenCV 5.xبه‌روزرسانی:

هدف#

  • یادگیری مدیریت رویدادهای ماوس در OpenCV
  • با این تابع آشنا خواهید شد: ()cv.setMouseCallback

دموی ساده#

در اینجا یک برنامه ساده ایجاد می‌کنیم که در هر نقطه‌ای از تصویر که دوبار کلیک کنیم، یک دایره رسم می‌کند.

ابتدا یک تابع بازخوانی ماوس (Mouse Callback Function) ایجاد می‌کنیم که هنگام وقوع یک رویداد ماوس اجرا می‌شود. رویداد ماوس می‌تواند هر عملی مرتبط با ماوس باشد مانند فشردن دکمه چپ، رها کردن دکمه چپ، دوبار کلیک دکمه چپ و غیره. این تابع مختصات (x,y) را برای هر رویداد ماوس در اختیار ما قرار می‌دهد. با داشتن این رویداد و موقعیت آن، می‌توانیم هر کاری که دوست داریم انجام دهیم. برای فهرست کردن تمام رویدادهای موجود، کد زیر را در ترمینال پایتون اجرا کنید:

import cv2 as cv
events = [i for i in dir(cv) if 'EVENT' in i]
print( events )

ایجاد تابع بازخوانی ماوس ساختار مشخصی دارد که در همه جا یکسان است و تنها در کاری که تابع انجام می‌دهد تفاوت دارد. بنابراین تابع بازخوانی ماوس ما یک کار انجام می‌دهد: در جایی که دوبار کلیک می‌کنیم، یک دایره رسم می‌کند. کد زیر را مشاهده کنید. توضیحات درون کامنت‌ها کاملاً گویای کد هستند:

import numpy as np
import cv2 as cv

# mouse callback function
def draw_circle(event,x,y,flags,param):
    if event == cv.EVENT_LBUTTONDBLCLK:
        cv.circle(img,(x,y),100,(255,0,0),-1)

# Create a black image, a window and bind the function to window
img = np.zeros((512,512,3), np.uint8)
cv.namedWindow('image')
cv.setMouseCallback('image',draw_circle)

while(1):
    cv.imshow('image',img)
    if cv.waitKey(20) & 0xFF == 27:
        break
cv.destroyAllWindows()

دموی پیشرفته‌تر#

اکنون به سراغ برنامه‌ای بسیار بهتر می‌رویم. در این برنامه، همانطور که در نرم‌افزار Paint انجام می‌دهیم، با کشیدن ماوس (drag کردن)، یا مستطیل و یا دایره رسم می‌کنیم (بسته به حالتی که انتخاب می‌کنیم). بنابراین تابع بازخوانی ماوس ما دو بخش دارد: یکی برای رسم مستطیل و دیگری برای رسم دایره‌ها. این مثال به طور ویژه در ایجاد و درک برنامه‌های تعاملی مانند ردیابی شیء (Object Tracking)، قطعه‌بندی تصویر (Image Segmentation) و غیره بسیار مفید خواهد بود.

import numpy as np
import cv2 as cv

drawing = False # true if mouse is pressed
mode = True # if True, draw rectangle. Press 'm' to toggle to curve
ix,iy = -1,-1

# mouse callback function
def draw_circle(event,x,y,flags,param):
    global ix,iy,drawing,mode

    if event == cv.EVENT_LBUTTONDOWN:
        drawing = True
        ix,iy = x,y

    elif event == cv.EVENT_MOUSEMOVE:
        if drawing == True:
            if mode == True:
                cv.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
            else:
                cv.circle(img,(x,y),5,(0,0,255),-1)

    elif event == cv.EVENT_LBUTTONUP:
        drawing = False
        if mode == True:
            cv.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
        else:
            cv.circle(img,(x,y),5,(0,0,255),-1)

سپس باید این تابع بازخوانی ماوس را به پنجره OpenCV متصل کنیم. در حلقه اصلی، باید کلید صفحه‌کلید 'm' را مقید کنیم تا بین حالت‌های مستطیل و دایره تغییر وضعیت دهد.

img = np.zeros((512,512,3), np.uint8)
cv.namedWindow('image')
cv.setMouseCallback('image',draw_circle)

while(1):
    cv.imshow('image',img)
    k = cv.waitKey(1) & 0xFF
    if k == ord('m'):
        mode = not mode
    elif k == 27:
        break

cv.destroyAllWindows()

تمرین‌ها#

  1. در مثال قبلی، ما مستطیل توپر رسم کردیم. کد را طوری تغییر دهید که یک مستطیل توخالی رسم کند.