下图对于理解处理视频过程 完美。可以解决小白一些疑惑
今天从hello word开始学习,希望可以走很远,不要只留在第一课。
一:先普及下基础知识,图像存储的一种格式yuv,就是矩阵。yuv有2中储存格式planar和packed。
planar是先连续存储所有像素点的y,再连续存储所有像素点的u,再存存储剩下的v。{y0y1y2y3y4....}{u0u1u2u3u4...}{v0v1v2v3v4....}
packed是每个像素点的yuv连续交叉存储的 {y0u0v0}{y1u1v1},{y2u2v2},{y3u3v3}{y4u4v5}.....
y表示亮度(luma或luminance),大神说也叫灰度值。
u和v是色度(chroma或者chromimance),影像的色彩和饱和度,用于指定像素的颜色。
yuv是一种颜色编码方法,主要用于电视系统和模拟视频领域,它将亮度信息y与色彩信息uv分离,没有uv一样可以显示图像。
只不过是黑白的,这样的设计很好的解决了彩色电视和黑白电视机的兼容问题(我自己都被惊讶掉了,原来是为黑白电视兼容)。
并且yuv不像rgb那样要求三个独立的视频信号同事传输,所以用yuv方式传送占用极少的频宽(我理解的是以前播放录像要用三个口的那个线红白绿头,现在一个线头就ok了)
yuv码流的存储格式其实和采样率有关系,主流的采样有三种4:4:4 , 4:2:2 , 4:2:0。具体是什么原理 不深究了,码流数据按照转换yuv通过上述比例采样,一个像素点
- YUV 4:4:4采样,每一个Y对应一组UV分量。
- YUV 4:2:2采样,每两个Y共用一组UV分量。
- YUV 4:2:0采样,每四个Y共用一组UV分量。
黑色代表y亮度值,u和v用小圈代表
packed模式
planar格式
关于yuv占用体积计算,跟存放模式有关系。用一个500*215的来举例,
yuv-422 占得体积y:500*215 u:500*215 /2 v:500*215/2 一共500*215*2
yuv-420 占得体积y:500*215 u:500*215 /4 v:500*215/4 一共500*215*3/2
排列模式还有yu12,yv12,nv12,nu12等,各种格式对应结果都在上述三种范围。
二:RGB格式数据转化为BMP图像
1)将RGB数据前面加上文件头。
2)将RGB数据中每个像素的“B”和“R”的位置互换。
BMP文件是由BITMAPFILEHEADER、BITMAPINFOHEADER、RGB像素数据共3个部分构成,如图所示。
BITMAPFILEHEADER
BITMAPINFOHEADER
RGB像素数据
BMP图像存储方式中“RGB24”格式的像素的分量存储的先后顺序为B、G、R。由于RGB24格式存储的顺序是R、G、B,所以需要将“R”和“B”顺序作一个调换再进行存储。
三:rgb24转为yuv420p
rgb24的一个像素点转化为yuv420p像素点公式
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
代码如下
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);
}
}