zoukankan      html  css  js  c++  java
  • OpenCV trackbar 避免使用全局变量

    OpenCV trackbar 避免使用全局变量

    在OpenCV中使用trackbar是交互式地图像处理的一种方式,例如用于图像阈值分割,用户可以一边调整阈值一边看效果。但是很不幸,绝大多数教程上使用trackbar的样例代码,都通过全局变量的方式进行调用。此做法,优点:写demo时候快速方便;缺点:糟糕的代码风格。

    看看函数原型:

    createTrackbar(const string& trackbarname, 
    			   const string& winname, 
    			   int* value, 
    			   int count, 
    			   TrackbarCallback callback=(TrackbarCallback)0,
    			   void* userdata=(void*)0
    			);
    

    其中最后一个参数,userdata,就是用来解救糟糕代码风格的。把回调函数中“不得不使用的全局变量”们,组装到一起,作为userdata传入createTrackbar函数,就避免了全局变量的使用。组装方式?用一个结构体就可以了;而在回调函数中,则通过类型转化而使用(void*->自定义结构体类型*)

    使用trackbar但是不使用全局变量的阈值分割代码如下:

    #include <iostream>
    #include <opencv2/opencv.hpp>
    
    using namespace std;
    using namespace cv;
    
    // 自定义结构体类型,将数据打包封装到结构体里
    struct FkOpenCV {
    	string winname;
    	Mat im;
    	FkOpenCV(string winname_, Mat& im_):
    		winname(winname_), im(im_){}
    };
    
    // 回调函数
    void on_threshold(int bar_val, void* userdata) {
    	cout << "bar_val is:" << bar_val << endl; //bar_val就是createTrackbar调用时的value参数
    	FkOpenCV fk = *(FkOpenCV*)(userdata);
    
    	Mat dst;
    	threshold(fk.im, dst, bar_val, 255, 0);
    	imshow(fk.winname, dst);
    }
    
    // demo代码
    void thresh_seg_demo() {
    	string im_name = "imgs/test.jpg";
    	Mat image = imread(im_name);
    
    	namedWindow("原图");
    	imshow("原图", image);
    
    	Mat im_gray;
    	cvtColor(image, im_gray, CV_BGR2GRAY);
    
    	string winname = "阈值分割";
    	namedWindow(winname);
    	int value = 30;
    	FkOpenCV fk(winname, im_gray);
    	createTrackbar("模式", winname, &value, 255, on_threshold, &fk);
    
    	waitKey();
    	destroyAllWindows();
    }
    
    // 主函数
    int main() {
    	thresh_seg_demo();
    	
    	return 0;
    }
    
  • 相关阅读:
    shell-变量的数值运算let内置命令
    shell-变量的数值运算符-计算双括号(())的使用
    shell-批量修改文件名及扩展名多案例
    shell-变量的字串应用技术
    一个MVVM前端扩展器
    测试一个mysql 悲观锁
    spring rest项目提示Request method 'PUT' not supported Method Not Allowed 405 错误
    Mysql 使用sql语句添加列,修改列默认值,添加类注释
    理解java泛型中的 上界extend 下界super
    mysql存储过程游标循环装载字符串SQL语句示例
  • 原文地址:https://www.cnblogs.com/zjutzz/p/7843651.html
Copyright © 2011-2022 走看看