首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >从rec中正确转换。709转至sRGB

从rec中正确转换。709转至sRGB
EN

Stack Overflow用户
提问于 2013-07-08 21:37:50
回答 2查看 5.4K关注 0票数 7

如何正确转换存储为Y‘’CrCb的颜色(使用rec )。到sRGB?

我正在处理HDTV视频,我正在使用libavcodec提取原始数据。虽然我已经成功地进行了转换,但我仍然没有信心我做的是正确的。VLC提供一个结果,在Gimp中使用另一个结果中的“组合”结果进行转换,使用来自web的代码也是不一致的。所以我还没有找到一个可靠的参考资料。

我的研究和目前的最佳选择如下。(数值为浮点,范围为0.0-1.0)我最不确定的是伽马校正。它比我想象的要轻一点,但我也不能说它看起来不对.

演播室-摆动移除

8位从16到235不等。Cr和Cb在16到240之间,中心在128。

代码语言:javascript
复制
y = (y - (16 / 255.0)) * ( 1 + 16.0 / 255.0 + (256-235) / 255.0 );
u = (u - (16 / 255.0)) * ( 1 + 16.0 / 255.0 + (256-240) / 255.0 );
v = (v - (16 / 255.0)) * ( 1 + 16.0 / 255.0 + (256-240) / 255.0 );

//Move chroma
u -= 0.5;
v -= 0.5;

我不确定是否可以安全地假设您永远不会得到超出范围的值,或者您是否需要限制它。

对于更高的位深度,规范说LSB被忽略了。那是什么意思?我也在用10位编码的材料,所以这是我感兴趣的。

从Y‘’CrCb到RGB

裁判。709规范说明如何将RGB转换为Y‘’CrCb:

代码语言:javascript
复制
E'y = 0.2126 * E'r + 0.7152 * E'g + 0.0722 * E'b
E'cb = 0.5389 * ( E'b - E'y )
E'cr = 0.6350 * ( E'r - E'y )

维基百科为Cb和Cr提供了一个似乎更准确的定义:

代码语言:javascript
复制
Pb = 0.5 * (B' - Y') / (1 - Kb)
Pr = 0.5 * (R' - Y') / (1 - Kr)

其中Kb和Kr是E'b和E'r的因子。似乎是从这些方程中舍入的。

通过逆转方程(使用Wikipedia版本)可以找到RGB:

代码语言:javascript
复制
double r = y + 2*(1.0-kr) * v;
double b = y + 2*(1.0-kb) * u;
double g = ( y - kr * rr - kb*rb ) / kg;

G可直接使用Cr和Cb:

代码语言:javascript
复制
double g = y - 2*kr*(1-kr)/kg * v - 2*kb*(1-kb)/kg * u;

(y因子为(1-kr-kb)/kg,为kr+kb+kg=1的kg/kg )。

RGB到sRGB

我还没有看到任何代码示例,包括这个步骤。我们需要转换rec指定的颜色空间。709到sRGB中指定的。AFAIK,两者之间唯一的区别是传递函数(即伽马)。rec指定的XY坐标。709与sRGB匹配,但我不知道为什么sRGB在rec时包含'Z‘坐标。709没有。这有什么区别吗?(我对CIE XYZ一无所知。)

裁判。709指定如何对线性RGB进行伽马编码:

代码语言:javascript
复制
V = 1.099 * L^0.45 - 0.099    for    1 >= L >= 0.018
V = 4.500 * L                 for 0.018 > L >= 0

我们需要反转它,但是线性截止值0.018在这两个方程中都没有给出V的相同值。那么反向版本的范围是多少呢?:

代码语言:javascript
复制
L = ( ( V + 0.099 ) / 1.099 ) ^ (1/0.45)    for  1 >= V >= ?
L = V / 4.5000                              for  ? >  V >= 0

sRGB也有同样的问题,但被修正为0.0031308,这是更准确的。我记得有人设计了一个分数,它精确地代表了sRGB,但我再也找不到它了。

我目前正在使用以下内容:

代码语言:javascript
复制
double cutoff = 1.099 * pow( 0.018, 0.45 ) - 0.099;
v = ( v < cutoff ) ? 1.0/4.5 * v : pow( (v+0.099)/1.099, 1.0/0.45 );
v = ( v <= 0.0031308 ) ? 12.92 * v : 1.055*pow( v, 1.0/2.4 ) - 0.055;
EN

回答 2

Stack Overflow用户

发布于 2014-05-02 23:21:56

为了正确地将线性sRGB转换为非线性sRGB (压缩过程)和反向过程(逆压缩),我使用以下函数:

代码语言:javascript
复制
public double Companding(double channel)
{
    double v = channel;
    double V = v <= 0.0031308 ? 12.92 * v : 1.055 * Math.Pow(v, 1 / 2.4d) - 0.055;
    return V;
}

public double InverseCompanding(double channel)
{
    double V = channel;
    double v = V <= 0.04045 ? V / 12.92 : Math.Pow((V + 0.055) / 1.055, 2.4);
    return v;
}

注:v是线性的,V是非线性的.

这些函数是基于这里找到的一个方程:XYZ.html

还有一个选项是使用压缩函数V=V^ gamma的简化sRGB,其中gamma为2.2,正如网站上所指出的。

票数 1
EN

Stack Overflow用户

发布于 2021-05-13 04:14:51

rec指定的XY坐标。709个与sRGB匹配,

那些是xy,不是XY,它和XYZ的XY不一样。

叹息,首先,XYZ是在线性化之后,您不需要去那里,因为sRGB已经使用BT.709初选,正如你说的。RGB线性,R'G'B‘是非线性的.Y‘’Cb‘’Cr‘也是非线性的。

我也在用10位编码的材料,所以这是我感兴趣的。

这意味着你可以把它圈起来,得到正确的8位值。如果最后两位10位值是10位或11位,则整到下一个8位值,否则下降(00,01是舍入)。LSB意味着最不重要的部分。只是不要忘记,1023应该四舍五入到255,而不是溢出。

我们需要反转它,但是线性截止值0.018在这两个方程中都没有给出V的相同值。

不,你不需要逆转任何东西。REC.601/REC.709/REC.2020的EOTF不是OETF的反面,EOTF在BT.1886中被指定,对于理想的OLED显示是2.4完美的伽玛,在200勒克斯环境光下几乎是用于不完美的液晶显示器的sRGB EOTF。这就是为什么Chrome只对BT.709使用sRGB EOTF,这意味着“没有”EOTF,因为windows默认使用它。

我记得有人设计了一个分数,精确地代表了sRGB,

只有0.04045/12.92 == 0.003130804954,809/258400。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17536417

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档