前言
在图像处理与交互式应用中,鼠标操作是不可或缺的一部分。OpenCV 提供了一套强大的鼠标事件处理机制,可以让我们轻松实现图像上的交互式操作。本篇文章将通过一个示例程序,演示如何利用鼠标在图像上绘制矩形,并响应鼠标的左键与右键操作。
功能实现
本示例实现以下功能:
- 左键按下:记录起点。
- 鼠标移动:实时显示矩形。
- 左键抬起:记录终点并绘制最终矩形。
- 右键按下:清除所有绘制内容,恢复原始图像。
- ESC 键:退出程序。
完整代码
import cv2 as cv
import numpy as np
# 加载图像
image = cv.imread('images/greenback.png')
if image is None:
raise FileNotFoundError("图像路径错误,请检查路径是否正确!")
image_bak = image.copy()
# 全局变量
x0, y0, x1, y1 = -1, -1, -1, -1
drawing = False # 标志是否正在绘制
def mouse_draw_callback(event, x, y, flags, param):
"""鼠标回调函数"""
global x0, y0, x1, y1, drawing
# 左键按下:记录起点
if event == cv.EVENT_LBUTTONDOWN:
print("左键按下", x, y)
x0, y0 = x, y
drawing = True # 开始绘制
# 鼠标移动:实时显示矩形
elif event == cv.EVENT_MOUSEMOVE and drawing:
x1, y1 = x, y
# 左键抬起:记录终点并绘制矩形
elif event == cv.EVENT_LBUTTONUP:
print("左键抬起", x, y)
x1, y1 = x, y
if x0 >= 0 and y0 >= 0:
cv.rectangle(image, (x0, y0), (x1, y1), (0, 0, 255), 2)
x0, y0, x1, y1 = -1, -1, -1, -1
drawing = False # 停止绘制
# 右键按下:清空图像
elif event == cv.EVENT_RBUTTONDOWN:
print("右键按下", x, y)
image[:, :, :] = image_bak # 恢复原始图像
def mouse_demo():
"""鼠标操作演示"""
global image, drawing
cv.namedWindow("mouse_demo", cv.WINDOW_AUTOSIZE)
cv.setMouseCallback("mouse_demo", mouse_draw_callback)
while True:
temp_image = image.copy() # 每帧刷新临时图像
if drawing and x0 >= 0 and y0 >= 0: # 如果正在绘制
cv.rectangle(temp_image, (x0, y0), (x1, y1), (0, 255, 0), 2)
cv.imshow("mouse_demo", temp_image)
# 按下 ESC 键退出
if cv.waitKey(1) == 27:
break
cv.destroyAllWindows()
# 调用函数
mouse_demo()
代码详解
图像加载与备份
image = cv.imread('images/greenback.png')
if image is None:
raise FileNotFoundError("图像路径错误,请检查路径是否正确!")
image_bak = image.copy()
cv.imread
:加载图像,确保路径正确。- 备份图像:使用
image.copy()
创建一个副本,用于清除绘制内容时恢复原始图像。
鼠标回调函数
def mouse_draw_callback(event, x, y, flags, param):
OpenCV 鼠标事件回调函数,可响应鼠标的多种操作。参数说明:
event
:鼠标事件类型,例如cv.EVENT_LBUTTONDOWN
(左键按下)。x, y
:鼠标指针在图像上的位置。flags
:鼠标的按键状态。param
:传递给回调函数的额外参数。
左键按下、抬起与鼠标移动
- 左键按下:python复制代码
if event == cv.EVENT_LBUTTONDOWN: x0, y0 = x, y drawing = True
- 记录矩形起点。
- 设置
drawing=True
,标记开始绘制。
- 鼠标移动:python复制代码
elif event == cv.EVENT_MOUSEMOVE and drawing: x1, y1 = x, y
- 更新当前终点坐标
x1, y1
,实时显示矩形。
- 更新当前终点坐标
- 左键抬起:python复制代码
elif event == cv.EVENT_LBUTTONUP: x1, y1 = x, y cv.rectangle(image, (x0, y0), (x1, y1), (0, 0, 255), 2) x0, y0, x1, y1 = -1, -1, -1, -1 drawing = False
- 绘制最终的矩形,颜色为红色。
- 重置坐标与
drawing
状态。
右键清除图像
elif event == cv.EVENT_RBUTTONDOWN:
image[:, :, :] = image_bak
- 恢复
image
为原始备份image_bak
,清除所有绘制内容。
主循环与实时刷新
while True:
temp_image = image.copy()
if drawing and x0 >= 0 and y0 >= 0:
cv.rectangle(temp_image, (x0, y0), (x1, y1), (0, 255, 0), 2)
cv.imshow("mouse_demo", temp_image)
- 每帧刷新临时图像
temp_image
。 - 在主循环中实时绘制未完成的矩形。
© 版权声明
转载请注明出处,并标明原文链接。
本网站尊重知识产权,如有侵权,请及时联系我们删除。
本站所有原创内容仅用于学习和交流目的,未经作者和本站授权不得进行商业使用或盈利行为。
本网站尊重知识产权,如有侵权,请及时联系我们删除。
本站所有原创内容仅用于学习和交流目的,未经作者和本站授权不得进行商业使用或盈利行为。
THE END
暂无评论内容