詳解OpenCV中簡單的鼠標事件處理

談及鼠標事件,就是在觸發鼠標按鈕後程序所做出相應的反應,但是不影響程序的整個線程。這有些像異步處理。鼠標事件響應不會一直等著我們去按而後續程序不執行,這樣會造成阻塞,而是在我們不按鼠標的時候程序也會正常進行,按的時候會調用鼠標的事件響應,這個過程就像程序一邊正常運行一邊等待鼠標響應。

為瞭將鼠標響應和操作畫面進行綁定,我們要創建一個回調函數:

cv2.setMouseCallback函數語法

cv2.setMouseCallback(img,onMouse)

cv2.setMouseCallback函數參數解釋:

img:要綁定畫面的名字

onMouse:響應函數,即當鼠標事件觸發時調用的函數。

示例代碼:

cv2.setMouseCallback('image',draw_circle)

舉個例子:

當我們在畫面內單擊的時候,會回調draw_circle函數,而這個被調用的函數成為響應函數,它的作用是畫一個圓。調用這個函數後,我們就實現瞭畫面與回調函數的綁定。

011-2-鼠標事件

查看所有被支持的鼠標事件:

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

程序顯示的鼠標事件:

['EVENT_FLAG_ALTKEY', 'EVENT_FLAG_CTRLKEY', 'EVENT_FLAG_LBUTTON', 'EVENT_FLAG_MBUTTON', 'EVENT_FLAG_RBUTTON', 'EVENT_FLAG_SHIFTKEY', 'EVENT_LBUTTONDBLCLK', 'EVENT_LBUTTONDOWN', 'EVENT_LBUTTONUP', 'EVENT_MBUTTONDBLCLK', 'EVENT_MBUTTONDOWN', 'EVENT_MBUTTONUP', 'EVENT_MOUSEHWHEEL', 'EVENT_MOUSEMOVE', 'EVENT_MOUSEWHEEL', 'EVENT_RBUTTONDBLCLK', 'EVENT_RBUTTONDOWN', 'EVENT_RBUTTONUP']

 回調函數  

在OpenCV中沒有特定的寫好的回調函數供我們直接使用,這需要我們自己編寫,回調函數的模板如下:

def draw_circle(event,x,y,flags,param):
    if event == cv2.EVENT_LBUTTONDBLCLK:
        cv2.circle(img,(x,y),100,(255,0,0),-1)

函數分析:

代碼第一行:是我們設置的函數名draw_circle以及它的參數,第一個參數event表示在什麼事件下調用這個函數,x ,y可以理解為圖像中鼠標指針所在的像素點的坐標值,後面兩個參數暫時不用理解。

代碼第二行:是事件的判定,如果發出瞭該事件,那麼執行第三行的代碼。

下面我們來通過雙擊鼠標左鍵畫一個圓:

import cv2
import numpy as np
#設置回調函數
def draw_circle(event,x,y,flags,param):
    if event == cv2.EVENT_LBUTTONDBLCLK:
        cv2.circle(img,(x,y),100,(255,0,0),-1)
#創建圖像與窗口並將窗口與回調函數進行綁定
img = np.zeros((500,500,3),np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image',draw_circle)
while(1):
    cv2.imshow('image',img)
    if cv2.waitKey(1)&0xFF == ord('q'):
        break
cv2.destroyAllWindows()

結果:

在通過拖動鼠標畫一個矩形:

import cv2
import numpy as np
#按下鼠標時為True
drawing = False
#當mode為true時繪制矩形,按下m後mode變成false,用來繪制曲線
mode = True
ix,iy=-1,-1
#設置回調函數
def draw_circle(event,x,y,flags,param):
    global ix,iy,drawing,mode
    #當單擊時返回起始位置坐標
    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        ix,iy=x,y
    #當移動鼠標時繪制圖形,event可以查看移動效果,flag檢測是否發生單擊
    elif event == cv2.EVENT_MOUSEMOVE and flags == cv2.EVENT_FLAG_LBUTTON:
        if drawing == True:
            if mode == True:
                cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
            else:
                #繪制圓圈,圓點連成線,3代表筆的粗細
                cv2.circle(img,(x,y),3,(0,255,0),-1)
    #當松開鼠標時停止繪制
    elif event == cv2.EVENT_LBUTTONUP:
        drawing ==False
#創建圖像與窗口並將窗口與回調函數進行綁定
img = np.zeros((500,500,3),np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image',draw_circle)
while(1):
    cv2.imshow('image',img)
    k = cv2.waitKey(1)
    if k == ord('m'):
        mode=not mode
    elif k == ord('q'):
        break
    elif k == ord('r'):
        img = np.zeros((500,500,3),np.uint8)
        cv2.namedWindow('image')
        cv2.setMouseCallback('image',draw_circle)
cv2.destroyAllWindows()
 

結果:

到此這篇關於詳解OpenCV中簡單的鼠標事件處理的文章就介紹到這瞭,更多相關OpenCV鼠標事件處理內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: