『OpenCV-Python』滑鼠事件

德育处主任發表於2024-11-20

點贊 + 關注 + 收藏 = 學會了

在使用 OpenCV 進行影像處理時,有時需要與影像進行互動,例如選擇感興趣區域(ROI)、標註關鍵點、調整引數、獲取圖片指定位置的顏色值等。OpenCV 提供了滑鼠事件支援,可以在影像視窗中透過滑鼠實現豐富的互動功能。

推薦 《OpenCV專欄》

用到的方法是 cv2.setMouseCallback(window_name, on_mouse, param=None),用這個方法監聽滑鼠在指定視窗裡做了什麼。

  • window_name:需要繫結滑鼠事件的視窗名稱。
  • on_mouse:回撥函式。在這個函式里可以知道使用者用滑鼠做了什麼操作。
  • param:傳遞給回撥函式的額外引數,可以不傳。也可以傳你需要的內容,比如傳遞影像資料到回撥函式中,讓回撥函式可以訪問或修改影像。

其中,回撥函式(on_mouse)需要按照以下形式定義:

def on_mouse(event, x, y, flags, param):
    # event: 當前的滑鼠事件型別。
    # x, y: 滑鼠事件發生時的座標。
    # flags: 事件相關的附加資訊(按下鍵盤時的修飾鍵狀態,比如按下shift健的同時滑鼠在圖片上有操作)。
    # param: 透過 setMouseCallback 傳遞的額外引數。

OpenCV 提供了多種滑鼠事件(event),以下是常見型別:

列舉值數字值描述
cv2.EVENT_MOUSEMOVE0滑鼠移動
cv2.EVENT_LBUTTONDOWN1滑鼠左鍵按下
cv2.EVENT_RBUTTONDOWN2滑鼠右鍵按下
cv2.EVENT_MBUTTONDOWN3滑鼠中鍵按下
cv2.EVENT_LBUTTONUP4滑鼠左鍵釋放
cv2.EVENT_RBUTTONUP5滑鼠右鍵釋放
cv2.EVENT_MBUTTONUP6滑鼠中鍵釋放
cv2.EVENT_LBUTTONDBLCLK7滑鼠左鍵雙擊
cv2.EVENT_RBUTTONDBLCLK8滑鼠右鍵雙擊
cv2.EVENT_MBUTTONDBLCLK9滑鼠中鍵雙擊
cv2.EVENT_MOUSEWHEEL10滾輪正向滾動(滾輪事件,向上滾動)
cv2.EVENT_MOUSEHWHEEL11滾輪橫向滾動(滾輪事件,水平滾動)

可以透過這些值判斷使用者做了什麼操作。

舉個例子,建立一個 400x400 的黑色背景圖片,然後監聽滑鼠在這個圖片上做過什麼操作。

01_compressed.gif

import cv2
import numpy as np

# 滑鼠回撥事件
def mouse_callback(event, x, y, flags, param):
    print(f"事件:{event} | 座標:x{x}, y{y} | 組合鍵:{flags} | 額外引數: {param}")

# 建立 400x400 黑色背景圖片
img = np.zeros((400, 400, 3), dtype=np.uint8)

# 展示圖片
cv2.imshow("ImgWindow",  img)

# 監聽 ImgWindow 視窗的滑鼠事件
cv2.setMouseCallback("ImgWindow", mouse_callback)

cv2.waitKey()
cv2.destroyAllWindows()

最後的一個引數 param 有什麼用呢?

如果需要透過滑鼠對影像做一些操作,比如框選、標記等操作,可以將圖片傳入滑鼠回撥函式里,在裡面對圖片進行繪製。

舉個例子,當檢測到滑鼠在影像上點選了左鍵,就在影像對應的位置標記一個紅點。

02.gif

import cv2
import numpy as np

# 滑鼠回撥事件
def mouse_callback(event, x, y, flags, param):
    # 左鍵按下時繪製一個點
    if event == cv2.EVENT_LBUTTONDOWN:
        img = param  # 從 param 引數獲取影像
        cv2.circle(img, (x, y), 5, (0, 0, 255), -1)

# 建立 400x400 黑色背景圖片
img = np.zeros((400, 400, 3), dtype=np.uint8)

# 展示圖片
cv2.imshow("ImgWindow",  img)

# 監聽 ImgWindow 視窗的滑鼠事件
cv2.setMouseCallback("ImgWindow", mouse_callback, param=img)

while True:
    cv2.imshow("ImgWindow", img)
    if cv2.waitKey(1) & 0xFF == 27:  # 按 ESC 鍵退出
        break
cv2.destroyAllWindows()

點贊 + 關注 + 收藏 = 學會了

相關文章