【Opencv】滑动条的使用

  • Post author:
  • Post category:其他




Opencv中滑动条的使用

滑动条是Opencv的一种控件,能够使用鼠标控制滑动条的位置,从而与图片程序进行交互。滑动条的内容包含两个部分,分别是滑动条的创建和回调函数。

回调函数一般不由主程序直接调用,而是当有特殊事件发生的时候会触发这个函数,就比如当我们改变滚动条的数值的时候,能够触发回调函数,从而产生一些效果。



滑动条的函数定义


int cv::createTrackbar	(	const String & 	trackbarname,
const String & 	winname,
int * 	value,
int 	count,
TrackbarCallback 	onChange = 0,
void * 	userdata = 0 
)	
  • 第一个参数 :trackbarname是一个字符串类型的变量,意义是滑动条的名字,会显示在滑动条的左边
  • 第二个参数: winname也是一个字符串类型的变量,用于说明滑动条吸附在哪个窗口上
  • 第三个参数:是一个int类型的指针,用于记录滑动条当前的值,这个数值会传递给回调函数
  • 第四个参数: count是int类型的变量,用于说明滑动条的最大值
  • 第五个参数: 是一个函数指针,用于说明运行时候调用哪个函数作为回调函数
  • 第六个参数:是一个void*类型的指针,可以表示任何一种类型的指针,其作用是向回调函数传递数据。如果你使用的变量都是全局变量,也可以不使用这个参数,这个参数具体怎么传递数据,后面进行说明。



回调函数的函数定义

回调函数是我们自定义的一个函数,但是必须满足格式上的要求,返回类型为void,并且带int和void

类型的两个变量,其格式要求是这样的。int的位置用来接受滑动条函数的第三个参数,void

位置用于接受滑动条的第六个参数,通过这两个参数可以实现数据在滑动条和回调函数之间的传递。

void MyFunction(int , void*)
{
}



滑动条的使用例子

这里结合毛星云《Opencv3编程入门》的例子稍微改变了一下,用于说明如何让回调函数能够接受到滑动条的数据。这个例子里面用到了void*的一些相关知识,可以查阅

https://blog.csdn.net/Lee_Shuai/article/details/53193436

这篇文章进行相关知识的了解。

//这个例子的功能是,我们要将两幅图片进行线性混合,通过滑动条来控制线性混合的比例
//这里要注意的是,用于线性混合的两张图片大小必须是一样的,否则无法成功
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;

class MyPicture
    //定义了一个类,用来作为滑动条的第六个参数进行传递数据,而没有使用全局变量的方式进行
{
public:
    double alpha;//线性混合的alpha值
    double beta;//线性混合的beta值
    Mat m1, m2;//用于存放用于线性混合的两张图片
    const int Max=100;//滑动条的最大值

    MyPicture(double aplha, double beta, Mat m1, Mat m2) :alpha(alpha), beta(beta), m1(m1), m2(m2) {}
    //构造函数,并且使用初始化列表的方法进行变量的初始化

};
void Track(int nowValue, void* p)//回调函数
{
    MyPicture mp = *(MyPicture*)p; //将void*类型的指针变成我们需要的类型,接受参数
    Mat m3;//线性混合的最后的输出结果
    double gamma = 0.0;//线性混合的参数
    mp.alpha = 1.0 * nowValue / mp.Max;
    mp.beta = 1 - mp.alpha;
    addWeighted(mp.m1, mp.alpha, mp.m2, mp.beta, gamma, m3);//线性混合
     //线性混合的公式为 输出图片m3 = m1*alpha + m2*beta + gamma; 
    imshow("window", m3);
}

int main()
{
    int nowValue = 100; //用于记录滑动条的当前数值
    Mat m1 = imread("1.jpg");//用于线性混合的第一张图
    Mat m2 = imread("2.jpg");//用于线性混合的第二张图
    MyPicture mp(1.0, 0.0, m1, m2);//初始化函数
    Track(nowValue, &mp);//初始化图片显示
    string TrackName = "透明值100";
    namedWindow("window", WINDOW_NORMAL);
    createTrackbar(TrackName, "window", &nowValue, mp.Max, Track, &mp);//创建滑动条
    waitKey(0);



    return 0;
}

当然,你也可以按照书中的方法,使用全局变量的方法进行,不需要构造新的指针传递参数了。

使用全局变量方法实现滑动条的例子也写在这里了,可以一并查看

#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;

//全局变量,滑动条
const int Max = 100;
int g_nowValue;
double alpha;
double beta;

//全局变量,图片
Mat m1, m2, m3;

void Track(int, void*)
{
	alpha = (double)g_nowValue / Max;
	beta = 1 - alpha;
	addWeighted(m1, alpha, m2, beta, 0.0, m3);
	imshow("1", m3);
}
int main()
{
	m1 = imread("1.jpg");
	m2 = imread("2.jpg");
	g_nowValue = 70;
	Track(g_nowValue,0);

	namedWindow("1");
	string TrackName = "透明度100";
		
	createTrackbar(TrackName, "1", &g_nowValue, Max, Track);
	waitKey(0);


	return 0;
}



版权声明:本文为qq_41741344原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。