目标:
学习函数cv2.setMouseCallback()
setMouseCallback(windowName, onMouse, param=None)第一个参数是绑定的窗口,第二个参数是回调函数。
7.1简单演示
这里我们来创建一个简单的程序,它会在图片上你双击过的位置绘制一个
圆。首先我们来创建一个鼠标事件回调函数,鼠标事件发生时它就会被执行。
鼠标事件可以是鼠标上的任何动作,比如左键按下,左键松开,左键双击等。
我们可以通过鼠标事件获得与鼠标对应的图片上的坐标。根据这些信息我们可
以做任何我们想做的事。你可以通过执行下列代码查看所有被支持的鼠标事件。
importcv2events=[iforiindir(cv2) if'EVENT'ini] print(events)
下表为所有支持的鼠标事件
EVENT |
鼠标事件 |
CV_EVENT_MOUSEMOVE |
滑动 |
CV_EVENT_LBUTTONDOWN |
左键点击 |
CV_EVENT_RBUTTONDOWN |
右键点击 |
CV_EVENT_MBUTTONDOWN |
中键点击 |
CV_EVENT_LBUTTONUP |
左键放开 |
CV_EVENT_RBUTTONUP |
右键放开 |
CV_EVENT_MBUTTONUP |
中键放开 |
CV_EVENT_LBUTTONDBLCLK |
左键双击 |
CV_EVENT_RBUTTONDBLCLK |
右键双击 |
CV_EVENT_MBUTTONDBLCLK |
中键双击 |
FLAGS |
|
CV_EVENT_FLAG_LBUTTON |
左键拖拽 |
CV_EVENT_FLAG_RBUTTON |
右键拖拽 |
CV_EVENT_FLAG_MBUTTON |
中键拖拽 |
CV_EVENT_FLAG_CTRLKEY |
按Ctrl不放事件 |
CV_EVENT_FLAG_SHIFTKEY |
按shift不放事件 |
CV_EVENT_FLAG_ALTKEY |
按Alt不放事件 |
所有的鼠标事件回调函数都有一个统一的格式,它们所不同的地方仅仅是
被调用后的功能。下面代码的鼠标事件回调函数只做了一件事:在双击过的地方绘
制一个圆。
importcv2importnumpyasnp# 创建回调函数defdraw_circle(event, x, y, flags, param): ifevent==cv2.EVENT_LBUTTONDBLCLK: cv2.circle(img, (x, y), 45, (255, 0, 0), -1) # 创建图像与窗口并将窗口与回调函数绑定 img=np.zeros((512, 512, 3), np.uint8) cv2.namedWindow('image') cv2.setMouseCallback('image', draw_circle) whileTrue: cv2.imshow('image', img) ifcv2.waitKey(20) &0xFF==27: # 按ESC退出breakcv2.destroyAllWindows()
7.2 高级一点的示例
现在我们来创建一个更好的程序。这次我们的程序要完成的任务是根据我
们选择的模式在拖动鼠标时绘制矩形或者是圆圈(就像画图程序中一样)。所以
我们的回调函数包含两部分,一部分画矩形,一部分画圆。
importcv2importnumpyasnp# 当鼠标按下是变为TRUEdrawing=False# mode为TRUE时绘制矩形,按下‘m’时绘制曲线,曲线有很多个小圆组成,圆的半径决定曲线的粗细mode=True# 矩阵的起始坐标ix, iy=-1, -1defdraw_circle(event, x, y, flags, param): globaldrawing, mode, ix, iy# 当按下左键时返回起始坐标ifevent==cv2.EVENT_LBUTTONDOWN: drawing=Trueix, iy=x, y# 当按下左键并拖动时绘制图形.event查看鼠标的移动,flags查看鼠标的按动elifevent==cv2.EVENT_MOUSEMOVEandflags==cv2.EVENT_FLAG_LBUTTON: ifdrawing: ifmode: cv2.rectangle(img, (ix, iy), (x, y), (255, 255, 0), -1, cv2.LINE_AA) else: cv2.circle(img, (x, y), 5, (0, 0, 255), -1, cv2.LINE_AA) # 当松开鼠标时停止绘制图形elifevent==cv2.EVENT_LBUTTONUP: drawing=Falseimg=np.zeros((512, 512, 3), np.uint8) cv2.namedWindow("img") cv2.setMouseCallback('img', draw_circle) whileTrue: cv2.imshow('img', img) k=cv2.waitKey(1) &0xFFifk==27: breakelifk==ord('m'): mode=notmodecv2.destroyAllWindows()