[笔记]音视频学习之视音频数据处理入门《一》YUV、RGB(下)

简介: [笔记]音视频学习之视音频数据处理入门《一》YUV、RGB

RGB格式

参考 YUV数据格式与RGB数据格式

RGB,其实就是R(red:红色)+G(green:绿色)+B(blue:蓝色);像彩色电视或者计算机显示屏都是通过这三种颜色按照不同比例混合叠加而构成图像而显示的。红色、绿色和蓝色又称为三基色。之所以称为‘基色’是因为这三种颜色按照不同比例混合后几乎可以变成人类示例所能感知的所有颜色。

RGB555、RGB565、RGB24(RGB888)和RGB32

RGB555(高彩色)

RGB555是一种16位的RGB格式,R、G、B分量都用5位来表示,剩下的一位不用,存储格式如下图:

假设计算机中存储某一个像素点的变量为color, 数据类型为short.,那么则有:

R = color & 0x7C00, (获取高字节的5个bit)

G = color & 0x03E0, (获取中间5个bit)

B = color & 0x001F, (获取低字节5个bit)

RGB565

RGB565同样是一种16位的RGB格式,R和B分量用5位来表示,G分量用6位标志。存储格式如下图:

假设计算机中存储某一个像素点的变量为color, 数据类型为short, 那么则有:

R = color & 0xF800, (获取高字节的5个bit)

G = color & 0x07E0, (获取中间6个bit)

B = color & 0x001F, (获取低字节5个bit)

RGB24(真彩色)

RGB24是一种24位的RGB格式,R、G、B分量都用8位来表示,每位取值范围都为0-255。存储格式如下图:

假设计算机中存储某一个像素点的变量为color, 数据类型为int, 那么则有:

R = color & 0x000000FF,

G = color & 0x0000FF00,

B = color & 0x00FF0000,

RGB32(真彩色)

RGB32使用32位来表示一个像素,RGB分量各用去8位,剩下的8位用作Alpha通道或者不用。Alpha通道是一个8位的灰度通道,该通道用256级灰度来记录图像中的透明度信息,定义透明、不透明和半透明区域,其中白表示不透明,黑表示透明,灰表示半透明。其结构如下:

假设计算机中存储某一个像素点的变量为color, 数据类型为int,那么则有:

a、低8位保留

R = color & 0x0000FF00

G = color & 0x00FF0000,

B = color & 0xFF000000,

b、低8位为ALPHA值

R = color & 0x0000FF00,

G = color & 0x00FF0000,

B = color & 0xFF000000,

A = color & 0x000000FF,

RGB数据常见处理

(8) 分离RGB24像素数据中的R、G、B分量

与YUV420P三个分量分开存储不同,RGB24格式的每个像素的三个分量是连续存储的。一帧宽高分别为w、h的RGB24图像一共占用wh3 Byte的存储空间。RGB24格式规定首先存储第一个像素的R、G、B,然后存储第二个像素的R、G、B…以此类推。类似于YUV420P的存储方式称为Planar方式,而类似于RGB24的存储方式称为Packed方式。

思路

RGB24是8,8,8,一个像素3个字节,按BBBBBBBB GGGGGGGG RRRRRRRR 排列的 属于Packet格式。

读取3wh, 3个字节一读取,然后分别写在三个分别存储 R,G,B的文件里。最后用yuvplayer设置500*500分别打开r,g,b文件 会发现

原图

R数据图像如下所示。

G数据图像如下所示。

B数据图像如下所示。

(9) 将RGB24格式像素数据封装为BMP图像
BMP文件组成
BITMAP_FILE_HEADER
BITMAP_INFO_HEADER
RGB像素数据
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;

BMP采用的是小端(Little Endian)存储方式。

这种存储方式中“RGB24”格式的像素的分量存储的先后顺序为B、G、R。由于RGB24格式存储的顺序是R、G、B,所以需要将“R”和“B”顺序作一个调换再进行存储。

思路
  1. 将RGB数据前面加上文件头
  2. 将RGB数据中每个像素的“B”和“R”的位置互换。
(10) 将RGB24格式像素数据转换为YUV420P格式像素数据
思路

RGB24是packet格式(连续rgb rgb),yuv420p是planar格式(平面分块yyyy uu v)。故需要连续读写3字节RGB 根据公式算出yuv之后然后分别存y,u,v。

RGB到YUV的转换公式:

Y= 0.299R+0.587G+0.114B
U=-0.147
R-0.289G+0.463B

V= 0.615R-0.515G-0.100*B

//RGB to YUV420
bool RGB24_TO_YUV420(unsigned char *RgbBuf,int w,int h,unsigned char *yuvBuf)
{
  unsigned char*ptrY, *ptrU, *ptrV, *ptrRGB;
  memset(yuvBuf,0,w*h*3/2);
  ptrY = yuvBuf;
  ptrU = yuvBuf + w*h;
  ptrV = ptrU + (w*h*1/4);
  unsigned char y, u, v, r, g, b;
  for (int j = 0; j<h;j++){
    ptrRGB = RgbBuf + w*j*3 ;
    for (int i = 0;i<w;i++){
      r = *(ptrRGB++);
      g = *(ptrRGB++);
      b = *(ptrRGB++);
      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 ;
      *(ptrY++) = clip_value(y,0,255);
      if (j%2==0&&i%2 ==0){
        *(ptrU++) =clip_value(u,0,255);
      }
      else{
        if (i%2==0){
        *(ptrV++) =clip_value(v,0,255);
        }
      }
    }
  }
  return true;
}

