转自:YUV与RGB互转各种公式 (YUV与RGB的转换公式有很多种,请注意区别!!!) - 罗引杰 - 博客园

关于写这篇文章的原因:

  本人也是摸索了很长时间才弄懂其中的原理,里面涉及的知识点太多了, 比如色彩空间, 比如Gamma, 里面还会涉及到很多的协议, 比如 BT601  BT709, BT2020,RP177 等, 一不小心就会写错, 然后色彩可能就不准确了, 可能偏白 偏黑或者偏色

自己也踩过很多坑, 然后把这些经验写出来, 防止大家踩重复的坑, 如果文章有不够严谨的地方, 请及时指出。

不同的色彩空间的转换公式是不一样的

  YUV与RGB互转的公式有很多, 不同的色彩空间的转换公式是不一样的,不同色彩空间的转换公式可以看我写的这篇文章: 计算不同色域下的RGB与YUV 以及 RGB与XYZ互转公式 - 简书

YUV 有多种表现形式

  除了色彩空间, 还需要注意YUV 的多种表现形式, 比如:

  YUV : YUV是一种模拟型号, Y∈ [0,1]   U,V∈[-0.5,0.5]

  YCbCr :也叫YCC或者Y'CbCr    YCbCr 是数字信号, 它包含两种形式, 分别为TV range 和 full range, TV range 主要是广播电视采用的标准, full range 主要是pc 端采用的标准, 所以full range 有时也叫 pc range

      TV range 的各个分量的范围为: YUV  Y∈[16,235]   Cb∈[16-240]   Cr∈[16-240]

      full range 的各个分量的范围均为: 0-255

  我们平时接触到的绝大多数都是 YCbCr (tv range) , ffmpeg 解码出来的数据绝大多数也是这个, 虽然ffmpeg 里面将它的格式描述成YUV420P , 实际上它是YCbCr420p tv range

  YUV转tv range:   Y' = 219.0*Y + 16 ;  Cb = U * 224.0 + 128;  Cr = V * 224.0 + 128;

关于为什么要将YUV量化为tv range 16-235 ?

  以下是维基百科摘抄的一段, 意思是tv range是为了解决滤波(模数转换)后的过冲现象,

  Y′ values are conventionally shifted and scaled to the range [16, 235] (referred to as studio swing or "TV levels") rather than using the full range of [0, 255] (referred to as full swing or "PC levels"). This practice was standardized in SMPTE-125M in order to accommodate signal overshoots ("ringing") due to filtering. The value 235 accommodates a maximal black-to-white overshoot of 255 − 235 = 20, or 20 / (235 − 16) = 9.1%, which is slightly larger than the theoretical maximal overshoot (Gibbs phenomenon) of about 8.9% of the maximal step. The toe-room is smaller, allowing only 16 / 219 = 7.3% overshoot, which is less than the theoretical maximal overshoot of 8.9%. This is why 16 is added to Y′ and why the Y′ coefficients in the basic transform sum to 220 instead of 255.[9] U and V values, which may be positive or negative, are summed with 128 to make them always positive, giving a studio range of 16–240 for U and V. (These ranges are important in video editing and production, since using the wrong range will result either in an image with "clipped" blacks and whites, or a low-contrast image.)

关于如何判断像素格式是否为tv range   Y(16-235)?

  1.  常见的一些解码帧结构体里面有color_range 参数, 如果为MPEG 或者 LIMITED 则表示为tv_range

  2. 在完全黑画面的时候打印出图像的Y数据, 如果Y=16左右    说明YCbCr 为tv range ,如果Y=0左右   说明YCbCr为 full range

以下是我推导的 BT601 与 BT2020 的公式, 包括各种形式, 比如 浮点 整形  等等。

一、 公式:基于BT.601-6 (NTSC 色域)

  BT601 UV(CbCr)的坐标图(量化后): (横坐标为u,纵坐标为v,左下角为原点)

通过坐标图我们可以看到UV(YUV六面体投影到UV坐标系)是一个旋转了一定角度的八边形(实际上是一个六面体在UV平面的投影),  U越大蓝色越蓝,V越大,红色越红。

以下具体为各种转换公式(该转换公式基于BT601 ,NTSC色域 )

1.小数形式, YUV   (  U∈[-0.5-0.5]  ,   R,G,B∈[0,1]  )

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

Y = 0.299*R + 0.587*G + 0.114*B;

U = (B-Y)/1.772;

V = (R-Y)/1.402;      
                                         
或写为:
Y =  0.299*R + 0.587*G + 0.114*B;

U = -0.169*R - 0.331*G + 0.5  *B ;

