點贊 + 關注 + 收藏 = 學會了
在使用 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()
點贊 + 關注 + 收藏 = 學會了