【图像处理基础】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:

#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;
}
View Code

使用memset函数对数组赋值不同类型(unsigned char/char/int)的问题分析

nv12转rgb:

// 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;
        }
    }
}
View Code

 

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博客

3. YUV数据格式 - 杨平 - 博客园

4. nv12转rgb_0点51 胜的博客-CSDN博客

5. YUV 格式详解-史上最全-CSDN博客

posted on 2023-02-14 18:28  鹅要长大  阅读(517)  评论(0编辑  收藏  举报

导航