1.API

1.createTrackbar()函数


createTrackbar()函数用于创建一个可以调整数值的滑动条(常常也称轨迹条),并将滑动条附加到指定的窗口上。它往往会和一个回调函数配合起来使用。

函数原型:

int createTrackbar(conststring& trackbarname, conststring& winname, int* value, 
                   int count, TrackbarCallback onChange=0, void* userdata=0);
      

createTrackbar 

共6个参数
            第1个参数 滚动条名称
            第2个参数 窗口名称
            第3个参数 初始的位置
            第4个参数 最大位置(最小位置始终为0)
            第5个参数 处理轨迹栏事件类型的回调函数
                    (opencv中这里默认是onChange = 0,实际应用中我们要自己进行函数定义及实现)
            第6个参数 userdata 传递给回调函数的用户数据(任何我们想传的,比如图像)
 

TrackbarCallback类型的函数


    共2个参数
        第1个参数 指定轨迹栏的当前位置
        第2个参数 void*类型的可选传入数据

createTrackbar 函数创建了一个具有特定名称和范围的轨迹条,指定一个和轨迹条位置同步的变量,而且指定回调函数onChange(第五个参数),在轨迹条改变的时候来调用这个回调函数,且创建的轨迹条显示在指定的winname(第二个参数)所代表的窗口上。

回调函数:通过函数指针调用的函数。把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,就称其为回调函数。
 

2.getTrackbarPos()函数


getTrackbarPos()函数用来获取当前轨迹条的位置,配合createTrackbar()函数使用。

函数原型:

int getTrackbarPos(conststring& trackbarname, conststring& winname);


参数说明:

第一个参数:conststring& trackbarname,表示轨迹条的名字

第二个参数:conststring& winname,表示轨迹条依托窗口的名称
 

3. addWeighted

调整亮度,对比度,我们也可以通过addWeighted实现
  

 共7个参数
        第1个参数 第一个输入 src1
        第2个参数 第一个输入的权重 alpha
        第3个参数 第二个输入 src2
        第4个参数 第二个输入的权重 beta
        第5个参数 每个数要增加的标量 gamma
        第6个参数 输出 dst

        第7个参数 输出的可选深度(一般用不到)
        
    公式
        dst = src1 * alpha + src2 * beta + gamma 
        范围截断在[0,255]


 

2.示例代码

第一种方法:

提高亮度 add(src, m, dst);

降低亮度 subtract(src, m, dst);

static void on_track(int light, void* userdata) {

	Mat image = *((Mat*)(userdata));

	Mat dst = Mat::zeros(image.size(), image.type());
	Mat m = Mat::zeros(image.size(), image.type());

	m = Scalar(light, light, light);

	//add(image, m, dst);
	subtract(image, m, dst);
	imshow("亮度调整", dst);

}

void QuickDemo::tracking_bar_demo(Mat& image) {

	namedWindow("亮度调整", WINDOW_AUTOSIZE);

	int lightness = 50;
	int max_light = 100;
	
	createTrackbar("Value Bar:", "亮度调整", &lightness, max_light, on_track,(void*)(&image));

	//on_track(lightness, &image);
	/*
	课程中的这一句代码,是多此一举,这是一个回调函数不需要我们手动调用
	
	这个lightness在createTrackbar中就已经传入了,这里没必要再去调用传入
	同时,我们使用了第6个参数,那么图像也已经传入,这里没必要再去调用传入
	*/

}

第二种方法:

为什么会变黑?

第一张图权重alpha,权重初始为1
第二张图权重beta,权重始终为0
第一张图的权重alpha变化时,当alpha从1.0→0,图像的每个像素点 * 这个变化alpha
这意味着第一张图的像素点的值在变小,在接近0,同时像素点之间的差值也在变小
因为最小就是0,最后每个像素点的值变成0,就变成了黑色

为什么会变白?

第一张图的权重alpha变化时,当alpha从1.0→2.0,图像的每个像素点 * 这个变化alpha
这意味着第一张图的像素点的值在变大,接近255,同时像素点之间的差值也在变大
因为最大就是255,最后每个像素点的值变成255,就变成了白色
 

关于亮度的调整
为什么会变亮呢?

第一张图权重alpha,权重始终为1
第二张图权重beta,权重始终为0
加gmama标量,增大了每个像素点的值,相当于每个像素点的值都在接近255,所以就会变亮

那该怎么变暗呢?

我们只需要让gamma标量是负数,这样就可以减小每个像素点的值
每个像素点的值,都在接近0,所以就会变暗
 

static void on_light(int lightness, void* userdata) {

    Mat image = *((Mat*)(userdata));
    Mat dst = Mat::zeros(image.size(), image.type());
    Mat m = Mat::zeros(image.size(), image.type());

    double light = lightness-50;
    /*
        gamma范围变成[-50,50]
        这样我们就实现了增大/降低亮度,
        先 降低一半,不然只能提高
    */

    addWeighted(image, 1.0, m, 0, light, dst);
    /*
    由公式:dst = src1 * alpha + src2 * beta + gamma 可知
    设置第1个权重1,第二个权重0
        相当于图片融合时,只有第1个的成分
    设置要增加的标量为lightness
        可以实现亮度的调整
    */
    imshow("windows", dst);

}

static void on_contrast(int contrast, void* userdata) {

    Mat image = *((Mat*)(userdata));
    Mat dst = Mat::zeros(image.size(), image.type());
    Mat m = Mat::zeros(image.size(), image.type());

    double contra = contrast / 100.0;
    /*
    这里的contrast初始值1 是一个[0,2]范围的数, 实现 可以调高调小
    */
    addWeighted(image, contra, m, 0, 0, dst);// 利用 图片融合函数
    /*
    由公式:dst = src1 * alpha + src2 * beta + gamma 可知
    设置第1个权重cotrast,第二个权重0
        相当于图片融合时,只有第1个的成分
        同时可以实现对比度的调整
    */

    imshow("windows", dst);

}


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    //w.show();

    namedWindow("windows", WINDOW_NORMAL);
    resizeWindow("windows", 500, 500);


    Mat srcImage = imread("C:\\Users\\29492\\Desktop\\Qt +opencv\\project\\light contrast regulate\\car7.png");
//默认BGR

    if (srcImage.empty())
    {
        printf("could not load image……\n");
    }

        int lightness = 50; //当前值
        int max_light = 100;//最大值

        int contrast = 100; //当前值
        int max_contrast = 200;//最大值

    createTrackbar("Value_contrast:", "windows", &contrast, max_contrast, on_contrast,(void*)(&srcImage));
    createTrackbar("Value_light:", "windows", &lightness, max_light, on_light,(void*)(&srcImage));

    imshow("windows", srcImage);

    std::cout <<srcImage << std::endl;

}

更多推荐