【翻译:OpenCV-Python教程】把鼠标当做一个画笔

⚠️这个系列是自己瞎翻的,文法很丑,跳着跳着捡重要的部分翻,翻错了不负责,就这样。

⚠️基于3.4.3,Mouse as a Paint-Brush,原文

目标 

简单示例 

现在,我们创建一个简单的应用,在我们鼠标双击的地方画一个圆圈。

首先我们创建一个由鼠标事件触发的鼠标回调方法。鼠标事件可以是任何与鼠标相关的操作,比如按下鼠标左键,弹起鼠标左键,双击鼠标左键等等。它返回给我们鼠标事件发生的座标点 (x,y) 。有了这些事件类型和发生事件的位置点,我们可以做出任何我们喜欢的操作。要列出所有被允许的鼠标事件,在python控制台上运行下面的代码。 

import cv2 as cv

events = [i for i in dir(cv) if 'EVENT' in i]

print( events )

创建鼠标回调方法,有一个走到哪都一样的固定格式。唯一不同的点在于方法本身做什么。因此我们的鼠标回调方法只干一个事情,它画一个圆圈在我们双击的地方。然后看下面的代码,代码自带注释:

import numpy as np
import cv2 as cv
# mouse callback function
def draw_circle(event,x,y,flags,param):
    if event == cv.EVENT_LBUTTONDBLCLK:
        cv.circle(img,(x,y),100,(255,0,0),-1)
# Create a black image, a window and bind the function to window
img = np.zeros((512,512,3), np.uint8)
cv.namedWindow('image')
cv.setMouseCallback('image',draw_circle)
while(1):
    cv.imshow('image',img)
    if cv.waitKey(20) & 0xFF == 27:
        break
cv.destroyAllWindows()

更复杂的示例 

现在我们要来一个更好玩的应用。在这个应用里,我们使用好像画图软件中那种拖动鼠标的方式,要么画框框要么画圆圈(取决于我们选择的模式)。因此我们的鼠标回调方法分为两部分,一部分画一个方框,另一部分画一个圆圈。这个特殊的示例会真的帮助到我们创建和理解一些有趣的应用比如object tracking、image segmentation等等。i

import numpy as np
import cv2 as cv
drawing = False # true if mouse is pressed
mode = True # if True, draw rectangle. Press 'm' to toggle to curve
ix,iy = -1,-1
# mouse callback function
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)

然后咱们必须要绑定这个鼠标回调方法到一个Opencv的窗口上,在主循环下,我们得为m键设置一个键盘绑定,用来在画方框和画圆圈之间切换。

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
    if k == ord('m'):
        mode = not mode
    elif k == 27:
        break
cv.destroyAllWindows()

额外资源 

练习 

  • 在我们的示例中,我们画了一个被填满的矩形。 自行修改代码画一个没有被填满的。

上篇:【翻译:OpenCV-Python教程】OpenCV里的画图方法

下篇:【翻译:OpenCV-Python教程】把拖动条当做调色板

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章