概述
OpenCV 是一个强大的计算机视觉库,广泛应用于图像处理和视频分析等领域。本文将详细介绍如何使用 OpenCV 实现鼠标事件回调功能,通过鼠标操作在图像上绘制圆圈和矩形。我们将通过两个示例程序来展示这一功能。
环境准备
确保已经安装了 OpenCV 库。可以使用以下命令安装:
pip install opencv-python
示例一:双击鼠标左键绘制圆圈
代码详解
import numpy as np
import cv2 as cv
# 鼠标回调函数
def draw_circle(event, x, y, flags, param):
if event == cv.EVENT_LBUTTONDBLCLK:
cv.circle(img, (x, y), 100, (255, 0, 0), -1)
# 创建一个黑色图像,一个窗口,并绑定函数到窗口
img = np.zeros((512, 512, 3), np.uint8)
cv.namedWindow('image')
cv.setMouseCallback('image', draw_circle)
while True:
cv.imshow('image', img)
if cv.waitKey(20) & 0xFF == 27: # 按下 ESC 键退出
break
cv.destroyAllWindows()
代码解析
1. 导入必要的库
import numpy as np
import cv2 as cv
import numpy as np
:导入 NumPy 库,并将其别名为np
,用于创建和操作数组。import cv2 as cv
:导入 OpenCV 库,并将其别名为cv
,用于图像处理和窗口管理。
2. 定义鼠标回调函数
def draw_circle(event, x, y, flags, param):
if event == cv.EVENT_LBUTTONDBLCLK:
cv.circle(img, (x, y), 100, (255, 0, 0), -1)
def draw_circle(event, x, y, flags, param)
:定义一个鼠标回调函数draw_circle
,参数分别为鼠标事件类型、鼠标位置的 x 和 y 坐标、额外的标志和参数。if event == cv.EVENT_LBUTTONDBLCLK
:检查鼠标事件是否为双击左键。cv.circle(img, (x, y), 100, (255, 0, 0), -1)
:在图像img
上绘制一个蓝色的圆形,圆心为(x, y)
,半径为 100,颜色为蓝色(255, 0, 0)
,填充模式-1
表示填充圆形。
3. 创建一个黑色图像,一个窗口,并绑定函数到窗口
img = np.zeros((512, 512, 3), np.uint8)
cv.namedWindow('image')
cv.setMouseCallback('image', draw_circle)
img = np.zeros((512, 512, 3), np.uint8)
:创建一个 512x512 的黑色图像,数据类型为无符号 8 位整数。cv.namedWindow('image')
:创建一个名为image
的窗口。cv.setMouseCallback('image', draw_circle)
:将鼠标回调函数draw_circle
绑定到窗口image
。
4. 主循环
while True:
cv.imshow('image', img)
if cv.waitKey(20) & 0xFF == 27: # 按下 ESC 键退出
break
cv.destroyAllWindows()
while True
:进入无限循环,持续显示图像。cv.imshow('image', img)
:在窗口image
中显示图像img
。if cv.waitKey(20) & 0xFF == 27
:等待 20 毫秒,如果按下 ESC 键(ASCII 值为 27),则退出循环。cv.destroyAllWindows()
:关闭所有 OpenCV 窗口。
示例二:拖动鼠标绘制矩形和圆圈
代码详解
import numpy as np
import cv2 as cv
drawing = False # true if mouse is pressed
mode = True # if True, draw rectangle. Press 'm' to toggle to curve
ix, iy = -1, -1
# 鼠标回调函数
def draw_circle(event, x, y, flags, param):
global ix, iy, drawing, mode
if event == cv.EVENT_LBUTTONDOWN:
drawing = True
ix, iy = x, y
elif event == cv.EVENT_MOUSEMOVE:
if drawing == True:
if mode == True:
cv.rectangle(img, (ix, iy), (x, y), (0, 255, 0), -1)
else:
cv.circle(img, (x, y), 5, (0, 0, 255), -1)
elif event == cv.EVENT_LBUTTONUP:
drawing = False
if mode == True:
cv.rectangle(img, (ix, iy), (x, y), (0, 255, 0), -1)
else:
cv.circle(img, (x, y), 5, (0, 0, 255), -1)
img = np.zeros((512, 512, 3), np.uint8)
cv.namedWindow('image')
cv.setMouseCallback('image', draw_circle)
while True:
cv.imshow('image', img)
k = cv.waitKey(1) & 0xFF
if k == ord('m'):
mode = not mode
elif k == 27:
break
cv.destroyAllWindows()
代码解析
1. 导入必要的库
import numpy as np
import cv2 as cv
import numpy as np
:导入 NumPy 库,并将其别名为np
,用于创建和操作数组。import cv2 as cv
:导入 OpenCV 库,并将其别名为cv
,用于图像处理和窗口管理。
2. 初始化变量
drawing = False # true if mouse is pressed
mode = True # if True, draw rectangle. Press 'm' to toggle to curve
ix, iy = -1, -1
drawing = False
:布尔变量,表示鼠标是否按下。mode = True
:布尔变量,表示当前绘制模式,True 为绘制矩形,False 为绘制圆圈。ix, iy = -1, -1
:初始化鼠标按下时的坐标。
3. 定义鼠标回调函数
def draw_circle(event, x, y, flags, param):
global ix, iy, drawing, mode
if event == cv.EVENT_LBUTTONDOWN:
drawing = True
ix, iy = x, y
elif event == cv.EVENT_MOUSEMOVE:
if drawing == True:
if mode == True:
cv.rectangle(img, (ix, iy), (x, y), (0, 255, 0), -1)
else:
cv.circle(img, (x, y), 5, (0, 0, 255), -1)
elif event == cv.EVENT_LBUTTONUP:
drawing = False
if mode == True:
cv.rectangle(img, (ix, iy), (x, y), (0, 255, 0), -1)
else:
cv.circle(img, (x, y), 5, (0, 0, 255), -1)
def draw_circle(event, x, y, flags, param)
:定义一个鼠标回调函数draw_circle
,参数分别为鼠标事件类型、鼠标位置的 x 和 y 坐标、额外的标志和参数。global ix, iy, drawing, mode
:声明全局变量。if event == cv.EVENT_LBUTTONDOWN
:检查鼠标事件是否为左键按下,如果是,则设置drawing
为True
并记录鼠标按下时的坐标。elif event == cv.EVENT_MOUSEMOVE
:检查鼠标事件是否为移动,如果是且drawing
为True
,则根据当前模式绘制矩形或圆圈。elif event == cv.EVENT_LBUTTONUP
:检查鼠标事件是否为左键松开,如果是,则设置drawing
为False
并完成绘制。
4. 创建一个黑色图像,一个窗口,并绑定函数到窗口
img = np.zeros((512, 512, 3), np.uint8)
cv.namedWindow('image')
cv.setMouseCallback('image', draw_circle)
img = np.zeros((512, 512, 3), np.uint8)
:创建一个 512x512 的黑色图像,数据类型为无符号 8 位整数。cv.namedWindow('image')
:创建一个名为image
的窗口。cv.setMouseCallback('image', draw_circle)
:将鼠标回调函数draw_circle
绑定到窗口image
。
5. 主循环
while True:
cv.imshow('image', img)
k = cv.waitKey(1) & 0xFF
if k == ord('m'):
mode = not mode
elif k == 27:
break
cv.destroyAllWindows()
while True
:进入无限循环,持续显示图像。cv.imshow('image', img)
:在窗口image
中显示图像img
。k = cv.waitKey(1) & 0xFF
:等待 1 毫秒,获取按键值。if k == ord('m')
:如果按下 'm' 键,则切换绘制模式。elif k == 27
:如果按下 ESC 键(ASCII 值为 27),则退出循环。cv.destroyAllWindows()
:关闭所有 OpenCV 窗口。
总结
本文详细介绍了如何使用 OpenCV 实现鼠标事件回调功能,通过鼠标操作在图像上绘制圆圈和矩形。通过理解这些基本概念和技术,我们可以更加灵活地在图像处理和交互式应用程序中应用 OpenCV。希望本文能帮助你在实际项目中更好地理解和应用这些技术。