YUV420转YUV444

在最近的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
#include

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


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






你可能感兴趣的:(图像处理,图像处理)