OpenCV(7) 处理鼠标事件

目标:

学习函数cv2.setMouseCallback()

setMouseCallback(windowName, onMouse, param=None)   第一个参数是绑定的窗口,第二个参数是回调函数。

7.1简单演示

        这里我们来创建一个简单的程序,它会在图片上你双击过的位置绘制一个

圆。首先我们来创建一个鼠标事件回调函数,鼠标事件发生时它就会被执行。

鼠标事件可以是鼠标上的任何动作,比如左键按下,左键松开,左键双击等。

我们可以通过鼠标事件获得与鼠标对应的图片上的坐标。根据这些信息我们可

以做任何我们想做的事。你可以通过执行下列代码查看所有被支持的鼠标事件。

import cv2
events=[i for i in dir(cv2) if 'EVENT'in i]
print(events)
Event

CV_EVENT_MOUSEMOVE

滑动

CV_EVENT_LBUTTONDOWN

左键点击

CV_EVENT_RBUTTONDOWN

右键点击

CV_EVENT_MBUTTONDOWN

中键点击

CV_EVENT_LBUTTONUP

左键放开

CV_EVENT_RBUTTONUP

右键放开

CV_EVENT_MBUTTONUP

中键放开

CV_EVENT_LBUTTONDBLCLK

左键双击

CV_EVENT_RBUTTONDBLCLK

右键双击

CV_EVENT_MBUTTONDBLCLK

中键双击

Flags

CV_EVENT_FLAG_LBUTTON

左键拖拽

CV_EVENT_FLAG_RBUTTON

右键拖拽

CV_EVENT_FLAG_MBUTTON

中键拖拽

CV_EVENT_FLAG_CTRLKEY

按Ctrl不放事件

CV_EVENT_FLAG_SHIFTKEY

按shift不放事件

CV_EVENT_FLAG_ALTKEY

按Alt不放事件

      所有的鼠标事件回调函数都有一个统一的格式,它们所不同的地方仅仅是

被调用后的功能。下面代码的鼠标事件的回调函数只做了一件事:在双击过的地方绘

制一个圆。

import cv2
import numpy as np


# 创建回调函数
def draw_circle(event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDBLCLK:
        cv2.circle(img, (x, y), 45, (255, 0, 0), -1) 
    
    
# 创建图像与窗口并将窗口与回调函数绑定     
img=np.zeros((512, 512, 3), np.uint8)
cv2.namedWindow('image')
cv2.setMouseCallback('image', draw_circle)
while True:
    cv2.imshow('image', img)
    if cv2.waitKey(20) & 0xFF == 27:  # 按ESC退出
        break
        
cv2.destroyAllWindows()

7.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 drawing, mode, ix, iy
    # 当按下左键时返回起始坐标
    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        ix, iy = x, y
    # 当按下左键并拖动时绘制图形.event查看鼠标的移动,flags查看鼠标的按动
    elif event == cv2.EVENT_MOUSEMOVE and flags == cv2.EVENT_FLAG_LBUTTON:
        if drawing:
            if mode:
                cv2.rectangle(img, (ix, iy), (x, y), (255, 255, 0), -1, cv2.LINE_AA)
            else:
                cv2.circle(img, (x, y), 5, (0, 0, 255), -1, cv2.LINE_AA)
    # 当松开鼠标时停止绘制图形
    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False


img = np.zeros((512, 512, 3), np.uint8)
cv2.namedWindow("img")
cv2.setMouseCallback('img', draw_circle)
while True:
    cv2.imshow('img', img)
    k = cv2.waitKey(1) & 0xFF
    if k == 27:
        break
    elif k == ord('m'):
        mode = not mode

cv2.destroyAllWindows()

文章出处登录后可见!

已经登录?立即刷新

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
乘风的头像乘风管理团队
上一篇 2022年5月10日
下一篇 2022年5月10日

相关推荐