点赞 + 关注 + 收藏 = 学会了
在使用 OpenCV 进行图像处理时,有时需要与图像进行交互,例如选择感兴趣区域(ROI)、标注关键点、调整参数、获取图片指定位置的颜色值等。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 |
鼠标移动 | |
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()
点赞 + 关注 + 收藏 = 学会了