YUV420转YUV444

news/2025/3/26 3:35:48/

在最近的CCP测试中,需要使用YUV444的测试序列,而平时使用的全都是YUV420的序列,因此自己尝试用C写了一个YUV420转YUV444的程序。


1、YUV分三种采样方式:


YUV444:对于每一个像素都对应一个Y分量、一个U分量、一个V分量。

YUV422:对于一个像素都对应一个Y分量,但是每两个像素(或者说Y分量)对应一个U分量和一个V分量。

YUV420:对于一个像素都对应一个Y分量,但是每四个像素(或者说Y分量)对应一个U分量和一个V分量。


2、YUV的存储格式:

YUV在存储时是以数组的形式存储的,可以看做连续的三个数组。三个数组分别单独存储Y、U、V分量。

以一副1920*1080的YUV444图像为例,如图,YUV分量分别存储在大小为1920*1080的数组中,因此对于数据的操作十分简单。


同理对于YUV420和YUV422,只是U和V的数组大小的不同而已。

总数据量来看,YUV444需要存储1920*1080*3个值,YUV422需要存储1920*1080*2个值,YUV420需要存储1920*1080*3/2个值。


3、YUV420转YUV444主要思路

YUV420转YUV444,实际就是对色度进行上采样,最为简单的实现思路是直接填充。

以U分量为例,其序列如下


对U进行插值,每个田字格四个位置使用一个U值。


在代码中,可以直接通过对数组循环赋值即可完成。

对V分量的操作相同。

填充方式实现简单,效果较差,可以通过插值来完成上采样。

4、代码实现

YUV420转YUV444函数:

