opencv如何实现不用全局变量进行滚动条控制

Posted ywsswy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了opencv如何实现不用全局变量进行滚动条控制相关的知识,希望对你有一定的参考价值。

opencv中自带滚动条,其中一个问题是该回调函数(on_trackbar)大多使用的是全局变量,大型项目调试时弊端众多,比如下图:

为此,留意了void on_Trackbar(int par1, void *)中的第二个参数,

按理说,这是允许用户传递参数进入的,但网上及书籍中未找到不用全局变量而自己传参数的例子,因此特意写了一版可以自己传局部参数的写法。

代码如下:

  1 #include <opencv2/opencv.hpp>
  2 
  3 namespace ycv {
  4 #include<iostream>
  5     class Win {
  6     public:
  7         Win(std::string name, int type);
  8         void imshow(cv::Mat &img);
  9         std::string getName();
 10     private:
 11         std::string name;
 12     };
 13 }
 14 namespace ycv {
 15     Win::Win(std::string name, int type) {
 16         this->name = name;
 17         cv::namedWindow(this->name, type);
 18     }
 19     void Win::imshow(cv::Mat &img) {
 20         cv::imshow(this->name, img);
 21     }
 22     std::string Win::getName() {
 23         return this->name;
 24     }
 25 }
 26 
 27 void on_Trackbar1(int par, void *pvoid)
 28 {
 29     static void *p0 = (void*)(*(0 + ((int*)pvoid)));
 30     static void *p1 = (void*)(*(1 + ((int*)pvoid)));
 31     static void *p2 = (void*)(*(2 + ((int*)pvoid)));
 32     static void *p3 = (void*)(*(3 + ((int*)pvoid)));
 33     static void *p4 = (void*)(*(4 + ((int*)pvoid)));
 34     ycv::Win *win = (ycv::Win*)p0;
 35     cv::Mat *mgray = (cv::Mat*)p1;
 36     cv::Mat *mbin = (cv::Mat*)p2;
 37     int *bs = (int*)p3;
 38     int *value = (int*)p4;
 39     *bs = par;//diff
 40     adaptiveThreshold(*mgray, *mbin, 255,
 41         cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY,
 42         *bs = (*bs > 1 ? ((*bs) % 2 == 1 ? *bs : *bs + 1) : 3),
 43         *value);
 44     win->imshow(*mbin);
 45 }
 46 void on_Trackbar2(int par, void *pvoid)
 47 {
 48     static void *p0 = (void*)(*(0 + ((int*)pvoid)));
 49     static void *p1 = (void*)(*(1 + ((int*)pvoid)));
 50     static void *p2 = (void*)(*(2 + ((int*)pvoid)));
 51     static void *p3 = (void*)(*(3 + ((int*)pvoid)));
 52     static void *p4 = (void*)(*(4 + ((int*)pvoid)));
 53     ycv::Win *win = (ycv::Win*)p0;
 54     cv::Mat *mgray = (cv::Mat*)p1;
 55     cv::Mat *mbin = (cv::Mat*)p2;
 56     int *bs = (int*)p3;
 57     int *value = (int*)p4;
 58     *value = par;//diff
 59     adaptiveThreshold(*mgray, *mbin, 255,
 60         cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY,
 61         *bs = (*bs > 1 ? ((*bs) % 2 == 1 ? *bs : *bs + 1) : 3),
 62         *value);
 63     win->imshow(*mbin);
 64 }
 65 void on_Trackbar3(int par, void *pvoid)
 66 {
 67     static void *p0 = (void*)(*(0 + ((int*)pvoid)));
 68     static void *p1 = (void*)(*(1 + ((int*)pvoid)));
 69     static void *p2 = (void*)(*(2 + ((int*)pvoid)));
 70     static void *p3 = (void*)(*(3 + ((int*)pvoid)));
 71     static void *p4 = (void*)(*(4 + ((int*)pvoid)));
 72     ycv::Win *win = (ycv::Win*)p0;
 73     cv::Mat *mgray = (cv::Mat*)p1;
 74     cv::Mat *mbin = (cv::Mat*)p2;
 75     int *bs = (int*)p3;
 76     int *value = (int*)p4;
 77     *value = par;//dif
 78     threshold(*mgray, *mbin, *value, 255, cv::THRESH_BINARY);
 79     win->imshow(*mbin);
 80 }
 81 int main(int argc, char** argv)
 82 {
 83     //读取图片、创建窗口
 84     ycv::Win w1 = ycv::Win("窗口1", CV_WINDOW_NORMAL);
 85     cv::Mat mgray = cv::imread("out1.jpg");
 86     cv::Mat mbin;
 87     if (!mgray.data) {
 88         std::cout << "read error\\n" << std::endl;
 89         return -1;
 90     }
 91 
 92 #if 1 //转换为HSV空间
 93     cvtColor(mgray, mgray, CV_BGR2HSV);
 94 #endif
 95 
 96 #if 1 //分离通道
 97     std::vector<cv::Mat> sbgr(mgray.channels());
 98     split(mgray, sbgr);
 99 #endif
100 
101 #if 0 //合并通道
102     std::vector<cv::Mat> mbgr(mgray.channels());
103     mbgr[0] = sbgr[2];//or sbgr.at(2);
104     mbgr[1] = sbgr[1];
105     mbgr[2] = sbgr[0];
106     merge(mbgr, mgray);
107 #endif
108 
109 #if 0 //灰度化
110     cvtColor(mgray, mgray, CV_BGR2GRAY);
111 #endif
112 
113     mgray = sbgr[0];
114 
115     int bs = 11;
116     int value = 11;
117     int *p[5];
118     p[0] = (int*)&w1;
119     p[1] = (int*)&mgray;
120     p[2] = (int*)&mbin;
121     p[3] = (int*)&bs;
122     p[4] = (int*)&value;
123 #if 0 //OSTU法
124     cv::threshold(mgray, mbin, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);//thresh is not setted manually
125     w1.imshow(mbin);
126 #elif 0 //自适应二值化
127     cv::createTrackbar("滑动条1", w1.getName(), &bs, 1111, on_Trackbar1,p);//多个滚动条,需要指明用户参数
128     cv::createTrackbar("滑动条2", w1.getName(), &value, 255, on_Trackbar2);
129     on_Trackbar2(bs, p);//显示调用一次,避免未进入之前画面无法显示
130 #else //固定二值化
131     cv::createTrackbar("滚动条3", w1.getName(), &value, 255, on_Trackbar3);//单个滚动条,可以不指明用户参数,通过下面的显示调用来指明
132     on_Trackbar3(value, p);
133 #endif
134     cv::waitKey();
135     return 0;
136 }

 

以上是关于opencv如何实现不用全局变量进行滚动条控制的主要内容,如果未能解决你的问题,请参考以下文章

如何通过css更改滚动条样式

原生JavaScript实现滚动条

如何编程控制vb2005的richtextbox的滚动条进行自由滚动?

css如何在页面内出现滚动条的地方禁止鼠标滑轮滚动

opencv再学习:视频的读取和滚动条的添加

如何用js控制网页刷新后滚动条保持在原来的位置