紧接上篇博客的序号
7. 计算两个YUV420P像素数据的PSNR
PSNR百度百科:https://baike.baidu.com/item/psnr/2925132?fr=aladdin,其主要用于对比两张图像,比如用于压缩后图片,去雾后图片的评价。
psnr的计算公式为:
其中n为每个像素存储所占的字节数,一般为8bit。mse为两幅图片的均值,计算公式为:
code
double yuv420_psnr(const char *url1, const char *url2, int w, int h){
FILE *fp1 = fopen(url1, "rb+");
FILE *fp2 = fopen(url2, "rb+");
unsigned char *pic1 = (unsigned char *)malloc(w*h);
unsigned char *pic2 = (unsigned char *)malloc(w*h);
fread(pic1, 1, w*h, fp1);
fread(pic2, 1, w*h, fp2);
double mse_sum = 0, psnr = 0;
for (int i=0; i<w*h; i++)
mse_sum += pow((pic2[i] - pic1[i]),2);
mse_sum /= (w * h);
psnr = 10 * log10(255.0*255.0/mse_sum);
free(pic1);
free(pic2);
fclose(fp1);
fclose(fp2);
return psnr;
}
说明
- 注意最后输出的时候%f,不要用%d
printf(“计算的psnr为:%.3f \n”, psnr);
- 这里为什么计算的时候只用了Y分量的值
…
8. 分离RGB24像素数据中的R、G、B分量
RGB24是首先存储第一个像素的R,G,B,然后是第二个像素的R,G,B,以此下去
code
int rgb24_split(const char *url, int w, int h){
FILE *fp = fopen(url, "rb+");
FILE *R = fopen("./output/rgb24_r.y", "wb+");
FILE *G = fopen("./output/rgb24_g.y", "wb+");
FILE *B = fopen("./output/rgb24_b.y", "wb+");
unsigned char *pic = (unsigned char *)malloc(w*h*3);
fread(pic, 1, w*h*3, fp);
for (int i=0; i < w*h*3; i += 3){
fwrite(pic+i, 1, 1, R);
fwrite(pic+i+1, 1, 1, G);
fwrite(pic+i+2, 1, 1, B);
}
free(pic);
fclose(fp);
fclose(R);
fclose(G);
fclose(B);
return 7;
}
说明:
- 产生结果的分辨率为500*500
9. 将RGB24格式像素数据封装为BMP图像
借鉴自原文 bmp图像内部实际上存储的就是RGB数据。封装成bmp文件之后就能用图片查看器进行查看了。
bmp图像格式的学问可参考:BMP格式详解
其中头信息是固定的,在写入bmp文件中时,赋上相应的值就可以。
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;