滑动条(Track)是*OpenCV*动态调节的辅助工具,如果只有0和1两个数值,还可以作为开关。
网上有相当多的成品代码可以使用,但是介于篇幅的问题,基本上都是用全局变量这种不安全的编码方式写出来的代码。
其实,OpenCV是有提供给我们不使用全局变量的方法的。
以下就来介绍怎么修改。
首先我们先看一下全局变量的例子。
//-------------------【程序说明】----------------------------
// 程序说明:
// 程序描述:为程序界面添加滑动条
// 开发测试所用IDE版本:Visual Studio 2013
// 开发测试所用OpenCV版本:2.4.11
// 2015年8月 Created by @klaokai
//--------------------------------------------------------
//---------------【头文件、命名空间包含部分】-------------------
// 描述:包含程序所使用的头文件和命名空间
//---------------------------------------------------------
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
//--------------------【宏定义部分】--------------------------
// 描述:定义一些辅助宏
//--------------------------------------------------------
#define WINDOW_NAME "【滑动条示例】" //为窗口标题定义的宏
//-------------------【全局变量声明部分】----------------------
// 描述:全局变量声明
//---------------------------------------------------------
const int g_nMaxValue = 254;//的最大值
int g_nValueSlider = 70;
//声明存储图像的变量
Mat g_dstImage = Mat(500 , 600 , CV_8UC1);
//--------------------【on_Trackbar( )函数】----------------
// 描述:响应滑动条的回调函数
//---------------------------------------------------------
void on_Trackbar(int , void*)
{
g_dstImage.setTo(g_nValueSlider);
//显示效果图
imshow(WINDOW_NAME , g_dstImage);
}
//------------------------【main( )函数】-------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//----------------------------------------------------
int main(int argc , char** argv)
{
//创建窗体
namedWindow(WINDOW_NAME , 1);
//在创建的窗体中创建一个滑动条控件
char TrackbarName[50];
sprintf(TrackbarName , "灰度值");
//创建滑动条
createTrackbar(TrackbarName , WINDOW_NAME ,
&g_nValueSlider , g_nMaxValue , on_Trackbar);
//结果在回调函数中显示
on_Trackbar(0 , 0);
//按任意键退出
waitKey(0);
return 0;
}
然后是修改后成局部变量的例子。
//-------------------【程序说明】----------------------------
// 程序说明:
// 程序描述:为程序界面添加滑动条
// 开发测试所用IDE版本:Visual Studio 2013
// 开发测试所用OpenCV版本:2.4.11
// 2015年8月 Created by @klaokai
//---------------------------------------------------------
//---------------【头文件、命名空间包含部分】-------------------
// 描述:包含程序所使用的头文件和命名空间
//-------------------------------------------------------------------------------------------------
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
//----------------------【宏定义部分】-----------------------
// 描述:定义一些辅助宏
//----------------------------------------------------------
#define WINDOW_NAME "【滑动条示例】" //为窗口标题定义的宏
//-----------------【on_Trackbar( )函数】-------------------
// 描述:响应滑动条的回调函数
//---------------------------------------------------------
//第一个形参是当前滑动条的数值,第二个是createTrackbar函数最后传入的数据
void on_Trackbar(int nValueSlider , void* dstImage)
{
//static_cast<>用于安全转换指针
Mat* tmpDst = static_cast<Mat*> (dstImage);
tmpDst->setTo(nValueSlider);
//显示效果图
imshow(WINDOW_NAME , *tmpDst);
}
//-----------------【main( )函数】--------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始执行
//---------------------------------------------------------
int main(int argc , char** argv)
{
const int nMaxValue = 254;//的最大值
int nValueSlider = 70;
//声明存储图像的变量
Mat dstImage = Mat(500 , 600 , CV_8UC1);
//创建窗体
namedWindow(WINDOW_NAME , 1);
//在创建的窗体中创建一个滑动条控件
char TrackbarName[50];
sprintf(TrackbarName , "灰度值");
//创建滑动条
//注意,这里最后添加上了数据的指针,不只是Mat类型,形参是一个void*类型的
createTrackbar(TrackbarName , WINDOW_NAME ,
&nValueSlider , nMaxValue , on_Trackbar , &dstImage);
//按任意键退出
waitKey(0);
return 0;
}
注意代码中void*的转换,如果使用以下代码片段,则有可能在某些时候出现错误,具体是什么原因本人现在也没有弄清楚,但是以上第二段 static_cast<>()的方式就能解决这一问题。
Mat* tmpDst = (Mat*)dstImage;