本文分享内容来自图书《学习OpenCV 4:基于Python的算法实战》,该书内容如下:
第1章 OpenCV快速入门;
第2章 图像读写模块imgcodecs;
第3章 核心库模块core;
第4章 图像处理模块imgproc(一);
第5章 图像处理模块imgproc(二);
第6章 可视化模块highgui;
第7章 视频处理模块videoio;
第8章 视频分析模块video;
第9章 照片处理模块photo;
第10章 2D特征模块features2d;
第11章 相机标定与三维重建模块calib3d;
第12章 传统目标检测模块objdetect;
第13章 机器学习模块ml;
第14章 深度神经网络模块dnn
案例79:键盘操作
OpenCV中提供了键盘操作的函数waitKey,函数定义如下:
retval = waitKey(delay=None)
参数说明如下:
delay,延迟等待的时间,单位为毫秒,设置为时则无限期等待直到键盘操作;
retval,返回操作的按键(返回值)。
函数waitKey无限期地(当参数为0时)等待一个按键事件,或者等待延迟毫秒(当参数为正时)。由于操作系统在切换线程之间有一个最短的时间间隔,因此函数不会完全等待delay毫秒,它至少会等待delay毫秒,这取决于此时计算机上运行的其他内容。它返回被按下的按键的编码,如果在指定的时间过去之前没有按下任何键,则返回-1。
函数waitKey函数是highgui模块中唯一可以获取和处理事件的方法,因此需要定期调用它以进行正常地进行事件处理,除非在处理事件的环境中已经使用了highgui。仅当至少创建了一个highgui窗口且该窗口处于活动状态时,该函数才起作用。如果有几个highgui窗口,其中任何一个都可以处于活动状态。
图像显示函数imshow后必须跟有waitKey函数,否则图像无法正常显示。
waitKey使用的案例代码如下:
import cv2
#读取图像
image = cv2.imread("src.jpg")
#图像显示
cv2.imshow("image", image)
#按键等待
key = cv2.waitKey(0)
print("Press key is:", key)
cv2.destroyWindow("image")
按下按键G,显示窗口关闭,按键按下打印信息如下:
Press key is: 103
案例80:鼠标操作
OpenCV中设置鼠标回调的函数为setMouseCallback,函数定义如下:
setMouseCallback(windowName, onMouse, param=None)
参数说明如下:
windowName,窗口名;
onMouse,鼠标事件回调函数;
param,参数。
setMouseCallback函数的返回值为None。
OpenCV中的鼠标事件可以通过如下的代码查询:
import cv2
events = [ev for ev in dir(cv2) if 'EVENT' in ev]
print( events ) # 将鼠标事件显示出来
鼠标事件打印结果如下:
['EVENT_FLAG_ALTKEY', 'EVENT_FLAG_CTRLKEY', 'EVENT_FLAG_LBUTTON', 'EVENT_FLAG_MBUTTON', 'EVENT_FLAG_RBUTTON', 'EVENT_FLAG_SHIFTKEY', 'EVENT_LBUTTONDBLCLK', 'EVENT_LBUTTONDOWN', 'EVENT_LBUTTONUP', 'EVENT_MBUTTONDBLCLK', 'EVENT_MBUTTONDOWN', 'EVENT_MBUTTONUP', 'EVENT_MOUSEHWHEEL', 'EVENT_MOUSEMOVE', 'EVENT_MOUSEWHEEL', 'EVENT_RBUTTONDBLCLK', 'EVENT_RBUTTONDOWN', 'EVENT_RBUTTONUP']
见6.1节,鼠标事件类型由MouseEventTypes定义,鼠标事件标志由MouseEventFlags定义。
本节案例是通过不同的鼠标操作进行图形绘制,鼠标左键双击可以绘制圆,鼠标左键按下拖动绘制红色线,鼠标右键按下拖动绘制蓝色线,案例代码如下:
import cv2
import numpy as np
#设置鼠标起始点
start_point, end_point= (0,0), (0,0)
#设置鼠标左键和右键按下/抬起标志
lb_down, lb_up, rb_down, rb_up = False, False, False, False
# 鼠标回调函数
def mouse_event(event, x, y, flags, param):
global end_point, start_point, lb_down, lb_up, rb_down, rb_up
# 左键双击
if event == cv2.EVENT_LBUTTONDBLCLK:
cv2.circle(img, (x, y), 100, (0, 255, 0), -1)
# 左键按下
elif event == cv2.EVENT_LBUTTONDOWN:
# 设置鼠标按下的起始点
end_point = (x, y)
start_point = end_point
lb_down = True
# 右键按下
elif event == cv2.EVENT_RBUTTONDOWN:
end_point = (x, y)
start_point = end_point
rb_down = True
# 鼠标移动,绘制线
elif event == cv2.EVENT_MOUSEMOVE:
# 鼠标左键按下绘制红色线
if lb_down:
cv2.line(img, end_point, (x,y), (0, 0, 255), 2, -1)
# 鼠标右键按下绘制蓝色线
if rb_down:
cv2.line(img, end_point, (x, y), (255, 0, 0), 2, -1)
end_point = (x, y)
# 左键释放
elif event == cv2.EVENT_LBUTTONUP:
lb_up = True
lb_down = False
cv2.line(img, end_point, (x,y), (0, 0, 255), 2, -1)
# 右键释放
elif event == cv2.EVENT_RBUTTONUP:
rb_up = True
rb_down = False
cv2.line(img, end_point, (x,y), (255, 0, 0), 2, -1)
# 创建一个黑色的图像,一个窗口,并绑定到窗口的功能
img = np.zeros((512, 512, 3), np.uint8)
cv2.namedWindow('image')
# 设置回调
cv2.setMouseCallback('image', mouse_event)
while (1):
cv2.imshow('image', img)
# 按下Esc键退出
if cv2.waitKey(10) == 27:
break
cv2.destroyAllWindows()
鼠标绘制结果如图6.5所示。
图6.5