【翻譯】把滑鼠當做一個畫筆
阿新 • • 發佈:2018-12-02
⚠️這個系列是自己瞎翻的,文法很醜,跳著跳著撿重要的部分翻,翻錯了不負責,就這樣。
⚠️基於3.4.3,Mouse as a Paint-Brush,附原文。
目標
- 掌握Opencv中的滑鼠事件
- 你會學到這個方法 : cv.setMouseCallback()
簡單示例
現在,我們建立一個簡單的應用,在我們滑鼠雙擊的地方畫一個圓圈。
首先我們建立一個由滑鼠事件觸發的滑鼠回撥方法。滑鼠事件可以是任何與滑鼠相關的操作,比如按下滑鼠左鍵,彈起滑鼠左鍵,雙擊滑鼠左鍵等等。它返回給我們滑鼠事件發生的座標點 (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()
額外資源
練習
- 在我們的示例中,我們畫了一個被填滿的矩形。 自行修改程式碼畫一個沒有被填滿的。