核心函数
函数定义
            
            
              python
              
              
            
          
          cv2.setMouseCallback(window_name, onMouse [, param])
        这个函数的作用是将一个用户自定义的函数(即回调函数)绑定到一个指定的窗口,当该窗口内发生任何鼠标事件时,OpenCV 就会自动调用这个自定义函数。
参数说明:
| 参数 | 说明 | 
|---|---|
window_name | 
要设置鼠标回调函数的窗口名(需先创建窗口 cv2.namedWindow()) | 
onMouse | 
鼠标事件回调函数,格式为 onMouse(event, x, y, flags, param) | 
param | 
(可选)用户自定义传入的数据,在回调中会被接收 | 
鼠标事件类型(event)
| 常量 | 含义 | 
|---|---|
cv2.EVENT_MOUSEMOVE | 
鼠标移动 | 
cv2.EVENT_LBUTTONDOWN | 
左键按下 | 
cv2.EVENT_LBUTTONUP | 
左键释放 | 
cv2.EVENT_LBUTTONDBLCLK | 
左键双击 | 
cv2.EVENT_RBUTTONDOWN | 
右键按下 | 
cv2.EVENT_RBUTTONUP | 
右键释放 | 
cv2.EVENT_RBUTTONDBLCLK | 
右键双击 | 
cv2.EVENT_MBUTTONDOWN | 
中键按下 | 
cv2.EVENT_MBUTTONUP | 
中键释放 | 
cv2.EVENT_MBUTTONDBLCLK | 
中键双击 | 
cv2.EVENT_MOUSEWHEEL | 
滚轮滚动(正为向上,负为向下) | 
cv2.EVENT_MOUSEHWHEEL | 
水平滚轮滚动 | 
鼠标状态标志(flags)
这些标志指示按下的键或鼠标按钮:
| 常量 | 含义 | 
|---|---|
cv2.EVENT_FLAG_LBUTTON | 
左键按下 | 
cv2.EVENT_FLAG_RBUTTON | 
右键按下 | 
cv2.EVENT_FLAG_MBUTTON | 
中键按下 | 
cv2.EVENT_FLAG_CTRLKEY | 
Ctrl 键按下 | 
cv2.EVENT_FLAG_SHIFTKEY | 
Shift 键按下 | 
cv2.EVENT_FLAG_ALTKEY | 
Alt 键按下 | 
回调函数
cv2.setMouseCallback() 的回调函数必须有固定的五个参数。
            
            
              python
              
              
            
          
          def onMouse(event, x, y, flags, param):
    # 在这里处理鼠标事件
    pass
        格式:
| 参数 | 描述 | 
|---|---|
event | 
发生的鼠标事件类型 (一个整数值,对应一个 cv2.EVENT_ 常量)。 | 
x, y | 
鼠标事件发生时的窗口内坐标(像素坐标)。 | 
flags | 
事件发生时按下的组合键/鼠标按钮 的标志(一个整数值,对应一个 cv2.EVENT_FLAG_ 常量)。 | 
param | 
从 cv2.setMouseCallback() 传递过来的可选参数 (userdata)。 | 
示例
示例1:鼠标绘图工具
实现的功能:
- 
左键拖动:绘制一个绿色的矩形。
 - 
右键点击:在点击位置绘制一个红色的圆点。
 - 
双击:清除画布。
 
            
            
              python
              
              
            
          
          import numpy as np
import cv2
# --- 全局变量 ---
window_name = 'OpenCV Mouse Drawing'
drawing = False # 标记是否正在拖动(按下鼠标左键)
mode = True     # True: 绘制矩形, False: 绘制圆形 (本例中只演示矩形和点)
ix, iy = -1, -1 # 存储鼠标按下时的起始坐标
# 创建一个 512x512 的黑色画布
img = np.zeros((512, 512, 3), np.uint8)
# 复制一份画布用于清除操作
temp_img = img.copy()
# --- 鼠标回调函数 ---
def draw_shape(event, x, y, flags, param):
    global ix, iy, drawing, img, temp_img
    
    # 1. 检查左键按下事件
    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        ix, iy = x, y # 记录起始点
        # 复制当前图像,用于拖动时的预览
        temp_img = img.copy()
    # 2. 检查鼠标移动事件
    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing == True:
            # 实时绘制预览矩形
            # 每次移动都从 temp_img (起始状态) 重新绘制,避免拖影
            img = temp_img.copy() 
            cv2.rectangle(img, (ix, iy), (x, y), (0, 255, 0), 2) # 绿色,线宽为 2
    # 3. 检查左键释放事件
    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        # 绘制最终的实心矩形
        cv2.rectangle(img, (ix, iy), (x, y), (0, 255, 0), -1) # 绿色,-1 表示填充
        # 将最终结果保存到 temp_img,作为下一次操作的起始图
        temp_img = img.copy()
    # 4. 检查右键点击事件
    elif event == cv2.EVENT_RBUTTONDOWN:
        # 绘制一个红色的实心圆点
        cv2.circle(img, (x, y), 5, (0, 0, 255), -1) # 红色,半径为 5
        temp_img = img.copy()
        
    # 5. 检查左键双击事件 (用于清除画布)
    elif event == cv2.EVENT_LBUTTONDBLCLK:
        # 清空画布 (重新创建一个全黑图像)
        img[:] = 0
        temp_img = img.copy()
        print("Canvas Cleared!")
