我正在编写一个程序,允许用户选择RGB中的各种前景色和背景色。我想不允许他们选择太相似的前景和背景,并决定转换为HSL并使用HSL欧氏距离作为检查相似性的方法。
HSL空间的加权是否很好(而不是H,S和L的加权相等)?我查看了各种网站,但没有找到我需要的确切内容;只是说HSL或HSB比RGB好。
答案 0 :(得分:4)
首先将颜色转换为Lab。设计此颜色空间使得任意两种颜色之间的矢量差异接近于“主观距离”。
在颜色管理中,给出“ΔE”值作为对给定颜色变换的感知忠实度的度量。它只是在Lab空间中表示的原始颜色和最终颜色之间的矢量差异的大小。
答案 1 :(得分:3)
我的建议是完全跳过HSL / HSB,直接从RGB to LAB开始。完成后,您可以执行标准delta E计算。
答案 2 :(得分:2)
我没有准确的数据,但我使用的L比H或S的重量要高得多。眼睛不同于区分不同饱和度的相同颜色,并且几乎与区分不同的色调一样差。 - 特别是如果它是你试图看到的细节,就像文字一样。
答案 3 :(得分:0)
我刚刚得出结论an interesting study into color spaces。就像其他人在这里提到的那样,将RGB转换为CIE-Lab并执行Delta E计算将为您提供感知的色彩距离。会产生好的结果。
我的目标是在有限的调色板中找到最接近的索引。但是,我发现使用CIE-Lab Delta E计算最终会出现“错误”的颜色。尤其是灰度级会导致饱和度过多,并从调色板中选择红色而不是灰色,但是其他颜色也存在问题(我不记得是哪种颜色)。不管好坏,我都会根据方向将权重色调设为1.2倍乘数,将饱和度设为1.5倍,将B值设为1.0倍或2.0倍。结果或多或少比单独使用Delta E更好。
计算色相的距离有点麻烦,因为它是一个圆。例如,色相0和色相359的距离为1。解决方案是选择两个不同距离中的最小值。
这是基于上面的代码:
// Finds the nearest color index in a RGB palette that matches the requested color.
// This function uses HSB instead of CIE-Lab since this function is intended to be called after GetReadableTextForegroundColors() and results in more consistent color accuracy.
public static function FindNearestPaletteColorIndex($palette, $r, $g, $b)
{
$hsb1 = self::ConvertRGBToHSB($r, $g, $b);
$result = false;
$founddist = false;
foreach ($palette as $key => $rgb)
{
$rgb = array_values($rgb);
$r = $rgb[0];
$g = $rgb[1];
$b = $rgb[2];
$hsb2 = self::ConvertRGBToHSB($r, $g, $b);
$hdiff = min(abs($hsb1["h"] - $hsb2["h"]), abs($hsb1["h"] - $hsb2["h"] + ($hsb1["h"] < $hsb2["h"] ? -360.0 : 360.0))) * 1.2;
$sdiff = ($hsb1["s"] - $hsb2["s"]) * 1.5;
$bdiff = $hsb1["b"] - $hsb2["b"];
if ($hsb1["b"] < $hsb2["b"]) $bdiff *= 2.0;
$hdiff *= $hdiff;
$sdiff *= $sdiff;
$bdiff *= $bdiff;
$dist = $hdiff + $sdiff + $bdiff;
if ($result === false || $founddist >= $dist)
{
$result = $key;
$founddist = $dist;
}
}
return $result;
}
来源:https://github.com/cubiclesoft/php-misc/blob/master/support/color_tools.php
将以上内容转换为使用HSL而不是HSB / HSV应该不太困难。我更喜欢HSB颜色空间,因为它可以反映Photoshop,这使我可以在软件中确认要查找的数字。