OpenCV-Utils学习日志:GUI模块要点总结

1.主窗体管理

         (1)namedWindow(win, flag=1)=void●destroyWindow(win)=void●destroyAllWindows()=void

                   1)flag=WINDOW_NORMAL:尺寸可任意缩放且可全屏的窗体

                   2)flag=WINDOW_AUTOSIZE:尺寸固定为图像大小且不可全屏的窗体

                   3)flag=WINDOW_KEEPRATIO:尺寸可任意缩放且可全屏但长宽比例固定的窗体

                   4)flag=WINDOW_OPENGL:支持OpenGL的窗体

         (2)moveWindow(win, x, y)=void●resizeWindow(win, w, h)=void●resizeWindow(win, size)=void

         (3)getWindowImageRect(win)=rect●setWindowTitle(win, title)=void

                   1)x和y是窗体左上角在屏幕坐标系中的坐标,w和h是窗体的宽高

                   2)rect是窗体工作区(即图像)左上角在屏幕坐标系中的坐标和宽高

         (4)setWindowProperty(win, key, val)=void●getWindowProperty(win, key)=val

                   1)key=WND_PROP_FULLSCREEN:取WINDOW_NORMAL或WINDOW_FULLSCREEN

                   2)key=WND_PROP_AUTOSIZE:取WINDOW_NORMAL或WINDOW_AUTOSIZE

                   3)key=WND_PROP_ASPECT_RATION:WINDOW_FREERATIO或WINDOW_KEEPRATIO

                   4)key=WND_PROP_OPENGL:未知

                   5)key=WND_PROP_VISIBLE:未知

2.事件循环

         (1)imshow(win, ima)=void●imshow(win, texture2D)=void:显示图像或二维纹理

         (2)waitKey(delay=0)=int●waitKeyEx(delay=0)=int:后者返回完整键码(值与系统相关)

         (3)loadWindowParameters()=void:加载备份的主窗体属性及其所有子窗体属性

         (4)saveWindowParameters()=void:备份主窗体属性及其所有子窗体属性到内存

         (5)startWindowThread()=int:功能未知

         (6)startLoop(Fun, argc, argv)=int●stopLop()=void:对QtConcurrent::run的封装

3.工作区管理

         (1)displayStatusBar(win, str, delay=0)=void:在状态栏左侧显示指定毫秒(0无限)

         (2)displayOverlay(win, str, delay=0)=void:在工作区顶部显示指定毫秒(0无限)当鼠标靠近

         (3)fontQt(fontName, pointSize=-1, color=Scalar::all(0), weight=~, style=~, spacing=0)=font

                  1)weight=QT_FONT_LIGHT、~NORMAL、~DEMIBOLD、~BOLD、~BLACK

                   2)style=QT_STYLE_NORMAL、~ITALIC、~OBLIQUE

         (4)selectROI(ima, showCrosschair=true, formCenter=false)=rect

         (5)selectROI(win, ima, showCrosschair=true, fromCenter=false)=rect

         (6)selectROIs(win, ima, rects, ~)=void●addText(ima, str, pt, font)=void

                  1)绘制ima到窗体并等待鼠标操作,鼠标右键按下与释放可绘制矩形

                  2)showCrosschair为真绘制田字矩形,fromCenter为真绘制起点是矩形中心

                  3)selectROI按enter/space/esc返回绘制的矩形,按c退出并返回空矩形

                  4)selectROIs按enter/space进行下一次绘制,按esc退出绘制

