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如何实现不用全局变量进行滚动条控制的主要内容,如果未能解决你的问题,请参考以下文章