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 版权协议,转载请附上原文出处链接和本声明。