OpenCV中如何使用滾動條動態(tài)調(diào)整參數(shù)
點擊上方“小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂”
重磅干貨,第一時間送達(dá)
OpenCV中有很多函數(shù)在圖像處理時候都有一些參數(shù)可以有多個選擇,這個時候開發(fā)者如果像快速試錯,找到最佳的參數(shù)組合或者參數(shù)類型的時候。OpenCV中通過HighGUI的滾動條提供這樣一種方便的調(diào)試方法,只是OpenCV官方教程里面滾動條的代碼實現(xiàn)比較簡單,甚至有些粗糙。本文講會在官方教程的基礎(chǔ)上進(jìn)一步改進(jìn),獲取的一個更加通用的版本代碼。
OpenCV中使用滾動條,首先需要創(chuàng)建一個窗口,然后再創(chuàng)建滾動條,滾動條本身依附于窗口上,創(chuàng)建滾動條的函數(shù)如下:
int cv::createTrackbar(
const String & trackbarname,
const String & winname,
int * value,
int count,
TrackbarCallback onChange = 0,
void * userdata = 0
)參數(shù)解釋
trackbarname表示滾動條名稱
winname表示對應(yīng)的依附窗口名稱
value表示滾動條上的值
count表示滾動條取值范圍的最大值,取值范圍為[0, count]
onChange表示拖動滾動條時產(chǎn)生事情的響應(yīng)處理函數(shù),需要自定義
userdata 表示 是否向事件處理函數(shù)傳遞參數(shù),支持的是無符號類型的指針
利用滾動條動態(tài)調(diào)整亮度
首先創(chuàng)建一個輸入圖像窗口,然后調(diào)用createTrackbar創(chuàng)建一個滾動條依附在窗口上,綁定好定義的函數(shù)onchange,其中onchange本質(zhì)上是一個事件回調(diào)函數(shù),它的定義格式如下:
typedef void(* cv::TrackbarCallback) (int pos, void *userdata)其中pos返回的是當(dāng)前滾動條滑塊的位置,userdata是該方法回調(diào)傳的用戶數(shù)據(jù)參數(shù)。這里onchange的函數(shù)定義與實現(xiàn)如下:
int max_count = 150;int cnt = 50;Mat temp;void onchange(int, void*) {Mat m = Mat::zeros(temp.size(), temp.type());m = Scalar(cnt, cnt, cnt);Mat dst;add(temp, m, dst);imshow("亮度調(diào)整", dst);}
創(chuàng)建滾動條并綁定回調(diào)函數(shù),顯示窗口與圖像的代碼
Mat image = imread("D:/images/1024.png"); // B, G, Rif (image.empty()) {printf("could not load image....\n");return -1;}temp = image.clone();namedWindow("輸入窗口", WINDOW_FREERATIO);createTrackbar("My Bar:", "輸入窗口", &cnt, max_count, onchange);imshow("輸入窗口", image);onchange(50, 0);waitKey(0);
運行結(jié)果如下:

動態(tài)調(diào)整圖像亮度與對比度
上面這個例子跟OpenCV官方教程上的很類似,缺點是定義一堆全局的臨時變量,不是很好的編程習(xí)慣。而且userdata這個參數(shù)沒有充分利用,所以我重新整合了代碼,實現(xiàn)了圖像的亮度與對比度調(diào)整,利用userdata來傳遞參數(shù),消滅了這堆臨時變量。
代碼實現(xiàn)首先創(chuàng)建兩個trackbar,一個用來調(diào)整亮度,一個用來調(diào)整對比度,分別綁定兩個回調(diào)函數(shù),然后分別通過userdata傳遞Mat對象,通過回調(diào)函數(shù)的pos參數(shù)獲取滾動條滑塊的位置,實現(xiàn)數(shù)據(jù)獲取,首先來看一下,兩個滾動條回調(diào)事件綁定函數(shù)的代碼實現(xiàn):
static void on_lightness(int pos, void* userdata) {
Mat image = *((Mat*)userdata);
Mat dst = Mat::zeros(image.size(), image.type());
Mat m = Mat::zeros(image.size(), image.type());
addWeighted(image, 1.0, m, 0, pos, dst);
imshow("亮度與對比度調(diào)整", dst);
}
static void on_contrast(int pos, void* userdata) {
Mat image = *((Mat*)userdata);
Mat dst = Mat::zeros(image.size(), image.type());
Mat m = Mat::zeros(image.size(), image.type());
double contrast = pos / 100.0;
addWeighted(image, contrast, m, 0.0, 0, dst);
imshow("亮度與對比度調(diào)整", dst);
}創(chuàng)建滾動條,綁定事件函數(shù),顯示窗口的代碼實現(xiàn)如下:
你好
int main(int argc, char** argv) {
Mat image = imread("D:/images/1024.png"); // B, G, R
if (image.empty()) {
printf("could not load image....\n");
return -1;
}
imshow("輸入窗口", image);
namedWindow("亮度與對比度調(diào)整", WINDOW_AUTOSIZE);
int lightness = 50;
int max_value = 100;
int contrast_value = 100;
createTrackbar("Value Bar:", "亮度與對比度調(diào)整", &lightness, max_value, on_lightness, (void*)(&image));
createTrackbar("Contrast Bar:", "亮度與對比度調(diào)整", &contrast_value, 200, on_contrast, (void*)(&image));
on_lightness(50, &image);
waitKey(0);
return 0;
}其中userdata參數(shù)是需要傳入指針,轉(zhuǎn)換為void*即無類型指針/任意類型指針,在事件函數(shù)中通過這行代碼:
Mat image = *((Mat*)userdata);先轉(zhuǎn)換為Mat類型指針,然后再轉(zhuǎn)換為數(shù)據(jù)使用。
運行結(jié)果如下:

好消息!
小白學(xué)視覺知識星球
開始面向外開放啦??????
下載1:OpenCV-Contrib擴(kuò)展模塊中文版教程 在「小白學(xué)視覺」公眾號后臺回復(fù):擴(kuò)展模塊中文教程,即可下載全網(wǎng)第一份OpenCV擴(kuò)展模塊教程中文版,涵蓋擴(kuò)展模塊安裝、SFM算法、立體視覺、目標(biāo)跟蹤、生物視覺、超分辨率處理等二十多章內(nèi)容。 下載2:Python視覺實戰(zhàn)項目52講 在「小白學(xué)視覺」公眾號后臺回復(fù):Python視覺實戰(zhàn)項目,即可下載包括圖像分割、口罩檢測、車道線檢測、車輛計數(shù)、添加眼線、車牌識別、字符識別、情緒檢測、文本內(nèi)容提取、面部識別等31個視覺實戰(zhàn)項目,助力快速學(xué)校計算機(jī)視覺。 下載3:OpenCV實戰(zhàn)項目20講 在「小白學(xué)視覺」公眾號后臺回復(fù):OpenCV實戰(zhàn)項目20講,即可下載含有20個基于OpenCV實現(xiàn)20個實戰(zhàn)項目,實現(xiàn)OpenCV學(xué)習(xí)進(jìn)階。 交流群
歡迎加入公眾號讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動駕駛、計算攝影、檢測、分割、識別、醫(yī)學(xué)影像、GAN、算法競賽等微信群(以后會逐漸細(xì)分),請掃描下面微信號加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三 + 上海交大 + 視覺SLAM“。請按照格式備注,否則不予通過。添加成功后會根據(jù)研究方向邀請進(jìn)入相關(guān)微信群。請勿在群內(nèi)發(fā)送廣告,否則會請出群,謝謝理解~

