准备工作

  使用工具:Python3.5 涉及包:cv2 numpy  

涉及函数

  函数:cv2.setMouseCallback()  

任务开始

  简单的程序,在图片上双击过的位置绘制一个圆圈  

  任务1.创建鼠标事件回调函数,当鼠标事件发生时就会被执行。

  比如左键按下,松开,左键双击等。可以通过鼠标事件获得相对应的图片上的坐标,根据这些信息可以做想做的事。所有鼠标事件回调函数都有一个统一的格式,不同的地方是被调用后的功能。  
#查看所有被支持的鼠标事件
import cv2
events = [i for i in dir(cv2) if 'EVENT' in i]
print (events)
  功能实现  
import cv2
import numpy as np

# mouse callback function

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'):#按q键退出
        break
cv2.destroyAllWindows()
 

关于回调函数

  回调函数使我们自己def的,现在我def一个回调函数:  
def OnMouse(event,x,y,flags,param):
  Event 有以下这些选择:  
EVENT_MOUSEMOVE 0            #滑动
EVENT_LBUTTONDOWN 1          #左键点击
EVENT_RBUTTONDOWN 2          #右键点击
EVENT_MBUTTONDOWN 3          #中键点击
EVENT_LBUTTONUP 4            #左键放开
EVENT_RBUTTONUP 5            #右键放开
EVENT_MBUTTONUP 6            #中键放开
EVENT_LBUTTONDBLCLK 7        #左键双击
EVENT_RBUTTONDBLCLK 8        #右键双击
EVENT_MBUTTONDBLCLK 9        #中键双击
  x,y,代表鼠标位于窗口的(x,y)坐标位置,   flags,代表鼠标的拖拽事件,以及键盘鼠标联合事件,flag有以下几个方法:  
EVENT_FLAG_LBUTTON 1       #左鍵拖曳  
EVENT_FLAG_RBUTTON 2       #右鍵拖曳  
EVENT_FLAG_MBUTTON 4       #中鍵拖曳  
EVENT_FLAG_CTRLKEY 8       #(8~15)按Ctrl不放事件  
EVENT_FLAG_SHIFTKEY 16     #(16~31)按Shift不放事件  
EVENT_FLAG_ALTKEY 32       #(32~39)按Alt不放事件  
 

关于cv2.setMouseCallback()函数

 
cv2.setMouseCallback('image',OnMouse)
第一个参数为要设置的窗口,然后第二个参数是回调函数
 

任务2 现在我们根据上面的函数写点高级点♂的程序

  根据我们选择的模式在拖动鼠标时绘制矩形。所以回调函数包含两个部分。  
import cv2
import numpy as np
#当鼠标按下时为True
drawing = False
#如果mode为true时绘制矩形,按下'm'变成绘制曲线
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,0,255),-1)
              
    #当鼠标松开时停止绘图
    elif event ==cv2.EVENT_LBUTTONUP:
        drawing == False

#下面把回调函数与OpenCV窗口关联在一起,在主循环中将'm'键与模式转换绑定在一起

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
cv2.destroyAllWindows()
 

总结

(本系列每周不定期更新,谢谢大家支持!)