點贊 + 關注 + 收藏 = 學會了
在使用 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_MOUSEMOVE |
0 | 鼠標移動 |
cv2.EVENT_LBUTTONDOWN |
1 | 鼠標左鍵按下 |
cv2.EVENT_RBUTTONDOWN |
2 | 鼠標右鍵按下 |
cv2.EVENT_MBUTTONDOWN |
3 | 鼠標中鍵按下 |
cv2.EVENT_LBUTTONUP |
4 | 鼠標左鍵釋放 |
cv2.EVENT_RBUTTONUP |
5 | 鼠標右鍵釋放 |
cv2.EVENT_MBUTTONUP |
6 | 鼠標中鍵釋放 |
cv2.EVENT_LBUTTONDBLCLK |
7 | 鼠標左鍵雙擊 |
cv2.EVENT_RBUTTONDBLCLK |
8 | 鼠標右鍵雙擊 |
cv2.EVENT_MBUTTONDBLCLK |
9 | 鼠標中鍵雙擊 |
cv2.EVENT_MOUSEWHEEL |
10 | 滾輪正向滾動(滾輪事件,向上滾動) |
cv2.EVENT_MOUSEHWHEEL |
11 | 滾輪橫向滾動(滾輪事件,水平滾動) |
可以通過這些值判斷用户做了什麼操作。
舉個例子,創建一個 400x400 的黑色背景圖片,然後監聽鼠標在這個圖片上做過什麼操作。
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 有什麼用呢?
如果需要通過鼠標對圖像做一些操作,比如框選、標記等操作,可以將圖片傳入鼠標回調函數裏,在裏面對圖片進行繪製。
舉個例子,當檢測到鼠標在圖像上點擊了左鍵,就在圖像對應的位置標記一個紅點。
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()
點贊 + 關注 + 收藏 = 學會了