# --- 主程序 ---
# 1. 创建窗口
cv2.namedWindow(window_name)
# 2. 绑定鼠标回调函数
cv2.setMouseCallback(window_name, draw_shape)
print(f"窗口名称:{window_name}")
print("操作说明:")
print(" - 按住鼠标左键拖动:绘制矩形 (松开时定稿)")
print(" - 点击鼠标右键:绘制红色圆点")
print(" - 双击鼠标左键:清空画布")
print(" - 按 ESC 键退出")
while True:
    # 3. 显示图像
    cv2.imshow(window_name, img)
    # 4. 等待按键事件
    # waitKey(20) 保持 GUI 响应性
    k = cv2.waitKey(20) & 0xFF
    
    # 按 ESC 退出
    if k == 27:
        break
# 5. 清理资源
cv2.destroyAllWindows()
        示例2:基于滚轮的缩放/画笔大小控制
一个图像窗口中响应垂直滚轮事件,并打印滚动的方向和幅度。
            
            
              python
              
              
            
          
          import numpy as np
import cv2 as cv
# --- 全局变量 ---
window_name = 'Scroll Wheel Demo'
img = np.zeros((512, 512, 3), np.uint8) + 50 # 512x512 的灰色画布
pen_size = 10 # 初始画笔大小/缩放因子
# 在图像上显示初始信息
cv.putText(img, f'Pen Size: {pen_size}', (50, 50), cv.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 2, cv.LINE_AA)
cv.putText(img, 'Scroll to change Pen Size', (50, 100), cv.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 0), 1, cv.LINE_AA)
cv.putText(img, 'Press any key to exit', (50, 150), cv.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 0), 1, cv.LINE_AA)
# --- 鼠标回调函数 ---
def mouse_callback(event, x, y, flags, param):
    global img, pen_size
    
    # 1. 检测垂直滚轮事件
    if event == cv.EVENT_MOUSEWHEEL:
        # 清空状态显示区域
        cv.rectangle(img, (0, 0), (512, 180), (50, 50, 50), -1) 
        
        # 滚轮信息存储在 flags 中
        scroll_amount = flags
        
        # 滚轮向前 (向上) 滚动
        if scroll_amount > 0:
            pen_size = min(100, pen_size + 5) # 增大,最大限制为 100
            print(f"Scroll Up/Forward: {scroll_amount} (New size: {pen_size})")
        # 滚轮向后 (向下) 滚动
        elif scroll_amount < 0:
            pen_size = max(5, pen_size - 5) # 减小,最小限制为 5
            print(f"Scroll Down/Backward: {scroll_amount} (New size: {pen_size})")
        # 重新绘制状态信息
        cv.putText(img, f'Pen Size: {pen_size}', (50, 50), cv.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 255), 2, cv.LINE_AA)
        cv.putText(img, 'Scroll to change Pen Size', (50, 100), cv.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 0), 1, cv.LINE_AA)
        cv.putText(img, 'Press any key to exit', (50, 150), cv.FONT_HERSHEY_SIMPLEX, 0.7, (255, 255, 0), 1, cv.LINE_AA)
        
    # 2. 演示画笔效果:鼠标移动时,根据 pen_size 绘制圆点
    elif event == cv.EVENT_MOUSEMOVE and flags & cv.EVENT_FLAG_LBUTTON:
        cv.circle(img, (x, y), pen_size // 2, (255, 255, 255), -1) # 根据 pen_size 绘制白色圆点
        
# --- 主程序 ---
# 1. 创建窗口
cv.namedWindow(window_name)
# 2. 绑定鼠标回调函数
cv.setMouseCallback(window_name, mouse_callback)
while True:
    # 3. 显示图像
    cv.imshow(window_name, img)
    # 4. 等待按键,并检查是否按下了 ESC 键
    if cv.waitKey(1) & 0xFF == 27:
        break
# 5. 清理资源
cv.destroyAllWindows()