以上是雷神的转换代码,指出其中

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 ;

是为了减少浮点运算 从而优化运算时间

以下代码是减少浮点和乘法运算

转自 图像处理-RGB24转YUV420遇到的坑以及执行效率对比

/**********************不包含浮点和乘法运算*****************/
#define RGB2Y_SHIFT(r,g,b) \
  ((unsigned char)((((r << 6) + (r << 3) + (r << 2) + r + (g << 7) + (g << 4) + (g << 2) + (g << 1) + (b << 4) + (b << 3) + (b << 2) + b) + 128) >> 8) + 16)
#define RGB2U_SHIFT(r,g,b) \
  ((unsigned char)(((-((r << 5) + (r << 2) + (r << 1)) - ((g << 6) + (g << 3) + (g << 1)) + ((b << 6) + (b << 5) + (b << 4))) + 128) >> 8) + 128)
#define RGB2V_SHIFT(r,g,b) \
  ((unsigned char)(((r << 7) + (r << 4) + (r << 3) + (r << 2) + (r << 1) - ((g << 7) + (g << 2)) - ((b << 4) + (b << 3) + (b << 1)) + 128) >> 8) + 128)
(11) 生成RGB24格式的彩条测试图
颜色 (R,G,B)
(255, 255, 255)
(255, 255, 0)
( 0, 255, 255)
绿 ( 0, 255, 0)
(255, 0, 255)
(255, 0, 0)
( 0, 0, 255)
( 0, 0, 0)
思路

分为8条色带,area = width /8 为一个区域,按如上表设置rgb值

[0,     area]为白色     
[area,area*2]为黄色 
[area*2,area*3]为青色  
[area*3,area*4]为绿色 
[area*4,area*5]为品色  
[area*5,area*6]为红色  
[area*6,area*7]为蓝色 
[area*7,area*8]为黑色

RGB和YUV转换

关于RGB与YUV之间的转换,有如下一条矩阵公式:

1)、YUV(256 级别) 可以从8位 RGB 直接计算:

Y = 0.299 R + 0.587 G + 0.114 B

U = - 0.1687 R - 0.3313 G + 0.5 B + 128

V = 0.5 R - 0.4187 G - 0.0813 B + 128

2)、反过来,RGB 也可以直接从YUV (256级别) 计算:

R = Y + 1.402 (Cr-128)

G = Y - 0.34414 (Cb-128) - 0.71414 (Cr-128)

B = Y + 1.772 (Cb-128)

注意:浮点数和乘法会比较耗时 转化为定点运算会比较快

HSV

相关文章
|
6月前
|
存储 编解码 数据处理
[笔记]音视频学习之视音频数据处理入门《一》YUV、RGB(上)
[笔记]音视频学习之视音频数据处理入门《一》YUV、RGB
102 0
|
存储 编解码 算法
音视频之音频知识入门
信息论的观点来看,描述信源的数据是信息和数据冗余之和,即:数据=信息+数据冗余。音频信号在时域和频域上具有相关性,也即存在数据冗余。将音频作为一个信源,音频编码的实质是减少音频中的冗余。自然界中的声音非常复杂,波形极其复杂,通常我们采用的是脉冲代码调制编码,即PCM编码。PCM通过抽样、量化、编码三个步骤将连续变化的模拟信号转换为数字编码。
500 0
|
2月前
|
存储 编解码 C++
C++ 音视频原理
C++ 音视频原理
|
5月前
|
存储 Cloud Native Linux
音视频 ffmpeg命令提取音视频数据
音视频 ffmpeg命令提取音视频数据
|
6月前
|
编解码 数据处理 数据格式
[笔记]音视频学习之视音频数据处理入门《四》AAC
[笔记]音视频学习之视音频数据处理入门《四》AAC
|
6月前
|
存储 编解码 数据处理
[笔记]音视频学习之视音频数据处理入门《二》PCM
[笔记]音视频学习之视音频数据处理入门《二》PCM
|
6月前
|
存储 编解码 缓存
[笔记]音视频学习之视音频数据处理入门《三》H264
[笔记]音视频学习之视音频数据处理入门《三》H264
|
6月前
[笔记]音视频学习之SDL篇《九》 渲染yuv数据
[笔记]音视频学习之SDL篇《九》 渲染yuv数据
|
6月前
|
编解码
[笔记]音视频之常见音视频封装格式组成
[笔记]音视频之常见音视频封装格式组成
|
6月前
[笔记]音视频学习之SDL篇《一》 渲染图片
[笔记]音视频学习之SDL篇《一》 渲染图片