目标

学习在OpenCV中处理鼠标事件 你将学习这些函数:cv2.setMouseCallback()

简单的演示

在这里,我们创建一个简单的应用程序,无论我们在哪里双击它,都会在图像上绘制一个圆圈。

首先我们创建一个鼠标事件发生时执行的回调函数。鼠标事件可以是任何与鼠标有关的东西,例如左键,左键,左键双击等。它给我们每个鼠标事件的坐标(x,y)。有了这个活动和地点,我们可以做任何我们喜欢的事情。要列出所有可用的事件,请在Python终端中运行以下代码:

# 查看所有被支持的鼠标事件
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((512,512,3), np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image',draw_circle)

while(1):
    cv2.imshow('image',img)
    if cv2.waitKey(20) & 0xFF == 27:
        break
cv2.destroyAllWindows()

更高级的教程

现在我们去更好的应用程序。在这里,我们通过像在Paint应用程序中一样拖动鼠标来绘制矩形或圆形(取决于我们选择的模式)。所以我们的鼠标回调函数有两个部分,一个画矩形,另一个画圆。这个具体的例子对于创建和理解对象跟踪,图像分割等一些交互式应用程序非常有帮助。

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()