比较YU12、I420、YV12、NV12、NV21、YUV420P、YUV420SP、YUV422P和YUV444P:理解并解析YUV420P的不同之处
最编程
2024-08-15 16:17:12
...
下面基于实例来理解Y,U,V分量的作用
先使用ffmpeg
将指定的图片转为yuv420p
格式
ffmpeg -i input.jpg -s 510x510 -pix_fmt yuv420p input.yuv
分离YUV分量
笔者使用的Clion
直接运行下面这段代码,分离出所需的文件
void split_yuv420(char *inputPath, int width, int height) {
FILE *fp_yuv = fopen(inputPath, "rb+");
FILE *fp_y = fopen("output_420_y.y", "wb+");
FILE *fp_u = fopen("output_420_u.y", "wb+");
FILE *fp_v = fopen("output_420_v.y", "wb+");
unsigned char *data = (unsigned char *) malloc(width * height * 3 / 2);
fread(data, 1, width * height * 3 / 2, fp_yuv);
//Y
fwrite(data, 1, width * height, fp_y);
//U
fwrite(data + width * height, 1, width * height / 4, fp_u);
//V
fwrite(data + width * height * 5 / 4, 1, width * height / 4, fp_v);
//释放资源
free(data);
fclose(fp_yuv);
fclose(fp_y);
fclose(fp_u);
fclose(fp_v);
}
笔者使用的是ubuntu系统
,因此运行yuvplayer.exe
文件,需要提前安装好wine
:sudo apt install wine
,运行yuvplayer
之后,需要先设置像素格式为Y
,否则你看到的图像可能会有问题
先看output_420_y.y
文件:(分辨率设置为510x510)
output_420_u.y
显示如下:(分辨率设置为255x255)
output_420_v.y
显示如下:(分辨率设置为255x255)
- 生成灰度图
上面的例子实际上已经生成了一个
灰度图
了,但是只保留了Y分量
,你如果直接用ffplay工具
查看会有问题,下面的函数将会生成一个标准的YUV文件
并且保留Y分量
,你可能会有疑问,为什么U分量和V分量
要写入0x80
,其实你可以参考上面的YUV转RGB的公式
,YUV数据是无法直接显示的,最终需要转成RGB显示,因此我这里是只需要保留Y分量
,忽略UV
分量的影响,因此根据上面的公式,我在U和V分量中都写入128
就是十六进制的0x80
- 保留Y分量(生成灰度图)
void yuv420p_y(char *inputPath, char *outputPath, int width, int height) {
FILE *inFile = fopen(inputPath, "rb+");
FILE *outFile = fopen(outputPath, "wb+");
unsigned char *data = (unsigned char *) malloc(width * height * 3 / 2);
fread(data, 1, width * height * 3 / 2, inFile);
//Y分量
fwrite(data, 1, width * height, outFile);
unsigned char *buffer = (unsigned char *) malloc(width * height / 4);
memset(buffer, 0x80, width * height / 4);
//U分量
fwrite(buffer, 1, width * height / 4, outFile);
//V分量
fwrite(buffer, 1, width * height / 4, outFile);
free(buffer);
free(data);
fclose(inFile);
fclose(outFile);
}
int main() {
yuv420p_y("/home/byhook/media/input.yuv", "/home/byhook/media/output.yuv", 510, 510);
return 0;
}
使用ffplay
来播放yuv格式
的文件:
ffplay -f rawvideo -video_size 510x510 output.yuv
要注意这里的分辨率不能错
上一篇: 深入解析YUV格式的原理和应用