1-4 使用鼠标绘画-OpenCV-Python教程翻译

目标

  • 掌握在OpenCv中处理鼠标事件
  • 掌握函数cv2.setMouseCallback()

简单项目

这个项目将创建一个简单的应用实现在一张图片上任意位置双击鼠标后画出一个圆形。

首先,需要创建一个当鼠标事件发生时会执行的鼠标回调函数。鼠标事件可以是单击左键、双击左键等。每个鼠标事件将传递给我们一个坐标(x,y)。有个了这个事件和坐标,我们可以实现任何我们想要实现的功能。运行下面的代码可以获得所有可能的事件。

import cv2 as cv
events = [i for i in dir(cv) 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 numpy as np
import cv2 as cv
# 鼠标回调函数
def draw_circle(event,x,y,flags,param):
    if event == cv.EVENT_LBUTTONDBLCLK:
        # opencv画圆函数
        cv.circle(img,(x,y),100,(255,0,0),-1)
# 创建一张黑色图片,一个窗口,并将函数与窗口关联
img = np.zeros((512,512,3), np.uint8)
cv.namedWindow('image')
cv.setMouseCallback('image',draw_circle)
while(1):
    cv.imshow('image',img)
    # 键盘按下ESC,退出窗口,27对于与ESC的ACSii码
    if cv.waitKey(20) & 0xFF == 27:
        break
cv.destroyAllWindows()

上面的代码首先创建了一个draw_circle函数,函数有5个输入参数,第一个参数event是鼠标事件,第二个和第三个参数是鼠标点的坐标,后两个参数是鼠标事件传递的参数,这个函数在获得鼠标事件后,会先判断事件是不是双击左键,如果是则画出一个圆。比较关键的代码是cv.setMouseCallback('image',draw_circle),其中第一个参数是一个字符串,传递窗口名,第二个参数是鼠标事件回调函数,通过这两个参数可以将窗口和鼠标事件结合在一起,其他参数则参看帮助手册。

 复杂一点的项目

接下来将要完成一个复杂一点的项目,这里通过拖动鼠标可以画一个方形或者圆形(取决于我们选择的模式)就像真实的画笔一样。因此,我们的鼠标回调函数需要有两个部分,一个是画方形一个是画圆形。这个项目将有助于我们创建和理解一些交互式应用,比如目标追踪和图片分割等。

import numpy as np
import cv2 as cv
drawing = False # 如果鼠标按下变为true
mode = True # 如果为true,则画方形,输入‘m’切换为曲线
ix,iy = -1,-1
# 鼠标回调函数
def draw_circle(event,x,y,flags,param):
    global ix,iy,drawing,mode
    # 鼠标左键按下
    if event == cv.EVENT_LBUTTONDOWN:
        drawing = True
        ix,iy = x,y
    # 鼠标移动
    elif event == cv.EVENT_MOUSEMOVE:
        if drawing == True:
            if mode == True:
                cv.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
            else:
                cv.circle(img,(x,y),5,(0,0,255),-1)
    # 鼠标左键释放
    elif event == cv.EVENT_LBUTTONUP:
        drawing = False
        if mode == True:
            cv.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
        else:
            cv.circle(img,(x,y),5,(0,0,255),-1)
# 画一张黑色的图
img = np.zeros((512,512,3), np.uint8)
# 建立窗口
cv.namedWindow('image')
# 关联窗口和鼠标回调函数
cv.setMouseCallback('image',draw_circle)
# 循环过程进行绘图
while(1):
    cv.imshow('image',img)
    # 获得键盘输入
    k = cv.waitKey(1) & 0xFF
    # 如果键盘输入m,则变换绘图模式,如果输入ESC则退出窗口
    if k == ord('m'):
        mode = not mode
    elif k == 27:
        break
cv.destroyAllWindows()

猜你喜欢

转载自blog.csdn.net/qq_22235957/article/details/81103272
1-4
今日推荐