本任务要求结合图形绘制的知识,基于龙芯平台,利用OpenCV实现鼠标事件的交互与响应,完成鼠标操作的综合实验。
在使用OpenCV实现计算机视觉算法的过程中,通常需要大量使用highgui模块进行一些交互式的操作,如鼠标事件监听或者滑块交互操作。这些操作需要在OpenCV中通过响应函数并结合回调函数来实现。
OpenCV提供了鼠标事件响应函数,程序调用鼠标事件响应函数之后,会一直监听鼠标动作,一旦监听到新的鼠标事件发生,就会通过调用回调函数指针onMouse所指向的函数,实现鼠标动作对应的功能。因此,鼠标事件响应函数在程序中是一直运行的,但鼠标事件响应函数本身并不直接实现某个功能,而通过onMouse回调函数指针调用回调函数间接实现具体的功能。鼠标回调函数的基本格式如下(mouseCallback是指定义的函数的名称)。
def mouseCallback(event, x, y, flags, param)
参数如下。
● event:指定调用时传递给函数的鼠标事件对象。
● x、y:指定鼠标事件触发时,鼠标指针在窗口中的坐标。
● flags:指定鼠标事件触发时,鼠标或键盘按键的具体操作,一般可以设置为以下常量。
√ cv2.EVENT_LBUTTONDBLCLK:双击鼠标左键。
√ cv2.EVENT_LBUTTONDOWN:按下鼠标左键。
√ cv2.EVENT_LBUTTONUP:释放鼠标左键。
√ cv2.EVENT_MBUTTONDBLCLK:双击鼠标中键。
√ cv2.EVENT_MBUTTONDOWN:按下鼠标中键。
√ cv2.EVENT_MBUTTONUP:释放鼠标中键。
√ cv2.EVENT_MOUSEHWHEEL:滚动鼠标中键(正值、负值分别表示向左、向右滚动)。
√ cv2.EVENT_MOUSEMOVE:鼠标移动。
√ cv2.EVENT_MOUSEWHEEL:滚动鼠标中键(正值、负值分别表示向前、向后滚动)。
√ cv2.EVENT_RBUTTONDBLCLK:双击鼠标右键。
√ cv2.EVENT_RBUTTONDOWN:按鼠标右键。
√ cv2.EVENT_RBUTTONUP:释放鼠标右键。
√ cv2.EVENT_FLAG_ALTKEY:按Alt键。
√ cv2.EVENT_FLAG_CTRLKEY:按Ctrl键。
√ cv2.EVENT_FLAG_LBUTTON:按住鼠标左键拖动。
√ cv2.EVENT_FLAG_MBUTTON:按住鼠标中键拖动。
√ cv2.EVENT_FLAG_RBUTTON:按住鼠标右键拖动。
√ cv2.EVENT_FLAG_SHIFTKEY:按Shift键。
● param:指定传递给回调函数的其他数据。
setMouseCallback()函数用于为图像窗口绑定鼠标事件回调函数,其基本格式如下。
cv2.setMouseCallback(wname, mouseCallback)
参数如下。
● wname:指定图像窗口的名称。
● mouseCallback:指定鼠标事件回调函数的名称。
以下是使用OpenCV接口实现鼠标事件的交互与响应的代码。
# 定义绘制矩形的函数 import cv2 as cv import numpy as np ox = 0 oy = 0 sx = 0 sy = 0 def draw_rectangle(event, x, y, flags, param): global img global ox, oy, sx, sy if event == cv.EVENT_LBUTTONDBLCLK: img = np.ones((500, 500, 3), np.uint8) * 100 elif event != cv.EVENT_MOUSEMOVE and flags == cv.EVENT_FLAG_LBUTTON: sx, sy = x, y ox, oy = x, y elif event == cv.EVENT_MOUSEMOVE and flags == cv.EVENT_FLAG_LBUTTON: cv.line(img, (ox, oy), (x, y), (255, 255, 255), 3, cv.LINE_AA) ox, oy = x, y elif flags != cv.EVENT_FLAG_LBUTTON and event != cv.EVENT_MOUSEMOVE: cv.rectangle(img, (sx, sy), (x, y), (255, 0, 255), 3, cv.LINE_AA) # 创建窗体,绑定监听回调函数 cv.namedWindow("image") cv.setMouseCallback('image', draw_rectangle) # 创建矩阵图像 img = np.ones((500, 500, 3), np.uint8) while True: cv.imshow("image", img) k = cv.waitKey(25) & 0xFF if chr(k) == 'q': break
鼠标事件的交互与响应结果如图1-6所示。
▲图1-6 鼠标事件的交互与响应结果