FFmpeg滤镜: 调整视频的亮度-对比度-饱和度

亮度是指图片的明暗程度,对比度是指图片明暗的差异,饱和度则是指图片颜色的饱满程度。在计算机中每个图片上的像素点都由三个字节来进行表示,分别代表着像素的RGB数据。

图片上每个像素的每种颜色都可以有从0到255的变化,数值越高,颜色的亮度越大,因此当改变一张图片的亮度时,实际上就是同时改变图片上每个像素的每个颜色的数值,提高图片的亮度,就是将图片上每个像素的每个颜色的数值调大,数值调小则会降低图片的亮度。

对于图片上每个像素的每个颜色值,以127为界,小于127的数值算暗,大于127的算亮。如果将图片上每个像素的颜色值小于127的所有颜色值减小,而将图片上每个像素的颜色值大于127的所有颜色值加大,我们看到的就是图片对比度的调整,也就是让图片中暗的部分越暗,而将图片中亮的部分越亮。

图片中每个像素都有三个字节表示自己的颜色,但是对于彩色照片来说每个像素总有一个突出的颜色,让你看到这个像素是红的还是绿的,提高这个突出的颜色值,就可以让红的更红,绿的更绿,简单的说这就是提高图片的饱和度,当然反过来调整,也可以降低饱和度。

参考链接

针对视频的亮度、对比度、饱和度的调整,FFmpeg提供了对应的调整滤镜,通过滤镜我们可以很方便的调整视频的色彩系数。对应的滤镜说明如下:

//contrast对比度,取值范围-1000~1000 默认为1
//brightness亮度,取值范围为-1.0~1.0 默认为0
//saturation饱和度,取值范围为0.0~3.0 默认为1.0
eq=contrast=100.0:brightness=0.5:saturation=2.0

FFmpeg调用色彩滤镜

FFmpeg调用视频滤镜的方法如下,在使用的时候我们可以给对应的色彩系数绑定一个变量从而实现对应参数的动态调整.

int InitFilter(AVCodecContext * codecContext)
{
    
    
	char args[512];
	int ret = 0;
	//缓存输入和缓存输出
	const AVFilter *buffersrc = avfilter_get_by_name("buffer");
	const AVFilter *buffersink = avfilter_get_by_name("buffersink");

	//创建输入输出参数
	AVFilterInOut *outputs = avfilter_inout_alloc();
	AVFilterInOut *inputs = avfilter_inout_alloc();

	//滤镜的描述
	string  filters_descr = "eq=contrast=100.0:brightness=0.5:saturation=2.0";
	enum AVPixelFormat pix_fmts[] = {
    
     AV_PIX_FMT_YUV420P, AV_PIX_FMT_YUV420P };

	//创建滤镜容器
	filter_graph = avfilter_graph_alloc();
	if (!outputs || !inputs || !filter_graph)
	{
    
    
		ret = AVERROR(ENOMEM);
		goto end;
	}

	//初始化数据帧的格式
	sprintf_s(args, sizeof(args),
		"video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
		codecContext->width, codecContext->height, codecContext->pix_fmt,
		codecContext->time_base.num, codecContext->time_base.den,
		codecContext->sample_aspect_ratio.num, codecContext->sample_aspect_ratio.den);

	//输入数据缓存
	ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
		args, NULL, filter_graph);

	if (ret < 0) {
    
    
		goto end;
	}

	//输出数据缓存
	ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",
		NULL, NULL, filter_graph);

	if (ret < 0)
	{
    
    
		av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");
		goto end;
	}

	//设置元素样式
	ret = av_opt_set_int_list(buffersink_ctx, "pix_fmts", pix_fmts,
		AV_PIX_FMT_YUV420P, AV_OPT_SEARCH_CHILDREN);
	if (ret < 0)
	{
    
    
		av_log(NULL, AV_LOG_ERROR, "Cannot set output pixel format\n");
		goto end;
	}

	//设置滤镜的端点
	outputs->name = av_strdup("in");
	outputs->filter_ctx = buffersrc_ctx;
	outputs->pad_idx = 0;
	outputs->next = NULL;

	inputs->name = av_strdup("out");
	inputs->filter_ctx = buffersink_ctx;
	inputs->pad_idx = 0;
	inputs->next = NULL;

	//初始化滤镜
	if ((ret = avfilter_graph_parse_ptr(filter_graph, filters_descr.c_str(),
		&inputs, &outputs, NULL)) < 0)
		goto end;

	//滤镜生效
	if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
		goto end;
end:
	//释放对应的输入输出
	avfilter_inout_free(&inputs);
	avfilter_inout_free(&outputs);
	return ret;
}

调整效果图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/yang1fei2/article/details/128272452