当前位置: 首页 > news >正文

OpenCV(五):鼠标控制

核心函数

函数定义

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_CTRLKEYCtrl 键按下
cv2.EVENT_FLAG_SHIFTKEYShift 键按下
cv2.EVENT_FLAG_ALTKEYAlt 键按下

回调函数

cv2.setMouseCallback() 的回调函数必须有固定的五个参数。

def onMouse(event, x, y, flags, param):# 在这里处理鼠标事件pass

格式:

参数描述
event发生的鼠标事件类型(一个整数值,对应一个 cv2.EVENT_ 常量)。
x, y鼠标事件发生时的窗口内坐标(像素坐标)。
flags事件发生时按下的组合键/鼠标按钮的标志(一个整数值,对应一个 cv2.EVENT_FLAG_ 常量)。
paramcv2.setMouseCallback() 传递过来的可选参数 (userdata)。

示例

示例1:鼠标绘图工具

实现的功能:

  • 左键拖动:绘制一个绿色的矩形。

  • 右键点击:在点击位置绘制一个红色的圆点。

  • 双击:清除画布。

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 = Trueix, 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) # 红色,半径为 5temp_img = img.copy()# 5. 检查左键双击事件 (用于清除画布)elif event == cv2.EVENT_LBUTTONDBLCLK:# 清空画布 (重新创建一个全黑图像)img[:] = 0temp_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:基于滚轮的缩放/画笔大小控制

一个图像窗口中响应垂直滚轮事件,并打印滚动的方向和幅度。

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) # 增大,最大限制为 100print(f"Scroll Up/Forward: {scroll_amount} (New size: {pen_size})")# 滚轮向后 (向下) 滚动elif scroll_amount < 0:pen_size = max(5, pen_size - 5) # 减小,最小限制为 5print(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()
http://www.dtcms.com/a/457000.html

相关文章:

  • Linux中权限系统
  • 网站域名到期后果四川人力资源考试官网二建
  • python爬虫(五) ---- Pyinstaller打包Python程序为exe文件及遇到的问题
  • 沈阳做网站价格自己做网站要学什么
  • 深入浅出ArkTS:HarmonyOS应用开发的现代化语法解析
  • UVa 204 Robot Crash
  • 2025 完整指南:Gemini 2.5 Computer Use 模型 - AI Agent 界面控制的革命性突破
  • 云南网站建设专业品牌网站域名怎么转
  • Vue项目中如何实现表格选中数据的 Excel 导出
  • 【多模态学习】QA7: GRPO算法?KL散度指的是什么?什么叫做长思维连冷启动?模型退火是什么意思?
  • 无人机_鲁棒性
  • 用自己的计算机做服务器建网站海外模板网站有哪些
  • 检测MODBUS通讯连接 (MODBUS POLL)
  • 数据结构(陈越,何钦铭)期末考试
  • 接口测试-Postman的关联
  • 重庆网站建设快忻科技国外h5汇总网站
  • 解决 LÖVE 引擎 liblua.so.5.4 库缺失问题
  • 从原始数据到实时防御:与 John Hammond 的对话
  • JavaScript事件流:冒泡与捕获的深度解析
  • 避免网站侵权免费域名申请 freenom最新
  • 【C++进阶】---- 红黑树实现
  • 【多模态学习】QA6: 什么是MOE架构?Router Z Loss函数是指什么?
  • 做seo网站公司jsp做网站还
  • 本地部署javaweb项目到Tomcat的三种方法
  • 中秋月满,心却不满
  • VSCode 中 c_cpp_properties.json 配置项 includePath 通配符“**”含义
  • 电商网站建设要多少钱建设银行官方网站入口
  • VS Code配置Python开发环境系列(1)___VScode的安装 ,VScode常用快捷键
  • Redis 集群分片算法
  • 【MYSQL】SQL学习指南:从常见错误到高级函数与正则表达式