为了账号安全,请及时绑定邮箱和手机立即绑定

我相信我在 sRGB 和线性 RGB 之间正确转换,那么为什么深色的结果看起来更差?

我相信我在 sRGB 和线性 RGB 之间正确转换,那么为什么深色的结果看起来更差?

Go
不负相思意 2023-02-21 13:15:21
在研究了sRGB 上的维基百科条目后,我实现了一组函数来帮助进行颜色转换:import "math"// https://en.wikipedia.org/wiki/SRGB#Transformationvar byteDecoded [256]float32 = func() (floats [256]float32) {    for i := 0; i < 256; i++ {        floats[i] = float32(i) / 255    }    return floats}()// Standard returns the sRGB color space value in range [0.0-1.0] for v, assuming v is in linear RGB in range [0.0-1.0].func Standard(v float32) float32 {    if v <= 0.0031308 {        return v * 12.92    }    return float32(1.055*math.Pow(float64(v), 1.0/2.4) - 0.055)}// Standardb returns the sRGB color space value in range [0-255] for v, assuming v is in linear RGB in range [0.0-1.0].func Standardb(v float32) uint8 {    if v >= 1 {        return 255    }    if v <= 0 {        return 0    }    return uint8(Standard(v)*255 + 0.5)}// Linear returns the linear RGB color space value in range [0.0-1.0] for v, assuming v is in sRGB in range [0.0-1.0].func Linear(v float32) float32 {    if v <= 0.04045 {        return v * (1.0 / 12.92)    }    return float32(math.Pow((float64(v)+0.055)/1.055, 2.4))}// Linearb returns the linear RGB color space value in range [0.0-1.0] for b, assuming b is in sRGB in range [0-255].func Linearb(b uint8) float32 {    return Linear(byteDecoded[b])}然后我玩了一些结果。log.Printf("Half of sRGB 255 calculated in linear RGB is %d", Standardb(Linearb(255)/2))版画Half of sRGB 255 calculated in linear RGB is 188。然后我做了这个:上半部分:棋盘格红色 (255, 0, 0) 和绿色 (0, 255, 0) 像素。左下角:使用 2 (128, 128, 0) 划分的原始混音。右下角:(188, 188, 0)下半部分显示了两种不同的尝试,当在两个轴上按比例缩小 50% 时,上半部分会是什么样子。由于上半部分是交错的全绿色和全红色像素,因此缩小比例必须将一半红色和一半绿色加在一起,其值是我之前计算的值 (188)。右下角与我的普通消费者显示器上的上半部分完全吻合,所以看起来整个转换数学都在起作用。但是深色呢?log.Printf("Half of sRGB 64 calculated in linear RGB is %d", Standardb(Linearb(64)/2))版画Half of sRGB 64 calculated in linear RGB is 44。我和以前一样:上半部分:棋盘格深红色 (64, 0, 0) 和深绿色 (0, 64, 0) 像素。左下角:使用 2 (32, 32, 0) 划分的原始混音。右下角:(44, 44, 0)这一次,在我的显示器上,朴素(不正确)的方法几乎完美地匹配了上半部分,而我在右下角努力计算的值看起来太亮了。我做错了吗?或者这只是消费者显示设备上预期的错误程度?
查看完整描述

1 回答

?
阿波罗的战车

TA贡献1862条经验 获得超6个赞

我做错了吗?

是和不是。您的代码是正确的,但您的测试方法有疏忽:

这只是消费者显示设备上预期的错误程度吗?

是的。特别是,这很可能是由显示面板的控制驱动程序引起的。在这里看到有人做出类似的观察:https://electronics.stackexchange.com/questions/401617/lcd-pixels-how-chess-board-pixel-fill-patterns-are-called

通过从棋盘像素图案到交替着色的水平像素线,可以降低问题的严重性。数学结果是一样的,但结果看起来却大不相同。

第一张带水平线的图片:

//img1.sycdn.imooc.com//63f453b40001549f06020438.jpg

第二张带水平线的图片:

//img1.sycdn.imooc.com//63f453c300010b4d06030440.jpg

奖励:带有垂直线的第二张图片(试着眯着眼睛;对我来说它看起来更准确):

//img1.sycdn.imooc.com//63f453ce0001449a06020438.jpg

另请注意,就显示的准确能力而言,“普通消费者显示器”已经是一个广泛的范围。如果我将这个非常 Stackoverflow 窗口拖到我更便宜的第二台显示器上,我完全无法确认您所做的任何断言,因为它的颜色输出非常不准确。



查看完整回答
反对 回复 2023-02-21
  • 1 回答
  • 0 关注
  • 254 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信