视觉媒体通信作业记录(三)视频编解码

作业要求

使用现有编码器ffmpeg,将原始视频进行编码、解码得到重建视频,并分析压缩码率与视频质量的关系;

实现方案

编码部分:
利用摄像头采集一段图像信息,转换为yuv420格式,调用库函数进行h.265编码,并保存
解码部分:
对编码得到的.H265调用库函数进行解码,得到yuv文件并保存,再利用第一次作业的yuv播放器,对解码得到的yuv文件进行格式转换并显示;

实现结果

编码

	if (firstencode)
		{
    
    
			firstencode = false;
			ffmpegobj.Ffmpeg_Encoder_Init();
			cout << "Init!" << endl;
			ffmpegobj.Ffmpeg_Encoder_Setpara(AV_CODEC_ID_H265, frame.cols, frame.rows);
			cout << "Setpara!" << endl;
		}
		ffmpegobj.Ffmpeg_Encoder_Encode(f_yuv, f, frame.data);

我们设置码率为1024kps,视频帧数为25,一个分组大小为10,像素格式为YUV420P,以及一些其他参数;
在这里插入图片描述

如下图所示,共编码了125帧,其中I帧13个,P帧50个,B帧62个,共花费了7.45s,编码的平均帧率为16.78fps,平均码率为961.90kb/s
在这里插入图片描述

解码

	decodeobj.Ffmpeg_Decoder_Readpara(filepath);
	decodeobj.Ffmpeg_Decoder_Decode(f_yuv);
	fclose(f_yuv);

解码结果,如下图所示,视频帧数为设置的25帧,分辨率为640X480,像素格式为YUV420P;
在这里插入图片描述

分析压缩码率与视频质量关系:

码率(Bitrate) 指每秒传输的数据位数,单位kbps 即千位每秒,这里的位指的是二进制位基本的算法是:
每秒传输的数据量=码率/8
·视频文件体积=码率/8x视频时长(s)=每秒传输的数据量*视频时长(s)
比如500Kbps,也就是每秒传输62K大小的数据,假如按照帧率30fps进行计算,那么每张图片大小约为2kb大小
也就是说视频时长和固定的情况下,码率越高,文件体积越大,同时视频显示的有效像素越多,视频更加接近原始分辨率,反之码率越低,文件体积越小,但是视频能显示的有效像素就越少,原本1080p的分辨率,每帧图像至少需要占用20k的数据量,但是码率过低每帧只能分配2K的量,此时像素点显示不全,就会造成视频模糊不清晰
因此,我们可以得到结论,码率跟视频质量有关系.相同的视频编码方式下, 码率越高肯定画面越清晰. 但是高到一定值, 再往上的画面改善程度就不明显了, 只会增大文件体积.所以码率选的合适, 才可以保证清晰度又保持文件不会太大.

我们分别在64kbps,256kbps,1024kbps三种码率下,进行实验如下;
64kbps时
在这里插入图片描述
在这里插入图片描述
由上,我们可以看出,当码率过低时,画面质量很差,随着码率升高,画面质量变好,当码率高到一定值, 再往上的画面改善程度就不明显了。

收获与心得

在本次实践中,我了解并学习了ffmpeg的使用,对opencv和ffmpeg的区别有了更加清晰的认识,opencv专注图像处理,以及图像相关的处理应用,主要做一些识别、跟踪、机器学习应用,而ffmpeg专注处理视频、音频的编解码和转换,主要应用是编解码和格式转换。

猜你喜欢

转载自blog.csdn.net/weixin_45774698/article/details/126093539