【图像处理基础】YUV格式理解
1. YUV数据格式简介
YUV,是一种颜色编码方法。常使用在各个视频处理组件中。“Y”表示明亮度(Luminance、Luma),“U” 和 “V” 则是色度、浓度(Chrominance、Chroma)。
NV21 和 NV12 是 YUV 的两种具体编码形式,以一个 2*2 像素大小的图为例,则排列如下:
NV21:YYYYVUVU
NV12:YYYYUVUV
2. YUV格式优点
1)可以避免相互干扰(没有 UV 信息一样可以显示完整的图像,因而解决了彩色电视与黑白电视的兼容问题);
2)降低色度的采样率而不会对图像质量影响太大,降低了视频信号传输时对频宽(带宽)的要求。
3. YUV格式类别
打包(packed)格式:Y、U、V交叉存储,如YUYV,即1个plane;
平面(planar)格式:Y、U、V全部连续存储,如I420、YV12,即3个plane;
半平面(semi-planar)格式: Y连续存储,U、V交叉存储,如NV21、NV12,即2个plane;
4. YUV采样表示法
5. YUV数据存储
5.1 4:4:4格式
AYUV
5.2 4:2:2格式
YUY2
图像大小w*h,其中 Y(w*h),U/V(w/2 * h)
数据大小: w*h + w/2 * h * 2 = w*h*2;
UYVY
5.3 4:2:0格式
5.3.1 NV12
与NV21的区别是,U/V的位置关系,NV12是UVUV,NV21是VUVU;
* RGB转YUV-NV12: 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 * YUV-NV12转RGB R = Y + 1.402 (V - 128) # 1.4075 G = Y - 0.34414 (U - 128) - 0.71414 (V - 128) B = Y + 1.772 (U - 128) # 1.770
rgb转nv12:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <string.h> void raw8ToNv12(unsigned char* raw8data, unsigned char* nv12data){ int w = 3, h = 4; for(int i =0; i< w*h; i++){ nv12data[i] = raw8data[i]; } memset(nv12data+w*h, 128, w*h/2); for (int i=0; i<18; i++){ std::cout << "nv12data f: " << i << " data: "<< (int)(nv12data[i]) << std::endl; } } int main() { // int w = 3, h = 4; unsigned char raw8data[12] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l'}; std::cout << "raw8data: " << raw8data << std::endl; unsigned char nv12data[18]; raw8ToNv12(raw8data, nv12data); std::cout << "nv12data: " << nv12data << std::endl; }
使用memset函数对数组赋值不同类型(unsigned char/char/int)的问题分析
nv12转rgb:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// from nv12 uchar data to rgb uchar data. void nv12ToRgb(unsigned char* nv12data, unsigned char* rgbdata, uint32_t width, uint32_t height) { uint16_t r, g, b; uint16_t y, u, v; for(uint32_t i=0; i<height; i++) { for(uint32_t j=0; j<width; j++) { y = nv12data[i * width + j]; u = nv12data[width * height + i/2 * width + j/2 *2]; v = nv12data[width * height + i/2 * width + j/2 *2 + 1]; r = y + 1.4075 *(v-128); g = y - 0.344 * (u-128) - 0.714 * (v-128); b = y + 1.770 * (u-128); if(r>255) r = 255; if(g>255) g = 255; if(b>255) b = 255; if(r<0) r = 0; if(g<0) g = 0; if(b<0) b = 0; rgbdata[(i * width + j) * 3 + 0] = (unsigned char)r; rgbdata[(i * width + j) * 3 + 1] = (unsigned char)g; rgbdata[(i * width + j) * 3 + 2] = (unsigned char)b; } } }
5.3.2 NV21
图像大小w*h,其中 Y(w*h),U/V(w/2 * h/2)
数据大小: w*h + w/2 * h/2 * 2 = w*h*3/2;
5.3.3 IMC1
5.3.4 IMC3
6. YUV数据转换
参考
1. NV12等常用YUV数据格式_泠山的博客-CSDN博客_nv12;
2. 求 yuv( nv12 / nv21 ) 图片各通道的均值_阿飞__的博客-CSDN博客;
完
心正意诚,做自己该做的事情,做自己喜欢做的事情,安静做一枚有思想的技术媛。
版权声明,转载请注明出处:https://www.cnblogs.com/happyamyhope/