分离YUV420P

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int yuv420pSplit(char *url,int w,int h,int num){
unsigned char *pic=(unsigned char *)malloc(w*h*3/2);
FILE *fp=fopen(url,"rb+");

for(int i=0;i<num;i++){
fread(pic,1,w*h*3/2,fp);

pic;//Y w*h
pic+w*h;//U w*h/4
pic+w*h*5/4;//V w*h/4
}
free(pic);
close(fp);

return 0;
}

分离YUV444P

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int yuv444Split(char *url,int w,int h,int num){
unsigned char *pic=(unsigned char *)malloc(w*h*3);
FILE *fp=fopen(url,"rb+");

for(int i=0;i<num;i++){
fread(pic,1,w*h*3,fp);

pic;//Y w*h
pic+w*h;//U w*h
pic+w*h*2;//V w*h
}
free(pic);
close(fp);

return 0;
}

去掉YUV420P的颜色

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
int yuv420Gray(char *url,int w,int h,int num){
unsigned char *pic=(unsigned char *)malloc(w*h*3/2);
FILE *fp=fopen(url,"rb+");

for(int i=0;i<num;i++){
fread(pic,1,w*h*3/2,fp);
memset(pic+w*h,128,w*h/2);

//色度分量在偏置处理前的取值范围是-128至127,此时无色对应0。经偏置后变成0-255,此时无色对应为128
//因此只需要将U V设置成128
}
free(pic);
close(fp);

return 0;
}

YUV的PSNR计算

PSNR是最基本的视频质量评价方法,


RGB2BMP

BMP文件是由BITMAPFILEHEADER、BITMAPINFOHEADER、BGR像素数据共3个部分构成,它的结构如下图所示

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
typedef  struct  tagBITMAPFILEHEADER
{
unsigned short int bfType; //位图文件的类型,必须为BM
unsigned long bfSize; //文件大小,以字节为单位
unsigned short int bfReserverd1; //位图文件保留字,必须为0
unsigned short int bfReserverd2; //位图文件保留字,必须为0
unsigned long bfbfOffBits; //位图文件头到数据的偏移量,以字节为单位
}BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER
{
long biSize; //该结构大小,字节为单位
long biWidth; //图形宽度以象素为单位
long biHeight; //图形高度以象素为单位
short int biPlanes; //目标设备的级别,必须为1
short int biBitcount; //颜色深度,每个象素所需要的位数
short int biCompression; //位图的压缩类型
long biSizeImage; //位图的大小,以字节为单位
long biXPelsPermeter; //位图水平分辨率,每米像素数
long biYPelsPermeter; //位图垂直分辨率,每米像素数
long biClrUsed; //位图实际使用的颜色表中的颜色数
long biClrImportant; //位图显示过程中重要的颜色数
}BITMAPINFOHEADER;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
void RGB2BMP(const char * rgbUrl,int width,int height,const char * bmpUrl){
int i=0,j=0;
BITMAPFILEHEADER m_BMPHeader={0};
BITMAPINFOHEADER m_BMPInfoHeader={0};
char bfType[2]={'B','M'};
int header_size=sizeof(bfType)+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
unsigned char *rgb24_buffer=(unsigned char *)malloc(width*height*3);

FILE *fp_rgb24=fopen(rgb24path,"rb"),*fp_bmp=fopen(bmppath,"wb");
fread(rgb24_buffer,1,width*height*3,fp_rgb24);

m_BMPHeader.bfSize=3*width*height+header_size;
m_BMPHeader.bfbfOffBits=header_size;

m_BMPInfoHeader.biSize=sizeof(InfoHead);
m_BMPInfoHeader.biWidth=width;
//BMP storage pixel data in opposite direction of Y-axis (from bottom to top).
m_BMPInfoHeader.biHeight=-height;
m_BMPInfoHeader.biPlanes=1;
m_BMPInfoHeader.biBitcount=24;
m_BMPInfoHeader.biSizeImage=3*width*height;

fwrite(bfType,1,sizeof(bfType),fp_bmp);
fwrite(&m_BMPHeader,1,sizeof(m_BMPHeader),fp_bmp);
fwrite(&m_BMPInfoHeader,1,sizeof(m_BMPInfoHeader),fp_bmp);

//BMP save R1|G1|B1,R2|G2|B2 as B1|G1|R1,B2|G2|R2
//It saves pixel data in Little Endian
//So we change 'R' and 'B'
for(j =0;j<height;j++){
for(i=0;i<width;i++){
char temp=rgb24_buffer[(j*width+i)*3+2];
rgb24_buffer[(j*width+i)*3+2]=rgb24_buffer[(j*width+i)*3+0];
rgb24_buffer[(j*width+i)*3+0]=temp;
}
}
fwrite(rgb24_buffer,3*width*height,1,fp_bmp);
fclose(fp_rgb24);
fclose(fp_bmp);
free(rgb24_buffer);

return 0;
}

RGB2YUV420P

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
int RGB2YUV420P(unsigned char *rgbBuf,int w,int h,unsigned char *yuvBuf){
memset(yuvBuf,0,w*h*3/2);
unsigned char *pY,*pU,*pV,*pRGB;

pY=yuvBuf;
pU=yuvBuf+w*h;
pV=yuvBuf+w*h*5/4;

unsigned char y,u,v,r,g,b;
for (int j = 0; j<h;j++){
pRGB = rgbBuf + w*j*3 ;
for (int i = 0;i<w;i++){

r = *(pRGB++);
g = *(pRGB++);
b = *(pRGB++);
y = (unsigned char)( ( 66 * r + 129 * g + 25 * b + 128) >> 8) + 16 ;
u = (unsigned char)( ( -38 * r - 74 * g + 112 * b + 128) >> 8) + 128 ;
v = (unsigned char)( ( 112 * r - 94 * g - 18 * b + 128) >> 8) + 128 ;

//过滤一下y u v的大小 确保在0~255

*(pY++) = y;
if (j%2==0&&i%2 ==0){
*(pU++) =u;
}else{
if (i%2==0){
*(pV++) =v;
}
}
}

return 0;
}
/*
Y= 0.299*R+0.587*G+0.114*B
U=-0.147*R-0.289*G+0.463*B
V= 0.615*R-0.515*G-0.100*B
*/