鼠标作为画笔
目标
在本次会议中:
学习用 OpenCV 处理鼠标事件
你将学习这些函数:cv.setMouseCallback()
简单例子
这里,我们创建一个简单的程序,在图像的任何位置双击在上面画一个圆。
首先我们创建一个鼠标回调函数,该函数在鼠标事件发生时执行。鼠标事件可以是与鼠标有关的任何内容,比如鼠标左键按下,左键弹起,左键双击等等。所有鼠标事件都给我们提供坐标 (x,y)。通过这个事件和位置,我们能做任何我们喜欢的事情。要列出所有可用事件,在 Python 终端执行以下代码:
import cv2 as cvevents = [i for i in dir(cv) if 'EVENT' in i]print( events )
创建鼠标回调函数是有特定的格式,在任何地方都一样。它仅仅是函数的功能不同。因此我们的鼠标回调函数是做一件事,就是我们双击的地方画圆。所以看下面的代码。代码注释能让你明白。
import numpy as npimport 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(1):cv.imshow('image',img)if cv.waitKey(20) & 0xFF == 27:breakcv.destroyAllWindows()
更多高级例子
现在我们寻求更好的应用。这次,我们通过拖动鼠标绘制矩形或者圆 (取决于我们选的模式),就像在 Paint 程序中一样。因此我们的鼠标回调函数有两个,一个画矩形一个画圆形。这个具体的例子将有助于我们创建和理解交互式程序,像对象跟踪,图像分割等等。
import numpy as npimport cv2 as cvdrawing = False # 如果 True 是鼠标按下mode = True # 如果 True,画矩形,按下‘m’切换到曲线ix,iy = -1,-1# 鼠标回调函数def draw_circle(event,x,y,flags,param):global ix,iy,drawing,modeif event == cv.EVENT_LBUTTONDOWN:drawing = Trueix,iy = x,yelif 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 = Falseif mode == True:cv.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)else:cv.circle(img,(x,y),5,(0,0,255),-1)
下面我们用鼠标回调函数和 OpenCV 窗口绑定。在主循环中,我们应该设置一个‘m‘按健绑定以在矩形和圆形之间切换。
img = np.zeros((512,512,3), np.uint8)cv.namedWindow('image')cv.setMouseCallback('image',draw_circle)while(1):··cv.imshow('image',img)k = cv.waitKey(1) & 0xFFif k == ord('m'):mode = not modeelif k == 27:breakcv.destroyAllWindows()
其他资源
练习
- 在我们的最后一个例子中,我们绘制了填充矩形。 您修改代码以绘制未填充的矩形。