#include "YUV.h"
#include<malloc.h>
#include<memory.h>typedef unsigned char	UINT8;
typedef signed short	INT16;
typedef signed int		INT32;#define Y_SIZE          (PIC_W*PIC_H)
#define YUV420_SIZE        (Y_SIZE*3/2)       //4:2:0格式
#define YUV422_SIZE        (Y_SIZE*2)       //4:2:2格式
#define YUV444_SIZE        (Y_SIZE*3)      //4:4:4格式int YUV2YUV(unsigned char *yuv_buff,unsigned char *yuv2_buff, int PIC_W, int PIC_H)
{UINT8 *y_buf=NULL;y_buf = (UINT8*)malloc(YUV444_SIZE);if(y_buf == NULL){printf("Error: malloc buf.\n");exit(1);}int h,v;//Y分量转换;for(v=0; v<PIC_H; v++){for(h=0; h<PIC_W; h++){y_buf[v*PIC_W+h] = yuv_buff[(v*PIC_W+h)];}}//UV分量转换for(v=0; v<PIC_H; v+=2){for(h=0; h<PIC_W; h+=2){y_buf[PIC_H*PIC_W+v*PIC_W+h] = yuv_buff[PIC_H*PIC_W+v/2*PIC_W/2+h/2];y_buf[PIC_H*PIC_W+v*PIC_W+h+1] = yuv_buff[PIC_H*PIC_W+v/2*PIC_W/2+h/2];y_buf[PIC_H*PIC_W+(v+1)*PIC_W+h] = yuv_buff[PIC_H*PIC_W+v/2*PIC_W/2+h/2];y_buf[PIC_H*PIC_W+(v+1)*PIC_W+h+1] = yuv_buff[PIC_H*PIC_W+v/2*PIC_W/2+h/2];y_buf[2*PIC_H*PIC_W+v*PIC_W+h] = yuv_buff[5*PIC_H*PIC_W/4+v/2*PIC_W/2+h/2];y_buf[2*PIC_H*PIC_W+v*PIC_W+h+1] = yuv_buff[5*PIC_H*PIC_W/4+v/2*PIC_W/2+h/2];y_buf[2*PIC_H*PIC_W+(v+1)*PIC_W+h] = yuv_buff[5*PIC_H*PIC_W/4+v/2*PIC_W/2+h/2];y_buf[2*PIC_H*PIC_W+(v+1)*PIC_W+h+1] = yuv_buff[5*PIC_H*PIC_W/4+v/2*PIC_W/2+h/2];}}memcpy(yuv2_buff,y_buf,YUV444_SIZE); free(y_buf);y_buf=NULL;return 1;		}


main函数如下,主要完成对YUV数据的读取和存储:

#include "YUV.h"#define _CRT_SECURE_NO_WARNINGS
#define	IMAGEWIDTH 1024    //图像的宽
#define	IMAGEHEIGHT 768    //高int main(int argc, char *argv[])
{//读入参数,共有3个参数if( argc != 3 ) {printf ("Please input infile and outfile!\n");exit(-1);}FILE * input_yuvfile;    //输入YUV420图像FILE * output_yuvfile;     //输出YUV444图像if(NULL == (input_yuvfile =  fopen(argv[1], "rb"))){printf("File input is can't open!\n");return -1;}if(NULL == (output_yuvfile = fopen(argv[2], "wb"))){printf("File output is can't open!\n");return -1;}int readsize;unsigned char *in_buff;in_buff =  (unsigned char *)malloc(IMAGEWIDTH*IMAGEHEIGHT*sizeof(unsigned char)*3/2); unsigned char *out_buff,*yuv_buff;out_buff=(unsigned char *)malloc(IMAGEWIDTH*IMAGEHEIGHT*sizeof(unsigned char)*3);memset (out_buff,0,IMAGEWIDTH*IMAGEHEIGHT*sizeof(unsigned char)*3);yuv_buff=(unsigned char *)malloc(IMAGEWIDTH*IMAGEHEIGHT*sizeof(unsigned char)*3/2);memset (yuv_buff,0,IMAGEWIDTH*IMAGEHEIGHT*sizeof(unsigned char)*3/2);while(1){readsize=fread(in_buff,1 , IMAGEWIDTH*IMAGEHEIGHT*3/2,input_yuvfile);if(readsize<IMAGEWIDTH*IMAGEHEIGHT*3/2) //读取的数据量少于IMAGEWIDTH*IMAGEHEIGHT*3/2时跳出break;memcpy(yuv_buff,in_buff,IMAGEWIDTH*IMAGEHEIGHT*sizeof(unsigned char)*3/2);YUV2YUV(yuv_buff, out_buff,IMAGEWIDTH,IMAGEHEIGHT);fwrite(out_buff,1,IMAGEWIDTH*IMAGEHEIGHT*3,output_yuvfile);}free(in_buff);in_buff=NULL;free(out_buff);out_buff=NULL;free(yuv_buff);yuv_buff=NULL;fclose(input_yuvfile);fclose(output_yuvfile);}







http://www.ppmy.cn/news/121768.html

相关文章

Linux V4l2驱动 -- 框架概述

V4l2框架简述 1 硬件 常用的电脑摄像头是USB接口&#xff0c;主流的智能手机摄像头是MIPI接口&#xff0c;另外还有像树莓派等硬件使用的CSI接口的设备。常用的智能手机Camera采用的MIPI接口&#xff0c;电路框架以及电路图如下 Camera传感器分前后两个&#xff0c;分别为前置…

NV12视频格式与YUV420P格式转化

视频raw data格式分为YUV和RGB格式&#xff0c;常见的YUV 格式有YUV420、YUV422、YUV444等&#xff0c;常见的RGB格式有RGB和RGBA等&#xff0c;根据内存存储方式的不同&#xff0c;YUV420又分为YUV420P和YUV420SP&#xff0c;分别是3平面存储和2平面存储&#xff1b; 常见的N…

YUV420(I420)与YV12的区别,YUV420p与YUV420区别

YUV420&#xff0c; I420 意义:每像素12bit 或表示为IYUV,数码摄像机专用表示法. 这里需要注意的是&#xff0c;虽然YV12也是&#xff08;4&#xff1a;2&#xff1a;0&#xff09;&#xff0c;但是YV12和I420的却是不同的&#xff0c;在存储空间上面有些区别。如下&#xff1…

YUV420之YV12格式以及yuv422格式的显示

这段时间&#xff0c;在做一个动态配置录相预览帧上的字符样式以及颜色等等的功能。因为要移植到几个不同的项目上&#xff0c;刚好这几个项目的camera原始预览数据格式&#xff0c;一个为yv12&#xff0c;一个yuv422&#xff0c;所以将这两种格式都做了送显的处理。先上一段传…

RGB、YUV420、NV21、I420编码区别

一、RGB与YUV 首先了解视频编码为什么使用YUV420而不是rgb。那么需要了解两者的原理&#xff0c;看图说话 所以从内存的角度来说&#xff0c;yuv单位像素使用的内存更低,但是两者表示的效果是一致的&#xff0c;也可以认为rgb过度绘制了&#xff0c;把人眼无法分辨的区域也进行…

YV12和I420的区别 yuv420和yuv420p的区别

YV12和I420的区别 YV12和I420的区别 一般来说&#xff0c;直接采集到的视频数据是RGB24的格式&#xff0c;RGB24一帧的大小size&#xff1d;widthheigth3 Bit&#xff0c;RGB32的size&#xff1d;widthheigth4&#xff0c;如果是I420&#xff08;即YUV标准格式4&#xff1a;2&a…

YUV420P格式分析

YUV格式通常有两大类&#xff1a;打包&#xff08;packed&#xff09;格式和平面&#xff08;planar&#xff09;格式。前者将YUV分量存放在同一个数组中&#xff0c;通常是几个相邻的像素组成一个宏像素&#xff08;macro-pixel&#xff09;&#xff1b;而后者使用三个数组分开…

详解YUV420数据格式

欢迎Follow我的GitHub, 关注我的CSDN. 其余参考Android目录.技术微信公众号&#xff1a;程序员小乐 详解YUV420数据格式 原文地址&#xff1a;http://www.cnblogs.com/azraelly/archive/2013/01/01/2841269.html 1. YUV简介 YUV定义&#xff1a;分为三个分量&#xff0c;“Y”表…