天天看點

OpenCV I_07滑鼠畫筆 setMouseCallback()

目标

• 學習使用 OpenCV 處理滑鼠事件

• 你将要學習的函數是:cv2.setMouseCallback()

滑鼠事件 :cv2.setMouseCallback()

cv2_EVENT_MOUSEMOVE 0 滑動 

cv2_EVENT_LBUTTONDOWN 1 左鍵點選 

cv2_EVENT_RBUTTONDOWN 2 右鍵點選 

cv2_EVENT_MBUTTONDOWN 3 中間點選 

cv2_EVENT_LBUTTONUP 4 左鍵釋放 

cv2_EVENT_RBUTTONUP 5 右鍵釋放 

cv2_EVENT_MBUTTONUP 6 中間釋放 

cv2_EVENT_LBUTTONDBLCLK 7 左鍵輕按兩下 

cv2_EVENT_RBUTTONDBLCLK 8 右鍵輕按兩下 

cv2_EVENT_MBUTTONDBLCLK 9 中間釋放

cv2_EVENT_FLAG_LBUTTON 1 左鍵拖拽  

cv2_EVENT_FLAG_RBUTTON 2 右鍵拖拽  

cv2_EVENT_FLAG_MBUTTON 4 中間拖拽  

cv2_EVENT_FLAG_CTRLKEY 8 (8~15)按Ctrl不放事件  

cv2_EVENT_FLAG_SHIFTKEY 16  (16~31)按Shift不放事件  

cv2_EVENT_FLAG_ALTKEY 32  (32~39)按Alt不放事件(後面8-39還有待研究)

執行個體1 :輕按兩下左鍵畫圓圈 

用到的EVENT為:cv2_EVENT_LBUTTONDBLCLK

所有的滑鼠事件回調函數都有一個統一的格式,他們所不同的地方僅僅是

被調用後的功能。我們的滑鼠事件回調函數隻用做一件事:在輕按兩下過的地方繪

制一個圓圈。下面是代碼,不懂的地方可以看看注釋。

import cv2
import numpy as np 
import time


img=cv2.imread('PIC/000.jpg') #讀取圖檔作為背景

#定義畫圓事件,如果事件輕按兩下左鍵發生
#則以此時輕按兩下的點為原點畫一個半徑為100px BGR為(255,255,0)粗細為3px的圓圈
def draw_circle(event,x,y,flags,param): 
	
	if event==cv2.EVENT_LBUTTONDBLCLK:
		cv2.circle(img,(x,y),100,(255,255,0),3)
		
# 建立圖像與視窗并将視窗與回調函數綁定
cv2.namedWindow('image') 
cv2.setMouseCallback('image',draw_circle)


while(1):
	cv2.imshow('image',img)
	if cv2.waitKey(100) == ord('q'):	#等待100毫秒 重新整理一次顯示圖像
		break
cv2.destroyAllWindows()
           

運作結果:

OpenCV I_07滑鼠畫筆 setMouseCallback()

執行個體2

現在我們來建立一個更好的程式。這次我們的程式要完成的任務是根據我

們選擇的模式在拖動滑鼠時繪制矩形或者是圓圈(就像畫圖程式中一樣)。是以

我們的回調函數包含兩部分,一部分畫矩形,一部分畫圓圈。這是一個典型的

例子他可以幫助我們更好了解與建構人機互動式程式,比如物體跟蹤,圖像分

割等。

下面我們要把這個回調函數與 OpenCV 視窗綁定在一起。在主循環中我

們需要将鍵盤上的“m”鍵與模式轉換綁定在一起。

import cv2
import numpy as np 
import time

img=cv2.imread('PIC/000.jpg')

# 當滑鼠按下時變為True
drawing=False
# 如果mode 為true 繪制矩形。按下'm' 變成繪制曲線。
mode=True
ix,iy=-1,-1



# 建立回調函數
def draw_circle(event,x,y,flags,param):
	global ix,iy,drawing,mode
# 當按下左鍵是傳回起始位置坐标
	if event==cv2.EVENT_LBUTTONDOWN:
		drawing=True
		ix,iy=x,y
# 當滑鼠左鍵按下并移動是繪制圖形。event 可以檢視移動,flag 檢視是否按下
	elif event==cv2.EVENT_MOUSEMOVE and flags==cv2.EVENT_FLAG_LBUTTON:
		if drawing==True:
			if mode==True:
				cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
			else:
				# 繪制圓圈,小圓點連在一起就成了線
				cv2.circle(img,(x,y),3,(0,0,255),-1)

# 當滑鼠松開停止繪畫。
	elif event==cv2.EVENT_LBUTTONUP:
		drawing==False




cv2.namedWindow('image')
cv2.setMouseCallback('image',draw_circle)
while(1):
	cv2.imshow('image',img)
	k=cv2.waitKey(1)&0xFF
	if k==ord('m'):
		mode=not mode
	elif k==ord('q'):
		break
           

運作結果:

OpenCV I_07滑鼠畫筆 setMouseCallback()

全部代碼:

'''函數:cv2.setMouseCallback()'''

import cv2
import numpy as np 
import time


img=cv2.imread('PIC/000.jpg')

def draw_circle(event,x,y,flags,param):

	if event==cv2.EVENT_LBUTTONDBLCLK:
		cv2.circle(img,(x,y),100,(255,255,0),3)

cv2.namedWindow('image') 
cv2.setMouseCallback('image',draw_circle)


while(1):
	cv2.imshow('image',img)
	if cv2.waitKey(100) == ord('q'):	#等待100毫秒 重新整理一次顯示圖像
		break
cv2.destroyAllWindows()




# 當滑鼠按下時變為True
drawing=False
# 如果mode 為true 繪制矩形。按下'm' 變成繪制曲線。
mode=True
ix,iy=-1,-1
6


# 建立回調函數
def draw_circle(event,x,y,flags,param):
	global ix,iy,drawing,mode
# 當按下左鍵是傳回起始位置坐标
	if event==cv2.EVENT_LBUTTONDOWN:
		drawing=True
		ix,iy=x,y
# 當滑鼠左鍵按下并移動是繪制圖形。event 可以檢視移動,flag 檢視是否按下
	elif event==cv2.EVENT_MOUSEMOVE and flags==cv2.EVENT_FLAG_LBUTTON:
		if drawing==True:
			if mode==True:
				cv2.rectangle(img,(ix,iy),(x,y),(0,255,0),-1)
			else:
				# 繪制圓圈,小圓點連在一起就成了線
				cv2.circle(img,(x,y),3,(0,0,255),-1)

# 當滑鼠松開停止繪畫。
	elif event==cv2.EVENT_LBUTTONUP:
		drawing==False




img=cv2.imread('PIC/000.jpg')
cv2.namedWindow('image')
cv2.setMouseCallback('image',draw_circle)
while(1):
	cv2.imshow('image',img)
	k=cv2.waitKey(1)&0xFF
	if k==ord('m'):
		mode=not mode
	elif k==ord('q'):
		break
           

繼續閱讀