V =  0.5  *R - 0.419*G - 0.081*B;

2.整数形式(减少计算量)未量化     R,G,B~[0,255]   U,V~[-128,128]

R= Y + ((360 * (V - 128))>>8) ; 
G= Y - (( ( 88 * (U - 128)  + 184 * (V - 128)) )>>8) ; 
B= Y +((455 * (U - 128))>>8) ;

Y = (77*R + 150*G + 29*B)>>8;

U = ((-44*R  - 87*G  + 131*B)>>8) + 128;

V = ((131*R - 110*G - 21*B)>>8) + 128 ;

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

  [Y,U,V,1]T =  M[R,G,B,1]T 其中 M =

[ 0.2568, 0.5041, 0.0979, 16

-0.1479, -0.2896, 0.4375, 128

0.4375, -0.3666, -0.0709, 128,

0, 0, 0, 1 ]

  [R,G,B,1]T = M[Y,U,V,1]T      M =

1.1644   0              1.6019   -223.5521

1.1644   -0.3928   -0.8163   136.1381

1.1644   2.0253   0              -278.0291

0.0000   0.0000   0.0000     1.0000

4  tv range的公式写成整数的形式(减小计算量)   ( Y~(16,235)  U/V ~(16,240)  )

yuv --> rgb

R = (298*Y + 411 * V - 57344)>>8
G = (298*Y - 101* U - 211* V+ 34739)>>8
B = (298*Y + 519* U- 71117)>>8

rgb --> yuv

Y= (  66*R + 129*G  +  25*B)>>8 + 16

U= (-38*R  -    74*G  + 112*B)>>8 +128

V= (112*R -    94*G  -   18*B)>>8   + 128

5. YUV量化 与 非量化 互转

tvrange  转 fullrange

