OpenCV鼠标事件处理
代码骑士 人气:0谈及鼠标事件,就是在触发鼠标按钮后程序所做出相应的反应,但是不影响程序的整个线程。这有些像异步处理。鼠标事件响应不会一直等着我们去按而后续程序不执行,这样会造成阻塞,而是在我们不按鼠标的时候程序也会正常进行,按的时候会调用鼠标的事件响应,这个过程就像程序一边正常运行一边等待鼠标响应。
为了将鼠标响应和操作画面进行绑定,我们要创建一个回调函数:
cv2.setMouseCallback函数语法
cv2.setMouseCallback(img,onMouse)
cv2.setMouseCallback函数参数解释:
img
:要绑定画面的名字
onMouse
:响应函数,即当鼠标事件触发时调用的函数。
示例代码:
cv2.setMouseCallback('image',draw_circle)
举个例子:
当我们在画面内单击的时候,会回调draw_circle函数,而这个被调用的函数成为响应函数,它的作用是画一个圆。调用这个函数后,我们就实现了画面与回调函数的绑定。
011-2-鼠标事件
查看所有被支持的鼠标事件:
import cv2 events = [i for i in dir(cv2) if 'EVENT' in i] 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']
回调函数
在OpenCV中没有特定的写好的回调函数供我们直接使用,这需要我们自己编写,回调函数的模板如下:
def draw_circle(event,x,y,flags,param): if event == cv2.EVENT_LBUTTONDBLCLK: cv2.circle(img,(x,y),100,(255,0,0),-1)
函数分析:
代码第一行:是我们设置的函数名draw_circle以及它的参数,第一个参数event表示在什么事件下调用这个函数,x ,y可以理解为图像中鼠标指针所在的像素点的坐标值,后面两个参数暂时不用理解。
代码第二行:是事件的判定,如果发出了该事件,那么执行第三行的代码。
下面我们来通过双击鼠标左键画一个圆:
import cv2 import numpy as np #设置回调函数 def draw_circle(event,x,y,flags,param): if event == cv2.EVENT_LBUTTONDBLCLK: cv2.circle(img,(x,y),100,(255,0,0),-1) #创建图像与窗口并将窗口与回调函数进行绑定 img = np.zeros((500,500,3),np.uint8) cv2.namedWindow('image') cv2.setMouseCallback('image',draw_circle) while(1): cv2.imshow('image',img) if cv2.waitKey(1)&0xFF == ord('q'): break cv2.destroyAllWindows()
结果:
在通过拖动鼠标画一个矩形:
import cv2 import numpy as np #按下鼠标时为True drawing = False #当mode为true时绘制矩形,按下m后mode变成false,用来绘制曲线 mode = True ix,iy=-1,-1 #设置回调函数 def draw_circle(event,x,y,flags,param): global ix,iy,drawing,mode #当单击时返回起始位置坐标 if event == cv2.EVENT_LBUTTONDOWN: drawing = True ix,iy=x,y #当移动鼠标时绘制图形,event可以查看移动效果,flag检测是否发生单击 elif event == cv2.EVENT_MOUSEMOVE and flags == cv2.EVENT_FLAG_LBUTTON: if drawing == True: if mode == True: cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),-1) else: #绘制圆圈,圆点连成线,3代表笔的粗细 cv2.circle(img,(x,y),3,(0,255,0),-1) #当松开鼠标时停止绘制 elif event == cv2.EVENT_LBUTTONUP: drawing ==False #创建图像与窗口并将窗口与回调函数进行绑定 img = np.zeros((500,500,3),np.uint8) cv2.namedWindow('image') cv2.setMouseCallback('image',draw_circle) while(1): cv2.imshow('image',img) k = cv2.waitKey(1) if k == ord('m'): mode=not mode elif k == ord('q'): break elif k == ord('r'): img = np.zeros((500,500,3),np.uint8) cv2.namedWindow('image') cv2.setMouseCallback('image',draw_circle) cv2.destroyAllWindows()
结果:
加载全部内容