『OpenCV-Python』鼠标事件
**点赞 + 关注 + 收藏 = 学会了** 在使用 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|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() ``` ---  **点赞 + 关注 + 收藏 = 学会了**