图像基础知识:YUV和RGB

一、YUV

是一种颜色编码方法。通常使用在各个视频处理组件中。YUV的原理是把亮度与色度分离。

1、使用YUV的优点

  1. 彩色YUV图像转黑白YUV图像转换非常的简单,这一特性用在电视信号上。
  2. YUV数据总尺寸小于RGB格式。

2、各个字母代表的含义

Y 表示明亮度,即我们说的灰度值。
U 表示色度
V 表示浓度

值得一提的是,Y分量可以黑白电视机的所有影像信息。

3、常用的YUV格式

YUV的表示法称为A:B:C表示法:

  1. 4:4:4 表示完全取样。
  2. 4:2:2表示2:1的水平取样,没有垂直下采样。
  3. 4:2:0表示2:1的水平取样。
  4. 4:1:1表示4:1的水平取样,没用垂直下采样。

最常用Y:UV记录的比重通常为1:1或者2:1,DVD-Video是以YUV4:2:0的方式记录,也就是我们俗称的I420。

4、转换

YUV420P,Y,U,V三个分量都是平面格式,分为I420和YV12。I420格式和YV12格式的不同处在U平面和V平面的位置不同。在I420格式中,U平面紧跟在Y平面之后,然后才是V平面(即:YUV);但YV12则是相反(即:YVU)。

YUV420SP, Y分量平面格式,UV打包格式, 即NV12。 NV12与NV21类似,U 和 V 交错排列,不同在于UV顺序。
I420: YYYYYYYY UU VV =>YUV420P
YV12: YYYYYYYY VV UU =>YUV420P
NV12: YYYYYYYY UV UV =>YUV420SP
NV21: YYYYYYYY VU VU =>YUV420SP

1、NV21转NV12
private void swapNV21ToNV12(byte[] nv21, byte[] nv12, int width, int height){
	if(nv21 == NULL || nv12 == NULL)
		return ;
	System.arraycopy(nv21 ,  0 , nv12 , 0 , framezie);
	for(int j  = 0 ;  j < framesize / 2 ; j += 2){
		nv12[framesize + j + 1] = nv21[j + framesize];
		nv12[framesize + j] = nv21[j + framesize + 1];
	}
}
2、YV12转I420
 private void swapYV12toI420(byte[] yv12bytes, byte[] i420bytes, int width, int height){
	System.arraycopy(yv12bytes , 0 , i420bytes , 0 , width * height);
	System.arraycopy(yu12bytes , width * height + widhth * height  / 4 , i420bytes , width * height , width*height/4 );
	System.arraycopy(yv12bytes, width*height, i420bytes,width*height+width*height/4,width*height/4);
}
3、yv12转nv12
 void swapYV12toNV12(byte[] yv12bytes, byte[] nv12bytes, int width,int height){
 	int nLenV = width * height;
 	int nLenU = nLenY / 4;
 	System.arraycopy(yv12bytes , 0 , nv12bytes , 0 , width * height);
 	for(int i = 0 ; i < nLenU ; i++){
		nv12bytes[nLenY + 2 * i + 1] = yv12bytes[nLenY + i];
		nv12bytes[nLenY + 2 * i]=yv12bytes[nLenY + nLenU +i];
	}
 }
4、nv12转I420
 void swapNV12toI420(byte[] nv12bytes, byte[] i420bytes, int width,int height){
 	    int nLenY = width * height;
  	    int nLenU = nLenY/4;
  	    System.arraycopy(nv12bytes, 0, i420bytes, 0, width*height);
  	    for(int i = 0 ; i < nLenU ; i++){
			i420bytes[nLenY+i] = nv12bytes[nLenY+2*i+1];
			i420bytes[nLenY+nLenU+i] = nv12bytes[nLenY+2*i];
		}
 }

4、YUV图解

图片来自网络

  • 图片来自网络
    YUV 4:4:4采样,每一个Y对应一组UV分量。
    YUV 4:2:2采样,每两个Y共用一组UV分量。
    YUV 4:2:0采样,每四个Y共用一组UV分量。
1、NV12、NV21(属于YUV420)存储方式

NV12和NV21属于YUV420格式,是一种two-plane模式,即Y和UV分为两个Plane,但是UV(CbCr)为交错存储,而不是分为三个plane。其提取方式即Y’00、Y’01、Y’10、Y’11共用Cr00、Cb00。
YUV420 planar数据, 以720×488大小图象YUV420 planar为例,其存储格式是: 共大小为(720×480×3>>1)字节,分为三个部分:Y,U和V。
Y分量: (720×480)个字节
U(Cb)分量:(720×480>>2)个字节
V(Cr)分量:(720×480>>2)个字节

三个部分内部均是行优先存储,三个部分之间是Y,U,V 顺序存储。
即YUV数据的0--720×480字节是Y分量值,
720×480--720×480×5/4字节是U分量,
720×480×5/4 --720×480×3/2字节是V分量。

2、4 :2: 2 和4:2:0 转换

YUV4:2:2 —> YUV4:2:0 Y不变,将U和V信号值在行(垂直方向)在进行一次隔行抽样。 YUV4:2:0 —> YUV4:2:2 Y不变,将U和V信号值的每一行分别拷贝一份形成连续两行数据。

