OpenCV for Python 學習筆記 二


今天主要看了OpenCV中的事件以及回調函數,這么說可能不准確,主要是下面這兩個函數(OpenCV中還有很多這些函數,可以在 http://docs.opencv.org/trunk/modules/highgui/doc/user_interface.html 找到,就不一一列舉了),然后自己做了一個簡單的繪圖程序

函數如下:

cv2.setMouseCallback(windowName, onMouse[, param]) 
cv2.createTrackbar(trackbarName, windowName, value, count, onChange) 

先看第一個函數,cv2.setMouseCallback()

import cv2
import numpy as np

def draw_circle(event, x, y, flags, param):
    print type(param[0]), param[1]
    if event == cv2.EVENT_LBUTTONDBLCLK:
        cv2.circle(parma, (x,y), 100, (255,0,0), -1)

img = np.zeros((512,512,3), np.uint8)
a = []
cv2.namedWindow('image')
cv2.setMouseCallback('image', draw_circle, [img, a]) while(1):
    cv2.imshow('image',img)
    if cv2.waitKey(20) & 0xFF == 27:
        break
cv2.destroyAllWindows()

這段代碼實現的功能是每當你在面板上雙擊時,繪制一個以雙擊點為園心,半徑為100的圓

加粗的地方是設置回調函數的地方,共有3個參數,第一個參數,表示將要操作的面板名,第二個參數是回調函數名,第三個是給回調函數的參數

如果要給回調函數傳遞多個參數的話,則將這么多個參數存入一個列表/元組中,將其傳入

然后看回調函數,共有5個參數:

第一個參數是鼠標事件名,可以通過如下方法查看OpenCV中的事件:

event = [i for i in dir(cv2) if 'EVENT' in i]
print event

#############################################
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_MOUSEMOVE      EVENT_RBUTTONDBLCLK
EVENT_RBUTTONDOWN     EVENT_RBUTTONUP

這么多事件,基本看名字就能知道干么了,就不說了

第二個,第三個參數是鼠標在面板中的坐標

第四個參數是有沒有其他特殊控制,比如在按左鍵的時候,按了Ctrl,Shift,Alt鍵等,參數也是剛剛上面的EVENT列表中的,通過事件名可以找到對應flags

第五個參數則是setMouseCallback()函數給回調函數傳遞的參數,至於怎么傳遞,前面已經說了(我的代碼中,a沒有用,只是為了演示如何給回調函數傳遞函數用的)

下面是第二個函數,cv2.createTrackbar()

共有5個參數,其實這五個參數看變量名就大概能知道是什么意思了

第一個參數,是這個trackbar對象的名字

第二個參數,是這個trackbar對象所在面板的名字

第三個參數,是這個trackbar的默認值

第四個參數,是這個trackbar上調節的范圍(0~count)

第五個參數,是調節trackbar時調用的回調函數名(為什么此處沒有像setMouseCallback函數一樣,設置一個回調函數的參數項,這個還不清楚)

至於如何獲取trackbar的當前位置,可以通過

cv2.getTrackbarPos(trackbarname, winname) 

這個函數獲得當前trackbar的位置,這里的參數我就不解釋了。

最后用這兩個函數做了下面一個簡單的繪圖程序:

每次獲取當前的色彩,鼠標按下后開始繪圖,鼠標移動到哪,則畫到哪,默認是繪制從起始點到終點的矩形,如果按了'm'鍵,則切換繪制以起始點和終點為直徑的圓,圓心在兩點的中心,如果再按'm'鍵,則切換會矩形。(由於本人對Python的變量作用域這塊理解還不是很到位,因此用了很多全局變量,寫的不好,請大家多多見諒)

import cv2
import numpy as np
import math
import copy as cp

drawing = False
mode = True
ix,iy = -1,-1
pre_img = np.zeros((512,512,3), np.uint8)
img = np.zeros((512,512,3), np.uint8)

def nothing(x):
    pass

def draw_circle(event, x, y, flags, param):
    global ix,iy,drawing,mode,pre_img,img
    
    # 每次獲取當前Trackbar的位置
    r = cv2.getTrackbarPos('R', 'hello')
    g = cv2.getTrackbarPos('G', 'hello')
    b = cv2.getTrackbarPos('B', 'hello') 
    colors=(b,g,r)    
   
    print colors 
    if event == cv2.EVENT_LBUTTONDOWN:
        drawing = True
        ix,iy = x,y
    elif event == cv2.EVENT_MOUSEMOVE:
        if drawing == True:
            img = cp.deepcopy(pre_img)
            if mode == True:
                cv2.rectangle(img, (ix,iy), (x,y), colors, -1)
            else:
                length = int(math.sqrt((ix-x)**2+(iy-y)**2)/2)
                center = (int(float(ix+x)/2), int(float(iy+y)/2))
                cv2.circle(img, center, length, colors, -1)
    elif event == cv2.EVENT_LBUTTONUP:
        drawing = False
        if mode == True:
            cv2.rectangle(img, (ix,iy), (x,y), colors,-1)
        else:
            length = int(math.sqrt((ix-x)**2+(iy-y)**2)/2)
            center = (int(float(ix+x)/2), int(float(iy+y)/2))
            cv2.circle(img, center, length, colors, -1)
        pre_img=img
   
   
# 創建面板       
cv2.namedWindow('hello')

# 在面板'hello'上,創建3個trackbar,分別命名為R,G,B,回調函數都是啥都不做
cv2.createTrackbar('R', 'hello', 0,255, nothing)
cv2.createTrackbar('G', 'hello', 0,255, nothing)
cv2.createTrackbar('B', 'hello', 0,255, nothing)

# 創建鼠標事件的回調函數
cv2.setMouseCallback('hello', draw_circle)

while(1):
    cv2.imshow('hello',img)
    k = cv2.waitKey(1) & 0xFF
    # 每次按'm'鍵都會切換狀態,當m=True時,繪制矩形,m=False,繪制圓
    if k == ord('m'):
        mode = not mode
        
    # 如果按了'ESC'鍵,則關閉面板
    elif k == 27:
        break
    
cv2.destroyAllWindows()

繪制出來的效果如下:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM