如何计算具有相同感知亮度的RGB值

问题描述 投票:0回答:3

我正在尝试生成具有相同感知亮度的 RGB 颜色。

函数 R*0.2126+ G*0.7152+ B*0.0722 据说可以计算给定 RGB 颜色的感知亮度(或等效灰度颜色)。

假设我们对所有 RGB 值使用区间 [0,1],我们可以计算以下内容:

  • 黄色 = RGB(1,1,0) => 亮度=0.9278
  • 蓝色 = RGB(0,0,1) => 亮度=0.0722

因此,为了使黄色色调与蓝色色调一样暗淡,我可以简单地对每个 RGB 分量的黄色执行以下简单计算:

  • dim_yellow = 黄色 * 0.0722 / 0.9278

然而,当做相反的事情,从而将蓝色“放大”到与原始黄色相同的感知亮度时,B分量明显超过1,这无法在计算机屏幕上显示。

我猜想多余的 B 分量所缺失的亮度可能会“重新分配”到 R 和 G 分量,从而伪造出更亮的蓝色。那么计算最终 RGB 值的最佳通用方法是什么?

math colors language-agnostic rgb
3个回答
3
投票

这些不是您要找的数学

函数 R*0.2126+ G*0.7152+ B*0.0722 据说可以计算给定 RGB 颜色的感知亮度(或等效灰度颜色)。

不,这是不正确的,或者至少是不完整的。是的,R*0.2126+ G*0.7152+ B*0.0722 是光谱系数,但这并不是完整的故事。

首先,不要在这种情况下使用术语亮度。亮度不是光的度量,它是一种感知,而不是可测量的量。当我们谈论光和比色法时,请使用术语“亮度”(L 或 Y)。亮度是光的线性测量,而不是感知。

CIELAB 的感知亮度或 L* (Lstar) 基于人类对亮度变化的“感知”。接近0.43左右的功效曲线。 sRGB,通常用于计算机显示器和网络的色彩空间,不像光那样是线性的,而且它也不完全像感知的 L* 曲线。 sRGB 的传输曲线接近 1/2.2 幂曲线。也就是说,sRGB 数据/信号被提升到 0.455 的幂,然后显示器应用 2.2 的幂。

出了什么问题

您的数学不起作用,因为您没有考虑传输曲线。在应用系数之前,您必须对 sRGB 值进行线性化。那么这些的总和将等于亮度 1。

sRGB 中的#FFFF00 等于亮度 0.9278,但这是 96.76% 的 sRGB 值或 97.14% 的 L* 值

sRGB 中的#0000FF 等于亮度 0.0722,但这是 29.79% 的 sRGB 值或 32.3% 的 L* 值

这是一些值的图表,扩展了您的示例:

因此,要回答您的其余问题,要获得与显示器的亮度相匹配的更高亮度的蓝色,需要对其进行去饱和,添加 R 和 G 以增加亮度。

在此图表中,我们有完全饱和但较暗的红色和绿色来匹配 7% 的蓝色亮度,然后我们有 18% 的亮度(如 18% 的灰卡),这里我们必须降低蓝色的饱和度以带来亮度值上升。

如何计算

首先,您需要对 sRGB 分量进行线性化,然后如果需要确定亮度,则应用系数。如果您想出一些对线性化分量进行数学运算的值,那么您需要重新伽玛编码以返回 sRGB。

我已经讨论过其他几个答案,

比如这里。


0
投票
HSV

颜色模型而不是RGB,因为您只需修改值(亮度)组件即可轻松实现您想要的效果。 wiki 页面还包含如何将 RGB 转换为 HSV 以及反向转换 编辑: 尝试使用

CIELAB

色彩空间,因为它接近人类视觉


0
投票

即我们可以找到与蓝色具有相同亮度的红色

// l = .299 r + .587 g + .114 b target_color = V(1, 0, 0); desired_brightness = V(0, 0, 1) * V(0.229, 0.587, 0.114); current_brightness = target_color * V(0.229, 0.587, 0.114); desired_color = target_color * desired_brightness / current_brightness

© www.soinside.com 2019 - 2024. All rights reserved.