本文主要內容來自於 OpenCV-Python 教程 的 OpenCV 中的 GUI 功能 部分,這個部分的主要內容如下:
- 圖像操作入門 學習加載一幅圖像,顯示它,並保存它
- 視頻入門 學習播放視頻,從攝像頭捕捉視頻,以及寫入視頻
- OpenCV 中的繪製功能 學習通過 OpenCV 繪製線、矩形、橢圓形和圓形等等
- 鼠標作爲畫筆 用鼠標畫東西
- 軌跡欄作爲調色板 創建軌跡欄以控制某些參數
目標
- 學習將軌跡欄綁定到 OpenCV 窗口
- 我們將學習這些函數: cv.getTrackbarPos(),cv.createTrackbar() 等等。
代碼演示程序
這裏我們將創建一個簡單的應用程序,它展示我們指定的顏色。這個應用中有一個展示顏色的窗口,以及三個軌跡欄以分別指定 B,G 和 R 顏色值。我們滑動軌跡欄並相應地更改窗口顏色。默認情況下,初始顏色將設置爲黑色。
對於 cv.createTrackbar() 函數,第一個參數是軌跡欄的名稱,第二個參數是它所附加的窗口的名稱,第三個參數是默認值,第四個是最大值,第五個是每次軌跡欄值更改時執行的回調函數。回調函數始終只有一個參數,即軌跡欄的位置。因而在軌跡欄事件的回調函數中,無法區分是綁定的哪個軌跡欄實例所產生的事件。
軌跡欄的另一個重要應用是用作按鈕或開關。OpenCV,默認情況下,沒有按鈕功能。因此,我們可以使用軌跡欄來獲得這種功能。在我們的應用程序中,我們創建一個開關,應用程序只要在這個開關打開時才運行,否則屏幕總是黑色的。
def trackbar():
# Create a black image, a window
img = np.zeros((300, 512, 3), np.uint8)
switch = True
blue = 0
green = 0
red = 0
def callback_factory(user_data):
def callback(pos):
nonlocal switch, blue, green, red
if user_data == 'S':
if pos == 0:
switch = False
else:
switch = True
elif user_data == 'B':
blue = pos
elif user_data == 'G':
green = pos
elif user_data == 'R':
red = pos
if not switch:
img.fill(0)
else:
img[:] = (blue, green, red)
cv.imshow('image', img)
return callback
cv.namedWindow('image')
# create trackbars for color change
cv.createTrackbar('R', 'image', 0, 255, callback_factory('R'))
cv.createTrackbar('G', 'image', 0, 255, callback_factory('G'))
cv.createTrackbar('B', 'image', 0, 255, callback_factory('B'))
# create switch for ON/OFF functionality
switch = '0 : OFF \n1 : ON'
cv.createTrackbar(switch, 'image', 0, 1, callback_factory('S'))
cv.imshow('image', img)
while True:
k = cv.waitKey(1) & 0xFF
if k == 27:
break
cv.destroyAllWindows()
在這個示例程序中,爲了及時響應發生的事件,同時也爲了降低輪詢各個軌跡欄的狀態所帶來的開銷,圖像的狀態的改變以及繪製,直接在回調中完成。
這裏爲所有軌跡欄實例只實現了一個回調函數,爲了能夠在軌跡欄事件回調中區分事件是發生在哪個軌跡欄上的,而通過另一個函數,將回調函數包爲閉包。
這裏爲了演示 cv.getTrackbarPos() 函數的用法,而在回調函數裏用了這個函數,但這個調用也可以替換爲回調函數的參數中的 pos。
這個應用程序的截屏看起來像下面這樣:
OpenCV 提供的窗口等 GUI 接口,僅僅用於一般的示例程序編寫,這部分接口的能力和靈活性與 GTK 或 QT 這種專業的 GUI 開發庫所提供的能力和靈活性相差甚遠。這部分的功能也不是 OpenCV 庫的核心,因而也並不值得投入太大的時間和精力來學習。
參考文檔
Done.