本系列專欄寫作方式
本系列專欄寫作將采用首創的問答式寫作形式,快速讓你學習到 OpenCV 的初級、中級、高級知識,
5. Python OpenCV 中滑動條詳細說明與常見問題解決方案
滑動條在 OpenCV 相關案例中使用場景非常豐富,很多時候都需要借助于滑動條進行相關引數的獲取,
掌味訓動條,只需要掌握 cv2.createTrackbar 與 cv2.getTrackbarPos 兩個函式即可,
以上兩個函式的原型,可以直接通過 help 函式查閱,本系列專欄對于函式原型只做簡單說明
createTrackbar(trackbarName, windowName, value, count, onChange) -> None
getTrackbarPos(trackbarname, winname) -> retval
其中 cv2.createTrackbar 函式引數豐富一些,cv2.getTrackbarPos 函式是其子級,
接下來通過一個簡單的案例,實作滑動條的基本應用,拖動改變視窗中某矩形的顏色,
import cv2
import numpy as np
cv2.namedWindow("Trackbar_Demo", cv2.WINDOW_NORMAL)
# 為了在滑動條中引數位置進行占位
def nothing():
pass
ret = np.zeros([512, 512, 3], np.uint8)
# 創建一個滑動條
cv2.createTrackbar("color_green", "Trackbar_Demo", 0, 255, nothing)
while 1:
# 獲取滑動條的取值
color_green = cv2.getTrackbarPos("color_green", "Trackbar_Demo")
cv2.rectangle(ret, (100, 100), (200, 200), (0, color_green, 0), -1)
cv2.imshow("Trackbar_Demo", ret)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
如果在代碼撰寫程序中出現了如下 BUG,缺少引數:
TypeError: function takes exactly 5 arguments (4 given)
該 BUG 表示 cv2.createTrackbar 函式中缺少了最后一個 onChange 引數,添加該引數即可,引數指向的函式體可以為空,
代碼運行之后的動圖效果如下:

cv2.createTrackbar 函式中 onChange 引數相關問題解決方案
在互聯網上所有的中文資料中進行檢索,會發現有一個知識點在 cv2.createTrackbar 函式的應用中經常被忽略,這個內容就是 onChange 引數,該引數的官方說明如下:
Pointer to the function to be called every time the slider changes position. This function should be prototyped as
void Foo(int,void*);, where the first parameter is the trackbar position and the second parameter is the user data (see the next parameter). If the callback is the NULL pointer, no callbacks are called, but onlyvalueis updated.
這里要注意一個細節的地方,在 OpenCV C++ 撰寫的時候,這個函式里面多一個引數,叫做 userdata ,也就是說 C++ 中此函式的原型如下:
int createTrackbar(const String& trackbarname, const String& winname, int* value, int count, TrackbarCallback onChange=0, void* userdata=0)
但是 Python 對其進行了整合,通過一個引數完成兩個資料值的操作,這樣其實我們在進行每一次拖動滑動條的時候,都可以對其進行相應的操作,
修改代碼如下,篇幅關系,只修改 nothing 函式部分,運行代碼會出現下圖所示內容:
# 滑動條每步的回呼函式
def nothing(x):
print("滑動條進行操作")
print(x)

甚至我可以直接調整代碼邏輯,將繪制矩形的操作放到滾動條的回呼函式中,具體代碼與說明如下:
import cv2
import numpy as np
cv2.namedWindow("Trackbar_Demo", cv2.WINDOW_NORMAL)
# 滑動條每步的回呼函式
def nothing(x):
print("滑動條進行操作")
cv2.rectangle(ret, (100, 100), (200, 200), (0, x, 0), -1)
ret = np.zeros([512, 512, 3], np.uint8)
# 創建一個滑動條
cv2.createTrackbar("color_green", "Trackbar_Demo", 0, 255, nothing)
# color_green = cv2.getTrackbarPos("color_green", "Trackbar_Demo")
while True:
cv2.imshow("Trackbar_Demo", ret)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
這種邏輯具備之后,我們就可以將滑動條設計成一個開關,拖動到不同值,可以呈現不同的效果,
更多細節,可以繼續取閱讀手冊相關內容,訪問地址
OpenCV 中拆分滑動條與圖片視窗
在實際編碼程序中,建議將滑動條視窗與圖片視窗進行拆分展示,便于調整各引數,
例如下面一個手動調參實作二值化的操作(后續文章會涉及到),
import cv2
import numpy as np
def nothing(a):
pass
cv2.namedWindow("HSV",cv2.WINDOW_AUTOSIZE)
cv2.createTrackbar("HUE Min", "HSV", 0, 255, nothing)
cv2.createTrackbar("HUE Max", "HSV", 180, 255, nothing)
cv2.createTrackbar("SAT Min", "HSV", 255, 255, nothing)
cv2.createTrackbar("SAT Max", "HSV", 43, 255, nothing)
cv2.createTrackbar("VALUE Min", "HSV", 255, 255, nothing)
cv2.createTrackbar("VALUE Max", "HSV", 46, 255, nothing)
while True:
img = cv2.imread("./t1.jpg")
imgHsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
h_min = cv2.getTrackbarPos("HUE Min", "HSV")
h_max = cv2.getTrackbarPos("HUE Max", "HSV")
s_min = cv2.getTrackbarPos("SAT Min", "HSV")
s_max = cv2.getTrackbarPos("SAT Max", "HSV")
v_min = cv2.getTrackbarPos("VALUE Min", "HSV")
v_max = cv2.getTrackbarPos("VALUE Max", "HSV")
lower = np.array([h_min, s_min, v_min])
upper = np.array([h_max, s_max, v_max])
mask = cv2.inRange(imgHsv, lower, upper)
result = cv2.bitwise_and(img, img, mask=mask)
mask = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)
hStack = np.hstack([img, mask, result])
cv2.imshow('Horizontal Stacking', hStack)
if cv2.waitKey(1) & 0xFF == 27:
break
cv2.destroyAllWindows()
以上代碼運行之后,會呈現一種非常便捷的操作,拖動一個視窗,在另一個視窗中可以動態的呈現對應變化,

這個地方編碼的時候有一個注意事項,即 cv2.namedWindow(“HSV”, cv2.WINDOW_AUTOSIZE) 函式部分,請使用 cv2.WINDOW_AUTOSIZE 值,如果不使用該值,很容易造成滑動條視窗亂版的情況,或者視窗引數分布不均勻情況,
最后再次強調滑動條的另一個作用,轉換按鈕,畢竟在 OpenCV 中不存在按鈕函式,使用帶有固定值的滑動條可以有效的解決該問題,
使用代碼如下所示即可:
cv2.createTrackbar(switch,'image',0,1,nothing)
果不使用該值,很容易造成滑動條視窗亂版的情況,或者視窗引數分布不均勻情況,
最后再次強調滑動條的另一個作用,轉換按鈕,畢竟在 OpenCV 中不存在按鈕函式,使用帶有固定值的滑動條可以有效的解決該問題,
使用代碼如下所示即可:
```python
cv2.createTrackbar(switch,'image',0,1,nothing)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/294122.html
標籤:AI
上一篇:task01-熟悉規則,學習概覽
下一篇:關于學習計算機的經驗
