番外5. Python OpenCV 中滑動(dòng)條詳細(xì)說(shuō)明與常見問(wèn)題解決方案

本系列專欄寫作方式

本系列專欄寫作將采用首創(chuàng)的問(wèn)答式寫作形式墓陈,快速讓你學(xué)習(xí)到 OpenCV 的初級(jí)恶守、中級(jí)第献、高級(jí)知識(shí)。

5. Python OpenCV 中滑動(dòng)條詳細(xì)說(shuō)明與常見問(wèn)題解決方案

滑動(dòng)條在 OpenCV 相關(guān)案例中使用場(chǎng)景非常豐富兔港,很多時(shí)候都需要借助于滑動(dòng)條進(jìn)行相關(guān)參數(shù)的獲取庸毫。

掌握滑動(dòng)條,只需要掌握 <kbd>cv2.createTrackbar</kbd> 與 <kbd>cv2.getTrackbarPos</kbd> 兩個(gè)函數(shù)即可押框。

以上兩個(gè)函數(shù)的原型橡伞,可以直接通過(guò) help 函數(shù)查閱,本系列專欄對(duì)于函數(shù)原型只做簡(jiǎn)單說(shuō)明

createTrackbar(trackbarName, windowName, value, count, onChange) -> None
getTrackbarPos(trackbarname, winname) -> retval

其中 <kbd>cv2.createTrackbar</kbd> 函數(shù)參數(shù)豐富一些崭闲,<kbd>cv2.getTrackbarPos</kbd> 函數(shù)是其子級(jí)。

接下來(lái)通過(guò)一個(gè)簡(jiǎn)單的案例,實(shí)現(xiàn)滑動(dòng)條的基本應(yīng)用,拖動(dòng)改變窗口中某矩形的顏色。

import cv2
import numpy as np

cv2.namedWindow("Trackbar_Demo", cv2.WINDOW_NORMAL)

# 為了在滑動(dòng)條中參數(shù)位置進(jìn)行占位


def nothing():
    pass


ret = np.zeros([512, 512, 3], np.uint8)
# 創(chuàng)建一個(gè)滑動(dòng)條
cv2.createTrackbar("color_green", "Trackbar_Demo", 0, 255, nothing)

while 1:
    # 獲取滑動(dòng)條的取值
    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()

如果在代碼編寫過(guò)程中出現(xiàn)了如下 BUG,缺少參數(shù):

TypeError: function takes exactly 5 arguments (4 given)

該 BUG 表示 <kbd>cv2.createTrackbar</kbd> 函數(shù)中缺少了最后一個(gè) <kbd>onChange</kbd> 參數(shù),添加該參數(shù)即可弱左,參數(shù)指向的函數(shù)體可以為空们镜。

代碼運(yùn)行之后的動(dòng)圖效果如下:

2d0d13b65ebfdc003ecf981e85b2020d[1].gif

<kbd>cv2.createTrackbar</kbd> 函數(shù)中 onChange 參數(shù)相關(guān)問(wèn)題解決方案

在互聯(lián)網(wǎng)上所有的中文資料中進(jìn)行檢索,會(huì)發(fā)現(xiàn)有一個(gè)知識(shí)點(diǎn)在 <kbd>cv2.createTrackbar</kbd> 函數(shù)的應(yīng)用中經(jīng)常被忽略褐鸥,這個(gè)內(nèi)容就是 <kbd>onChange</kbd> 參數(shù)翠霍,該參數(shù)的官方說(shuō)明如下:

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 only value is updated.

這里要注意一個(gè)細(xì)節(jié)的地方,在 OpenCV C++ 編寫的時(shí)候,這個(gè)函數(shù)里面多一個(gè)參數(shù)掸鹅,叫做 <kbd>userdata</kbd> ,也就是說(shuō) C++ 中此函數(shù)的原型如下:

int createTrackbar(const String& trackbarname, const String& winname, int* value, int count, TrackbarCallback onChange=0, void* userdata=0)

但是 Python 對(duì)其進(jìn)行了整合削咆,通過(guò)一個(gè)參數(shù)完成兩個(gè)數(shù)據(jù)值的操作炊邦,這樣其實(shí)我們?cè)谶M(jìn)行每一次拖動(dòng)滑動(dòng)條的時(shí)候碘菜,都可以對(duì)其進(jìn)行相應(yīng)的操作计雌。

修改代碼如下,篇幅關(guān)系恬口,只修改 <kbd>nothing</kbd> 函數(shù)部分钞螟,運(yùn)行代碼會(huì)出現(xiàn)下圖所示內(nèi)容:

# 滑動(dòng)條每步的回調(diào)函數(shù)
def nothing(x):
    print("滑動(dòng)條進(jìn)行操作")
    print(x)

[圖片上傳失敗...(image-81b869-1640564856488)]
)

甚至我可以直接調(diào)整代碼邏輯褒链,將繪制矩形的操作放到滾動(dòng)條的回調(diào)函數(shù)中恍箭,具體代碼與說(shuō)明如下:

import cv2
import numpy as np

cv2.namedWindow("Trackbar_Demo", cv2.WINDOW_NORMAL)

# 滑動(dòng)條每步的回調(diào)函數(shù)
def nothing(x):
    print("滑動(dòng)條進(jìn)行操作")
    cv2.rectangle(ret, (100, 100), (200, 200), (0, x, 0), -1)