Y=(Y'-16   )*255/219 ;

U=(U'-128)*128/112;

V=(V'-128)*128/112;

full range 转 tv range  U(-128-127) ==>  U(16-240)

Y' = ((219*Y)>>8)   +   16;

U' = ((219*U)>>8)   + 128;

V' = ((219*V)>>8)   + 128;

 

二、. Rec2020 (BT2020) 下的YUV与RGB转换公式  (写成矩阵形式)

  BT2020 UV 的坐标图(量化后为CbCr): (横坐标为Cb,纵坐标为Cr,左下角为原点)

1.  BT2020 文档上的公式

即:

Y = 0.2627*R + 0.6780*G + 0.0593*B;

U = -0.1396*R - 0.3604*G + 0.5*B;

V = 0.5*R - 0.4598*G -0.0402*B;

矩阵形式

YUV RGB互转公式

[Y,U,V]T =  M[R,G,B]T   其中 M = 0.2627   0.6780   0.0593 ,     -0.1396   -0.3604   0.5000,    0.5000   -0.4598   -0.0402

     [R,G,B]T =  M[Y,U,V]T  其中 M = 1.0000   -0.0000   1.4746   1.0000   -0.1645   -0.5713   1.0000   1.8814   -0.0001

YCbCr(tv range) RGB互转公式

  [Y,U,V,1]T =  M[R,G,B,1]T   其中 M = 0.2256, 0.5823, 0.05093, 16,       -0.1222, -0.3154, 0.4375, 128 ,        0.4375, -0.4023, -0.0352, 128,       0,0,0,1

  [R,G,B,1]T = M[Y,U,V,1]T            M =1.1644,   0,   1.6853,   -234.3559,       1.1644,   -0.1881,   -0.6529,   89.0206,       1.1646,   2.1501,   0.0000,   -293.8542,       0.0000,   0.0000,   0.0000,   1.0000

tv range 互转公式写成整数形式

  [Y,U,V,1]T =  (M[R,G,B,1]T)>>8 其中 M  =

58, 149, 13, 4096,

-31,-81, 112, 32768,

112, -103, -9, 32768,

0, 0, 0, 256

  [R,G,B,1]T = (M[Y,U,V,1]T)>>8            M =

298, 0, 431, -59995,    

298, -48, -167, 22789,    

298, 550, 0, -75227,    

0, 0, 0, 256

YUV与RGB互转各种公式 (YUV与RGB的转换公式有很多种,请注意区别)相关推荐

  1. YUV与RGB互转各种公式 (YUV与RGB的转换公式有很多种,请注意区别!!!)

    一. 公式:基于BT.601-6 BT601 UV 的坐标图(量化后): (横坐标为u,纵坐标为v,左下角为原点) 通过坐标图我们可以看到UV并不会包含整个坐标系,而是呈一个旋转了一定角度的八边形, ...

  2. python rgb转yuv_YUV与RGB互转各种公式 (YUV与RGB的转换公式有很多种,请注意区别!!!)...

    一. 公式:基于BT.601-6 BT601 UV 的坐标图(量化后): (横坐标为u,纵坐标为v,左下角为原点) 通过坐标图我们可以看到UV并不会包含整个坐标系,而是呈一个旋转了一定角度的八边形, ...

  3. yuv rgb 互转 公式 及算法

    1 前言 自然界的颜色千变万化,为了给颜色一个量化的衡量标准,就需要建立色彩空间模型来描述各种各样的颜色,由于人对色彩的感知是一个复杂的生理和心理联合作用的过程,所以在不同的应用领域中为了更好更准确的 ...

  4. RGB转YUV----RGB色域与YUV色域的介绍

    以下文章来源于疯狂的FPGA,作者CrazyBingo.文章仅用于学术分享. 正式开始前,我们有必要介 绍一下色彩模型.色彩模型有很多种类,比如RGB三原色模型.CMYK四原色模型.YUV/YCbCr ...

  5. java rgb转yuv_RGB,CMY(K),YUV,YIQ,YCbCr颜色的转换算法(java实现)

    import java.lang.Math; import java.awt.*; public class ColorConverter{ public ColorConverter(){ } // ...

  6. 十六进制颜色和RGB互转

    2019独角兽企业重金招聘Python工程师标准>>> dd //颜色互转 //十六进制颜色值域RGB格式颜色值之间的相互转换//-------------------------- ...

  7. python修改rgb红色通道为黑白_如何将RGB图像(3通道)转换为灰度(1通道)并保存?...

    您的第一个代码块:import matplotlib.pyplot as plt plt.imsave('image.png', image, format='png', cmap='gray') 这 ...

  8. 转接口IC大全-RGB互转LVDS-LVDS或RGB转MIPI-MIPI转LVDS或RGB-LVD

    EDP输出 NCS8801 :LVDS转EDP.RGB转EDP封装QFN56 2560*1600用于手机.平板.转接板.液晶驱动板.广告机.可视门铃等等控制 器到显示设备上 MIPI输出 SDD282 ...

  9. 用java实现十六进制代码与RGB互转的颜色转换器

    最近在学java,学完基础不知道做点什么好,心血来潮想写个小工具,某天突然发现十六进制转RGB很麻烦,网上一搜工具不是很多,大多都是在线转换,要是某天没网了怎么办呢??我想可能太简单了吧,大家都不愿意 ...

最新文章

  1. 确定有限状态机和非确定有限状态机详解 包含Java实现源码(Nondeterministic finite automata)
  2. C#面向插件级别的软件开发 - 开源研究系列文章
  3. php类对象无法转还子符串问题,php – 类stdClass的对象无法转换为字符串
  4. SpringBoot - 探究Spring Boot应用是如何通过java -jar 启动的
  5. 中国非动物胶市场来产销需求及发展潜力研究报告2022版
  6. 产品汪们匿名自爆工资,看完心里好难受......
  7. AttributeError系列之:AttributeError: module 'scipy.misc' has no attribute 'imread'报错问题
  8. gson Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 1 column 2 path
  9. Xamarin.Forms 解决ListView高度问题
  10. Sql Server2005分离数据库
  11. js版in_array函数
  12. java的程序员工资一般多少_JAVA程序员工资一般是多少
  13. android offtime编程,OFFTIME - 做功课就憋玩手机了! - Android 应用 - iPad - 【最美应用】...
  14. 信号调制解调matlab仿真,基于matlab的psk信号调制解调仿真设计开题报告.doc
  15. docker compose自定义IP报错ERROR: Pool overlaps with other one on this address space
  16. mysql 创建用户、授权、修改密码
  17. 24个希腊字母 大小写 读音
  18. model vs shema vs instance vs store engine
  19. JS实现统一社会信用代码的效验(组织机构代码效验)
  20. Java1.5泛型指南中文版

热门文章

  1. 步进电机(四相五线为例子)步进角度和工作原理介绍
  2. 全国计算机二级c语言怎么复习,全国计算机二级C语言知识点复习:基本知识
  3. oracle中prot是什么意思,Oracle 10g及pro*c相关问题及解决方法
  4. ZORRO佐罗软件安装教程及一键新机使用方法详细简介
  5. Google 释出开源软件漏洞扫描工具 OSV-Scanner​
  6. 【moeCTF题解-0x04】Crypto
  7. BUGKU_WEB_never give up
  8. 计算机编程的11种趋势:
  9. Latex编辑论文常用package
  10. 【工具】动图展示 60+ 个前端常用插件库合集