RGB和YUV概念
RGB方式:(必定是Packet形式存放数据)
①RGB565(对于真彩的图像而言,肉眼在16bit的时候已经难以分辨了)
②RGB888(真彩色)
③ARBG=RGB+A透明度
本质:只记录R、G、B三基色各自的亮度
优势:方便数字化表达,广泛用于数字化彩色显示器,计算机编程等领域。
劣势:和传统的灰度图兼容不好,表达颜色的效率不高
RGB565和RGB888的转换
RGB888用unsigned int 32位字节存储
0 0 0 0 0 0 0 0 R7R6R5R4R3R2R1R0 G7G6G5G4G3G2G1G0 B7B6B5B4B3B2B1B0
RGB565用unsigned short 16位字节存储
R7R6R5R4R3 G7G6G5G4G3G2 B7B6B5B4B3
一.RGB888->RGB565(将几位清零)
方法只要提取相应单色高位即可(R5 G6 B5),但会导致低位的缺失,影响精度,而且无法恢复。
二.RGB565->RGB888
方法只要补充相应单色低位即可(R3 G2 B3)。
R7R6R5R4R3 G7G6G5G4G3G2 B7B6B5B4B3
👇
R7R6R5R4R3_000 G7G6G5G4G3G2_00 B7B6B5B4B3_000(未进行补偿的数据,在精度上会有损失)
👇
R7R6R5R4R3_R5R4R3 G7G6G5G4G3G2_G3G2 B7B6B5B4B3_B5B4B3(对于低位,用原始数据的低位进行补偿)
2、YUV和RGB的关系及转换
相互转换:用数学方法互相换算,是个典型的浮点运算过程。
YUV转灰度图:UV=128
rgb->BMP(文件头+信息头+像素数据)
按照小端存储顺序RRGB=0x00bbggrr调整然后写入像素数据
2种像素格式的转换公式(线性量化与否)
RGB常用颜色:常用颜色RGB、灰度值
其中: #808080 Gray 灰色 即R=G=B=128
根据换算公式:
Y = 0.299R+0.587G+0.114B
U = -0.169R-0.331G+0.5B+128
V = 0.5R-0.419G-0.081B+128
↓↓↓
由灰度图像R=G=B可知:Y=R=G=B, U=128, V=128.
故YUV420P去颜色(变成灰度图)//UV颜色→设置为128
memset(pic+wh,128,wh/2);//把后面部分的1/3像素’UV’数据转换成灰度色
将RGB24格式像素数据封装为BMP图像
BMP文件结构:
1、BITMAPFILEHEADER文件头(14byte)
2、BITMAPINFOHEADER信息头(10byte)
3、调色板(RGB24真彩不存在调色板)
4、RGB像素数据
MSDN中有说明:RGB文件存储性质-大端存储【0xbgr ,高位的R处于低地址,低位的B处于高地址
于是在普遍的小端存储的模式下,读取到的顺序正好就是 r g b 】
实例:RGB数据封装成BMP文件:
//BITMAPFILEHEADER实际包含‘BM’,只是这里将其拆开而已
/**
* Convert RGB24 file to BMP file
* @param rgb24path Location of input RGB file.
* @param width Width of input RGB file.
* @param height Height of input RGB file.
* @param url_out Location of Output BMP file.
*/
int simplest_rgb24_to_bmp(const char *rgb24path,int width,int height,const char *bmppath){
typedef struct
{
long imageSize;//=文件头(包括起始的'BM')+信息头+像素数据
long blank;
long startPosition;//有效数据相较起始位置偏移量
}BmpHead