ret = np.zeros([512, 512, 3], np.uint8)
# 創(chuàng)建一個(gè)滑動(dòng)條
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()

這種邏輯具備之后,我們就可以將滑動(dòng)條設(shè)計(jì)成一個(gè)開關(guān)伍掀,拖動(dòng)到不同值县好,可以呈現(xiàn)不同的效果缕贡。

更多細(xì)節(jié),可以繼續(xù)取閱讀手冊(cè)相關(guān)內(nèi)容剂跟,訪問(wèn)地址

OpenCV 中拆分滑動(dòng)條與圖片窗口

在實(shí)際編碼過(guò)程中辽剧,建議將滑動(dòng)條窗口與圖片窗口進(jìn)行拆分展示阐斜,便于調(diào)整各參數(shù)为居。

例如下面一個(gè)手動(dòng)調(diào)參實(shí)現(xiàn)二值化的操作(后續(xù)文章會(huì)涉及到)。

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()

以上代碼運(yùn)行之后,會(huì)呈現(xiàn)一種非常便捷的操作嘉熊,拖動(dòng)一個(gè)窗口遥赚,在另一個(gè)窗口中可以動(dòng)態(tài)的呈現(xiàn)對(duì)應(yīng)變化。

7c1a738ee0a8f84f7e294f16c1989e64[1].png

這個(gè)地方編碼的時(shí)候有一個(gè)注意事項(xiàng)阐肤,即 <kbd>cv2.namedWindow("HSV", cv2.WINDOW_AUTOSIZE)</kbd> 函數(shù)部分凫佛,請(qǐng)使用 <kbd>cv2.WINDOW_AUTOSIZE</kbd> 值,如果不使用該值孕惜,很容易造成滑動(dòng)條窗口亂版的情況愧薛,或者窗口參數(shù)分布不均勻情況。

最后再次強(qiáng)調(diào)滑動(dòng)條的另一個(gè)作用衫画,轉(zhuǎn)換按鈕毫炉。畢竟在 OpenCV 中不存在按鈕函數(shù),使用帶有固定值的滑動(dòng)條可以有效的解決該問(wèn)題削罩。

使用代碼如下所示即可:

cv2.createTrackbar(switch,'image',0,1,nothing)
果不使用該值瞄勾,很容易造成滑動(dòng)條窗口亂版的情況,或者窗口參數(shù)分布不均勻情況弥激。

最后再次強(qiáng)調(diào)滑動(dòng)條的另一個(gè)作用进陡,轉(zhuǎn)換按鈕。畢竟在 OpenCV 中不存在按鈕函數(shù)秆撮,使用帶有固定值的滑動(dòng)條可以有效的解決該問(wèn)題四濒。

使用代碼如下所示即可:

```python
cv2.createTrackbar(switch,'image',0,1,nothing)
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子盗蟆,更是在濱河造成了極大的恐慌戈二,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,490評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件喳资,死亡現(xiàn)場(chǎng)離奇詭異觉吭,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)仆邓,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門鲜滩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人节值,你說(shuō)我怎么就攤上這事徙硅。” “怎么了搞疗?”我有些...
    開封第一講書人閱讀 165,830評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵嗓蘑,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我匿乃,道長(zhǎng)桩皿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,957評(píng)論 1 295
  • 正文 為了忘掉前任幢炸,我火速辦了婚禮泄隔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘宛徊。我一直安慰自己佛嬉,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評(píng)論 6 393
  • 文/花漫 我一把揭開白布岩调。 她就那樣靜靜地躺著巷燥,像睡著了一般。 火紅的嫁衣襯著肌膚如雪号枕。 梳的紋絲不亂的頭發(fā)上缰揪,一...
    開封第一講書人閱讀 51,754評(píng)論 1 307
  • 那天,我揣著相機(jī)與錄音葱淳,去河邊找鬼钝腺。 笑死,一個(gè)胖子當(dāng)著我的面吹牛赞厕,可吹牛的內(nèi)容都是我干的艳狐。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼皿桑,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼毫目!你這毒婦竟也來(lái)了蔬啡?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,357評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤镀虐,失蹤者是張志新(化名)和其女友劉穎箱蟆,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體刮便,經(jīng)...
    沈念sama閱讀 45,847評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡空猜,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了恨旱。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片辈毯。...
    茶點(diǎn)故事閱讀 40,137評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖搜贤,靈堂內(nèi)的尸體忽然破棺而出谆沃,到底是詐尸還是另有隱情,我是刑警寧澤仪芒,帶...
    沈念sama閱讀 35,819評(píng)論 5 346
  • 正文 年R本政府宣布管毙,位于F島的核電站,受9級(jí)特大地震影響桌硫,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜啃炸,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評(píng)論 3 331
  • 文/蒙蒙 一铆隘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧南用,春花似錦膀钠、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至筑公,卻和暖如春雳窟,著一層夾襖步出監(jiān)牢的瞬間匣屡,已是汗流浹背誉结。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留惩坑,地道東北人以舒。 一個(gè)月前我還...
    沈念sama閱讀 48,409評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像瓦侮,于是被迫代替她去往敵國(guó)和親肚吏。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容