鼠标事件

首先,我们将创建一个简单的小demo,通过在图像上双击鼠标然后在点击地点绘制一个圆。

我们需要创建一个鼠标的回调函数(callback),这个函数会鼠标事件触发的时候被调用。鼠标事件绑定到所有的鼠标操作上,如左键按下、右键按下、左键抬起、右键抬起、左键双击等等。系统可以捕获到发生鼠标事件的位置坐标,通过这个坐标我们可以做出相应的定位和处理(坐标以及事件类型都会以参数形式传递到回调函数中)。以下代码可以列出所有可用的事件。

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']

创建鼠标回调函数必须以一种指定的格式。这里我们的回调函数仅在双击处画一个圆,代码如下

import cv2
import numpy as np

#鼠标回调函数,双击画圆
def draw_circle(event, x, y, flags, param):
    bg = param['background']
    if event == cv2.EVENT_LBUTTONDBLCLK:
        cv2.circle(bg, (x, y), 100, (255, 0, 0), -1)

#背景图
img = np.zeros((512, 512, 3), np.uint8)
cv2.namedWindow('circle', cv2.WINDOW_NORMAL)
cv2.setMouseCallback('circle', draw_circle, {'background': img})

while True:
    cv2.imshow('circle', img)
    #esc键推出
    if cv2.waitKey(20) == 27:
        break
cv2.destroyAllWindows()

效果如下所示:

复杂的演示

现在我们做一个稍微复杂一点的demo。我们需要画矩形和圆(具体画什么取决于我们拖拽鼠标的方式)。所以我们的callback中有两个部分,一个是画矩形,一个是画圆。这个demo有助于我们理解一些交互应用,如对象追踪,图像分割等。

import cv2
import numpy as np

#鼠标回调函数
def draw_callback(event,x,y,flags,param):
    global bg, drawing, mode, ix ,iy
    if event == cv2.EVENT_MBUTTONDOWN:
        drawing = True
        ix, iy = x, y
    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing == True:
            if mode == True:
                cv2.rectangle(bg, (ix, iy), (x, y), (0, 255, 0), -1)
            else:
                cv2.circle(bg, (x, y), 5, (0, 0, 255), -1)
    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        if mode == True:
            cv2.rectangle(bg, (ix, iy), (x, y), (0, 255, 0), -1)
        else:
            cv2.circle(bg, (x, y), 5, (0, 0, 255), -1)

if __name__ == '__main__':
    drawing = False
    mode = True
    ix, iy = -1,-1
    bg = np.ones([512, 512, 3], np.uint8) * 255
    cv2.namedWindow('mouse')
    cv2.setMouseCallback('mouse', draw_callback)
    while True:
        cv2.imshow('mouse', bg)
        k = cv2.waitKey(1)
        if k == ord('r'):
            mode = True
        elif k == ord('c'):
            mode = False
        elif k == 27:
            break
    cv2.destroyAllWindows()

演示效果如下:

原文地址:https://www.cnblogs.com/leoych/p/12097809.html