3、YUV420sp与YUV420p的数据格式

它们的UV排列在原理上是完全不同的。
420p它是先把U存放完后,再存放V,也就是说UV它们是连续的。
图片来自网络

  • 图片来自网络

420sp它是UV、UV这样交替存放的。
图片来自网络

  • 图片来自网络

有了上面的理论,我就可以准确的计算出一个YUV420在内存中存放的大小。
width * hight =Y(总和)
U = Y / 4
V = Y / 4
所以YUV420 数据在内存中的长度是 width * hight * 3 / 2。

4、旋转90度的算法
public static void rotateYUV24(byte[] src,byte[] des,int width,int height){
	   int wh = width * height;
	   //旋转
	    int k =0;
	    for(int i =0;i<width;i++){
		    for(int j=0;j<height;j++){
			    des[k] = src[width*j + i];
			    k++;
		    }
	    }
	    for(int i=0;i<width;i+=2){
		    for(int j=0;j<height/2;j++){
			    des[k]=src[wh + width*j +i];
			    des[k+1] = src[wh + width*j + i + 1];
			    k+=2;
		    }
    }
}
5、NV21和NV12

NV21 颜色空间排列 :YYYYYYYY VUVU
NV12 颜色空间排列 :YYYYYYYY UVUV
YUV420SP颜色排列顺序为:YYYYYYY UVUV

YUV420 是与NV12对应的。

二、RGB

R代表Red
G代表Green
B代表Blue

1、RGB565 与RGB888的区别

RGB565 就是R-5bit,G-6bit,B-5bit
RGB555 就是R-5bit,G-5bit,B-5bit
RGB888 就是R-8bit,G-8bit,B-8bit ;其实这就是RGB24

RGB565 是16位的,2个字节,5+6+5,第一字节的前5位是R,后三位+第二字节前三位是G,第二字节后5位是B。

RGB555 也是16位的,2个字节,RGB各5位,有1位未用。

RGB888 是24位的,3个字节。

三、YUV和RGB的转换公式

1.小数形式,full range

R = Y + 1.4075 * (V-128);
G = Y - 0.3455 * (U-128) - 0.7169*(V-128);
B = Y + 1.779 * (U-128);

Y = 0.299R + 0.587G + 0.114B;
U = (B-Y)/1.772; (U~(-128-127))
V = (R-Y)/1.402;
或写为:
Y = 0.299
R + 0.587G + 0.114B;
U = -0.169R - 0.331G + 0.5 B + 128; 注: +128 的含义是让UV的范围处于整数区间(0-255)
V = 0.5 R - 0.419G - 0.081
B + 128;

2.整数形式(减少计算量)full range

R= Y + ((360 * (V - 128))>>8) ;
G= Y - (( ( 88 * (U - 128) + 184 * (V - 128)) )>>8) ;
B= Y +((455 * (U - 128))>>8) ;
Y = (77R + 150G + 29B)>>8;
U = ((131
R - 110G - 21B)>>8) + 128 ;
V = ((-44R - 87G - 131*B)>>8) + 128;

3. 量化后的公式( Y~(16,235) U/V ~(16,240) ) tv range

yuv --> rgb
R = 1.155Y + 1.605 * V - 224
G = 1.168
Y - 0.393 * U - 0.823 * V+ 135.7
B = 1.168Y + 2.028 * U- 277.8
rgb --> yuv
Y= ( 66
R + 128G + 25B)>>8 + 16
U= (112R - 94G - 18B)>>8 + 128
V= (-38
R - 74G + 112B)>>8 +128

四、图片尺寸

1、720P、1080P、2K、4K的区别

目前主流清晰度主要分为720P(高清)、1080i 、1080P(全高清)、2K、4K。

1、720P分辨率为1280*720,长宽比16:9,P是Progressive逐行扫描的的意思。720P是一种在逐行扫描下达到1280×720的分辨率的显示格式。视频网站这种分辨率的比较多,兼顾了清晰度和画质。

2、1080i分辨率是1920*1080,长宽比16:9,i是interlace,代表隔行扫描。这种清晰度的视频格式比较少见。

1080P分辨率是1920*1080,长宽比16:9,P是Progressive逐行扫描的的意思.这也是目前主流的全高清格式。

3、4K分辨率38402160;是全高清(FHD.19201080)的4倍;高清(HD.1280*720)的9倍。

2、根据分辨率计算图片的大小

x bit=2的x次方
1byte=8bit
1K=1024byte
1M=1024K

看图片格式,如果是图片无损格式,这样计算:

灰度分辨率小于8Bit黑白:水平像素垂直像素1byte
灰度分辨率大于8Bit黑白:水平像素垂直像素2byte

彩色就复杂点,一个像素存储了红绿蓝三色的信息,通场灰度级别为8bit,计算方式为:水平像素垂直像素3byte

例如: 256x256的图片
如果是8bit黑白 256x256x1byte=65536 byte=64Kb
如果是24bit彩色 256x256x3byte=192Kb

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值