07 滚动条操作2.0 - 调整亮度与对比度

07 滚动条操作2.0 - 调整亮度与对比度

opencv知识点:

  • 创建滚动条 - createTrackbar()
  • 处理滚动条事件的函数 - TrackbarCallback()
  • 亮度与对比度的概念
  • 巧用图片融合 - addWeighted()

本课所解决的问题:

  • 如何利用createTrackbaruserdata
  • 调整亮度/对比度的内涵是什么?
  • 如何利用图片融合addWeighted调整亮度/对比度?

1.参数userdata

对上一次课代码的改进,利用上userdata这个参数

合理运用第6个参数userdata,进行参数传递,从而调整亮度,以降低亮度为例。

程序

quickdemo.cpp

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个参数,那么图像也已经传入,这里没必要再去调用传入
	*/

}

2197940dd53444294b0432f7b0443a9

2.亮度与对比度

亮度

调整亮度,就是整体的像素点值的调整,相当于整体同时加上一个数(可正可负)。

对比度

调整对比度,就是调整像素点之间的差值,相当于乘上一个数,如0.5,1.3。
像素点的值在变化的同时,像素点之间的差值也在变化。

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]

完整代码

quickdemo.cpp

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());

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

}

void QuickDemo::tracking_bar_demo(Mat& image) {

	namedWindow("亮度/对比度调整", WINDOW_AUTOSIZE);

	int lightness = 50;
	int max_light = 100;

	int contrast = 100;
	int max_contrast = 200;

	createTrackbar("Value Bar:", "亮度/对比度调整", &lightness, max_light, on_light, (void*)(&image));
	createTrackbar("Contrast Bar:", "亮度/对比度调整", &contrast, max_contrast, on_contrast, (void*)(&image));

	/*无用语句,理由同上*/
	//on_light(lightness, &image);
	//on_contrast(lightness, &image);

}

关于亮度的调整

为什么会变亮呢?

第一张图权重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.0;
	/*
		gamma范围变成[-50,50]
		这样我们就实现了增大/降低亮度,
	*/

	addWeighted(image, 1.0, m, 0, light, dst);

	imshow("亮度/对比度调整", dst);

}

436542340711ac284e9713774dac4a9

具体代码如下:

完整代码

main.cpp

#include "opencv2/opencv.hpp"
#include "quickopencv.h"
#include <iostream>

using namespace cv;
using namespace std;

int main(int argc, char** argv) {
	Mat src = imread("C:/Users/LZQ/Desktop/lena.png"); //  B, G, R
	if (src.empty()) {
		printf("could not load image....\n");
		return -1;
	}

	imshow("输入窗口", src);

	QuickDemo qd;

	qd.tracking_bar_demo(src);
	
	waitKey(0);
	destroyAllWindows();
	return 0;
}

quickdemo.cpp

static void on_track(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.0;
	/*
		gamma范围变成[-50,50]
		这样我们就实现了增大/降低亮度,
	*/

	addWeighted(image, 1.0, m, 0, lightness, dst);

	imshow("亮度/对比度调整", 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);

	imshow("亮度/对比度调整", dst);

}

void QuickDemo::tracking_bar_demo(Mat& image) {

	namedWindow("亮度/对比度调整", WINDOW_AUTOSIZE);

	int lightness = 50;
	int max_light = 100;

	int contrast = 100;
	int max_contrast = 200;

	createTrackbar("Value Bar:", "亮度/对比度调整", &lightness, max_light, on_track, (void*)(&image));
	createTrackbar("Contrast Bar:", "亮度/对比度调整", &contrast, max_contrast, on_contrast, (void*)(&image));


}

quickdemo.h

#pragma once
#include <opencv2/opencv.hpp>

using namespace cv;

class QuickDemo {            //快速的演示文件 class类
public:

	void tracking_bar_demo(Mat& image);           //06

};

关于对比度的调整

为什么会变黑?

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

为什么会变白?

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

本课所用API查阅

creatTrackbar()

TrackbarCallback()

addWeighted()

dst = src1*alpha + src2*beta + gamma;

9e738260c5ff486bbef0600e58552c9d

posted @ 2023-01-12 14:42  L707  阅读(197)  评论(0编辑  收藏  举报