4.事件交互

         (1)setMouseCallback(win, cbMouse, usrdata=0)=void●getMouseWheelDelta(wheelFlag)=int

                  1)回调函数形式:void cbMouse(eventType, x, y, eventFlag, usrdata){}

                  2)eventType取值:event_mousemove/event_mousewheel/event_mousehwheel

                  3)eventType取值:event_lbuttondown/event_lbuttonup/event_lbuttondblclk

                  4)eventType取值:event_rbuttondown/event_rbuttonup/event_rbuttondblclk

                  5)eventType取值:event_mbuttondown/event_mbuttonup/event_mbuttondblclk

                  6)eventFlag取值:event_flag_lbutton/event_flag_rbutton/event_flag_mbutton

                  7)eventFlag取值:event_flag_ctrlkey/event_flag_shiftkey/event_flag_altkey

                  8)wheelFlag取值:仅响应event_mousewheel和event_mousehwheel事件

         (2)createTrackbar(bar, win, bindVar, maxVal, cbTracker=0, usrdata=0)=int

         (3)setTrackbarMin(bar, win,val)=void●setTrackbarMax(bar, win, val)=void

         (4)setTrackbarPos(bar, win, val)=void●getTrackbarPos(bar, win)=int

                  1)回调函数形式:void cbTracker(val, usrdata) {}

                  2)最简使用方式:绑定变量是随跟踪条实时更新的,若无复杂操作则不用提供回调函数

                  3)按需使用方式:在需要时再由getTrackbarPos获取跟踪条的当前值

         (5)createButton(bar, cbButton, usrdata=0, btnType=QT_PUSH_BUTTON, state=false)

                  1)回调函数形式:void cbButton(state, usrdata)

                  2)btnType取值:qt_push_button/qt_checkbox/qt_radiobox + qt_new_buttonbar

                  3)单选按分组:同一行的单选按钮归为同一组,即同一行的单选按键互斥

         (6)回调函数的lambda问题:用lambda似乎捕获参数只能为空,但可直接访问外部静态变量

5.立体显示

         (1)setOpenGlContext(win)=void●updateWindow(win)=void

         (2)setOpenGlDrawCallback(win, cbGlDraw, usrdata)=void

                  1)回调函数形式:void cbGlDraw(usrdata)=void

                  2)使用注意事项:首先要设置窗体支持OpenGL,否则setOpenGLContext会异常。

                  3)使用基本流程:参见对应样例代码。这几个函数难以完成立体交互,需用viz模块。

6.使用样例

         以下提供OpenCV GUI模块的使用样例,封装在类AboutOpenCVGUI,实现功能如下:

         (1)模拟使用selectROI和selectROIs,在图像上选择感知兴趣的区域并按相应的键退出后,终端将显示选择的区域。

         (2)模拟使用setWindowTitle、displayStatusBar及displayOverlay,可在窗口相应处观察到相应的文字且在动态变化,按q退出。

         (3)模拟使用setMouseCallback、createTracker、createButton,可单击右上角的扫帚打开子窗口查看创建的控制。

 

         以下是详细代码,依赖于C++14、OpenCV4.x和Spdlog。

 

  1 #include <opencv2/opencv.hpp>
  2 #include <spdlog/spdlog.h>
  3 using namespace std;
  4 using namespace cv;
  5 
  6 #ifndef StrPairKey
  7 #define StrPairKey(key) make_pair(#key, key)
  8 #define StrPairVal(val) make_pair(val, #val)
  9 #endif
 10 
 11 class AboutOpenCVGUI
 12 {
 13 public:
 14     struct MouseInfo
 15     {
 16         int rowsUser;//GivenByUser
 17         int colsUser;//GivenByUser
 18         MouseInfo(int rows = INT_MAX, int cols = INT_MAX) : rowsUser(rows), colsUser(cols) {}
 19         int xMouse;//UpdatedByCbMouse
 20         int yMouse;//UpdatedByCbMouse
 21         int eventMouse;//UpdatedByCbMouse
 22         int flagMouse;//UpdatedByCbMouse
 23         const map<int, string> mouseEvents =
 24         {
 25             StrPairVal(EVENT_MOUSEMOVE),
 26             StrPairVal(EVENT_LBUTTONDOWN),
 27             StrPairVal(EVENT_RBUTTONDOWN),
 28             StrPairVal(EVENT_MBUTTONDOWN),
 29             StrPairVal(EVENT_LBUTTONUP),
 30             StrPairVal(EVENT_RBUTTONUP),
 31             StrPairVal(EVENT_MBUTTONUP),
 32             StrPairVal(EVENT_LBUTTONDBLCLK),
 33             StrPairVal(EVENT_RBUTTONDBLCLK),
 34             StrPairVal(EVENT_MBUTTONDBLCLK),
 35             StrPairVal(EVENT_MOUSEWHEEL),
 36             StrPairVal(EVENT_MOUSEHWHEEL)
 37         };
 38         const map<int, string> mouseFlags =
 39         {
 40             StrPairVal(EVENT_FLAG_LBUTTON),
 41             StrPairVal(EVENT_FLAG_RBUTTON),
 42             StrPairVal(EVENT_FLAG_MBUTTON),
 43             StrPairVal(EVENT_FLAG_CTRLKEY),
 44             StrPairVal(EVENT_FLAG_SHIFTKEY),
 45             StrPairVal(EVENT_FLAG_ALTKEY)
 46         };
 47     };
 48 
 49     static void callbackMouse(int event, int x, int y, int flag, void* pMouseInfo)
 50     {    //common case. could be replaced by lambda based on actual requirement
 51         MouseInfo* mouseInfo = (MouseInfo*)pMouseInfo;
 52 
 53         if (x >= mouseInfo->colsUser * 3) x -= mouseInfo->colsUser * 3;
 54         else if (x >= mouseInfo->colsUser * 2) x -= mouseInfo->colsUser * 2;
 55         else if (x >= mouseInfo->colsUser) x -= mouseInfo->colsUser;
 56 
 57         if (y >= mouseInfo->rowsUser * 3) y -= mouseInfo->rowsUser * 3;
 58         else if (y >= mouseInfo->rowsUser * 2) y -= mouseInfo->rowsUser * 2;
 59         else if (y >= mouseInfo->rowsUser) y -= mouseInfo->rowsUser;
 60 
 61         mouseInfo->xMouse = x;
 62         mouseInfo->yMouse = y;
 63         mouseInfo->eventMouse = event;
 64         mouseInfo->flagMouse = flag;
 65     }
 66 
 67 public:
 68     static void testBasicGUI(int argc = 0, char** argv = 0)
 69     {
 70         Mat_<Vec3b> ima(720, 1280, Vec3b(128, 128, 128));
 71 
 72         //1.AboutSelectROI
 73         string tips1 = "cv::selectROI: press enter/space/esc to return selected rect, press c to return invalid rect.";
 74         string tips2 = "cv::selectROIs: press enter/space to select next rect, press esc to return all selected rects.";
 75         string tips3 = "current mode: cv::selectROIs";
 76         auto exitFunction = [](Mat ima, string str)->void { putText(ima, "Current Test: " + str, Point(ima.cols >> 2, ima.rows - 100), FONT_HERSHEY_PLAIN, 3, Scalar(255, 0, 0), 3, LINE_8, false); };
 77         putText(ima, tips1, Point(10, 100), FONT_HERSHEY_PLAIN, 1.5, Scalar(255, 255, 255), 2, LINE_8, false);
 78         putText(ima, tips2, Point(10, 200), FONT_HERSHEY_PLAIN, 1.5, Scalar(255, 255, 255), 2, LINE_8, false);
 79         putText(ima, tips3, Point(10, 300), FONT_HERSHEY_PLAIN, 1.5, Scalar(255, 255, 255), 2, LINE_8, false);
 80         exitFunction(ima, "selectROI"); Rect rect = cv::selectROI(__FUNCTION__, ima, true, false); 
 81         spdlog::info(fmt::format("selectROI results: {} {} {} {}", rect.x, rect.y, rect.width, rect.height));
 82         exitFunction(ima, "selectROIs"); vector<Rect> rects; cv::selectROIs(__FUNCTION__, ima, rects, true, false);
 83         for(size_t k = 0; k < rects.size(); ++k) spdlog::info(fmt::format("selectROIs results{}: {} {} {} {}", k, rects[k].x, rects[k].y, rects[k].width, rects[k].height));
 84 
 85         //2.AboutTipFunctions
 86         cv::setWindowProperty(__FUNCTION__, 1, 0);//__FUNCTION__ window has created but fixed size. 
 87         for (int k = 0; ; ++k)
 88         {
 89             ima = Vec3b(128, 128, 128);
 90 
 91             tips1 = std::to_string(k) + string(" cv::setWindowTitle: show tips in the title bar until next tip is reached");
 92             tips2 = std::to_string(k) + string(" cv::displayStatusBar: show tips in the status bar until given time or next tip is reached");
 93             tips3 = std::to_string(k) + string(" cv::displayOverlay: show tips at the top of the workarea until given time or next tip is reached when mouse hovers");
 94             putText(ima, tips1, Point(10, 100), FONT_HERSHEY_PLAIN, 1.5, Scalar(255, 255, 255), 2, LINE_8, false);
 95             putText(ima, tips2, Point(10, 200), FONT_HERSHEY_PLAIN, 1.5, Scalar(255, 255, 255), 2, LINE_8, false);
 96             putText(ima, tips3, Point(10, 300), FONT_HERSHEY_PLAIN, 1.5, Scalar(255, 255, 255), 2, LINE_8, false);
 97             exitFunction(ima, "TipsFunction");
 98 
 99             cv::imshow(__FUNCTION__, ima);
100             cv::setWindowTitle(__FUNCTION__, tips1);
101             cv::displayStatusBar(__FUNCTION__, tips2, 2000);
102             cv::displayOverlay(__FUNCTION__, tips3, 2000);
103             if (cv::waitKey(4000) == 'q') break;
104         }
105 
106         //3.AboutControls
107         ima = Vec3b(128, 128, 128);
108         MouseInfo mouseInfo(ima.rows, ima.cols); cv::setMouseCallback(__FUNCTION__, callbackMouse, &mouseInfo);
109         int value = 128; cv::createTrackbar("tracker", __FUNCTION__, &value, 255, 0, 0);
110         auto cbButton = [](int state, void* usrdata)->void
111         {
112             string* str = (string*)usrdata;
113             if (str->find_first_of(':') == string::npos) *str += string(": ") + std::to_string(state);
114             else *str = str->substr(0, str->find_first_of(':')) + string(": ") + std::to_string(state);
115         };
116         string radioNames[8]; for (int k = 0; k < 8; ++k) cv::createButton(radioNames[k] = string("RadioBox") + std::to_string(k + 1), cbButton, radioNames + k, QT_RADIOBOX | (k == 0 || k == 4 ? QT_NEW_BUTTONBAR : 0));
117         string checkNames[8]; for (int k = 0; k < 8; ++k) cv::createButton(checkNames[k] = string("CheckBox") + std::to_string(k + 1), cbButton, checkNames + k, QT_CHECKBOX | (k == 0 || k == 4 ? QT_NEW_BUTTONBAR : 0));
118         string pushNames[8]; for (int k = 0; k < 8; ++k) cv::createButton(pushNames[k] = string("PushButton") + std::to_string(k + 1), cbButton, pushNames + k, QT_PUSH_BUTTON | (k == 0 || k == 4 ? QT_NEW_BUTTONBAR : 0));
119         string winName = __FUNCTION__;
120         cv::createButton("PushButtonAccept", [](int state, void* usrdata)->void {cv::setWindowTitle(*((string*)usrdata), "PushButtonAccept"); }, &winName, QT_PUSH_BUTTON | QT_NEW_BUTTONBAR);
121         cv::createButton("PushButtonCancel", [](int state, void* usrdata)->void {cv::setWindowTitle(*((string*)usrdata), "PushButtonCancel"); }, &winName, QT_PUSH_BUTTON | QT_NEW_BUTTONBAR);
122         while (1)
123         {
124             ima = Vec3b(value, value, value);
125             for (int k = 0; k < 8; ++k) putText(ima, radioNames[k], Point(100 + k % 4 * 250, 100 + k / 4 * 100), FONT_HERSHEY_PLAIN, 1.5, Scalar(255, 255, 255), 2, LINE_8, false);
126             for (int k = 0; k < 8; ++k) putText(ima, checkNames[k], Point(100 + k % 4 * 250, 300 + k / 4 * 100), FONT_HERSHEY_PLAIN, 1.5, Scalar(255, 255, 255), 2, LINE_8, false);
127             for (int k = 0; k < 8; ++k) putText(ima, pushNames[k], Point(100 + k % 4 * 250, 500 + k / 4 * 100), FONT_HERSHEY_PLAIN, 1.5, Scalar(255, 255, 255), 2, LINE_8, false);
128 
129             cv::displayOverlay(__FUNCTION__, string("x: ") + std::to_string(mouseInfo.xMouse) + "   y: " + std::to_string(mouseInfo.yMouse), 0);
130             exitFunction(ima, "Controls");
131             cv::imshow(__FUNCTION__, ima);
132             if (cv::waitKey(40) == 'q') break;
133         }
134     }
135 
136 };
137 
138 int main(int argc, char** argv) { AboutOpenCVGUI::testBasicGUI(argc, argv); return 0; }
View Code
原文地址:https://www.cnblogs.com/dzyBK/p/13909410.html