本節書摘來自華章計算機《opencv圖像處理》一書中的第1章,第1.7節,作者:[西]葛羅瑞亞·布埃諾·加西亞(gloria bueno garcía)著,更多章節内容可以通路雲栖社群“華章計算機”公衆号檢視
前面幾節介紹了如何建立視窗(namedwindow)來顯示(imshow)一幅圖像和提取/處理事件(waitkey)。我們提供的示例展示了一種通過鍵盤使用opencv應用進行使用者互動的簡單方法。waitkey函數在逾時之前會傳回一個按鍵
編碼。
幸運的是,opencv為使用者互動提供了更為靈活的方式,例如,滑動條和滑鼠互動,它們可以和某些繪圖功能結合提供豐富的使用者體驗。而且,如果使用qt支援(cmake的with_qt選項)對opencv進行本地編譯,那麼一組新函數可用來編寫一個更好的使用者界面(ui)。
本節給出一個快速綜述來說明,在使用qt支援的一個opencv項目中,編寫使用者界面的可用功能。下面使用一個名為showui的示例,在opencv界面支援下對上述綜述進行說明。
該示例展示了一個視窗中的一幅彩色圖檔,說明如何使用某些基本元素來豐富使用者互動。圖1-6顯示了在該示例中建立的ui元素:

showui示例(沒有回調函數)的源代碼如下:
當使用qt支援建立opencv時,每個所建立的視窗(通過highgui子產品)顯示了一個預設工具欄(見圖1-6),帶有平移、縮放、儲存和打開屬性視窗的選項(從左到右)。
除了上述提到的工具欄(僅在qt上可用),下面幾節将說明在該示例中建立的各種ui元素和實作這些ui元素的代碼。
1.7.1 滑動條
在指定的視窗(winname)中,使用createtrackbar(const string& trackbarname, const string& winname, int value, int count, trackbarcallback onchange=0, void userdata=0)函數建立滑動條,該函數使用了一個連結整數值(value)、一個最大值(count)、一個當滑動條改變時被調用的可選回調函數(onchange)和回調函數的一個參數(userdata)。回調函數本身得到兩個參數:值(通過滑動條選取)和一個指向userdata(可選)的指針。對于qt支援,如果沒有指定視窗,那麼會在屬性視窗中建立該滑動條。在showui示例中,建立了兩個滑動條:第一個在主視窗中,第二個在屬性視窗中。滑動條回調的代碼是:
1.7.2 滑鼠互動
總是生成滑鼠事件使得使用者可以用滑鼠(移動和點選)進行互動。通過設定正确的處理程式或回調函數,可以實作諸如選擇、拖放之類的動作。在指定的視窗(winname)和可選參數(userdata)下使用setmousecallback(const string& winname, mousecallback onmouse, void* userdata=0)函數可啟用該回調函數(onmouse)。
處理滑鼠事件的回調函數的源代碼是:
在showui示例中,通過一個回調函數(cbmouse),可用滑鼠事件繪制一個矩形來選擇一個矩形區域。在這個示例中,該函數的聲明為void cbmouse(int event, int x, int y, int f?lags, void*),其參數為事件發生點(x, y)的位置、事件發生(f?lags)時的條件和可選項userdata。
可以在highgui.hpp頭檔案中找到可用的事件、标志以及它們對應的定義符号。
1.7.3 按鈕
opencv(隻在使用qt支援時)允許建立三種類型的按鈕:複選框(qt_checkbox)、單選框(qt_radiobox)和按鈕(qt_push_button)。可以分别使用這些類型的按鈕來設定選項、設定互斥選項和按鈕上的執行動作。在屬性視窗中,這三個按鈕可使用函數createbutton(const string& button_name, buttoncallback on_change, void* userdata=0, int type=qt_push_button, bool init_state=false)來建立,它被安排在這個視窗所建立的最後一個滑動條之後的一個按鈕條中。該按鈕的參數是它的名字(button_name)、狀态變化(on_change)時調用的回調函數、該回調函數的一個可選參數(userdate)、按鈕的類型(type)和該按鈕的初始狀态(init_state)。
接下來,展示本示例中按鈕所對應的回調函數的源代碼:
一個按鈕的回調函數得到兩個參數:它的狀态和一個指向使用者資料的(可選項)指針。在showui示例中,展示了如何将一個整數(radioboxcallback(int state, void id))傳遞到指定的按鈕和一個更複雜的對象(pushbuttoncallback(int, void font))。
1.7.4 文本繪制與顯示
實作圖像處理結果與使用者間通信的一種非常有效的方式是在被處理的圖檔上繪制形狀或顯示文本。通過imgproc子產品,opencv提供了一些友善的功能來實作諸如輸入文本、繪制線、圓、橢圓、矩形、多邊形等之類的任務。showui示例說明了如何在一幅圖像上選擇一個矩形區域和繪制一個矩形來标記所選擇的區域。下面的函數繪制(img)一個矩形,該矩形通過在一幅圖像上的兩個點(p1,p2)定義,并具有指定的顔色和其他可選參數,如線條的寬度(對于填充形狀是負數)和類型:
除了支援形狀繪制之外,imgproc子產品提供一個功能,使用下面的函數在一幅圖像上放置文本:
在core.hpp頭檔案中,可以為文本檢查可用的字型。
在highgui子產品中,qt支援還增加了一些附加方法用于在一個opencv應用的主視窗上顯示文本:
圖像上的文本:使用函數addtext(const mat& img, const string& text, point org, const qtfont& font)得到這個結果。這個函數允許選擇所顯示文本的起點,該文本使用了之前用的函數fontqt(const string& namefont, int pointsize=-1, scalar color=scalar::all(0), int weight=qt_font_normal, int style=qt_style_normal, int spacing=0)建立的字型。在showui示例中,當點選按鈕時(通過在回調函數内調用addtext函數)這個函數用于在圖像上輸入文本。
狀态欄上的文本:使用函數displaystatusbar(const string& winname, const string& text, int delayms=0)顯示狀态欄中的文本,由最後一個參數(delayms)指定顯示的毫秒數。在showui示例中,當屬性視窗的按鈕和滑動條更改其狀态時,使用該函數(在回調函數中)顯示一條文本資訊。
覆寫在圖像上的文本:使用函數displayoverlay(const string& winname, const string& text, int delayms=0)顯示覆寫在圖像上的文本,由最後一個參數指定顯示的毫秒數。在showui示例中,當主視窗滑動條更改其值時,使用該函數(在回調函數中)顯示文本資訊。