一种简单的方法是说,当 RGB 分量相等时,它们形成灰色。然而,这还不是全部,因为如果它们只有细微的差别,它们仍然看起来是灰色的。
假设观看者对颜色有健康的视觉,我如何确定给定的值是否会被视为灰色(可能具有可调节的“灰度”阈值水平)?
一种简单的方法是说,当 RGB 分量相等时,它们形成灰色。然而,这还不是全部,因为如果它们只有细微的差别,它们仍然看起来是灰色的。
假设观看者对颜色有健康的视觉,我如何确定给定的值是否会被视为灰色(可能具有可调节的“灰度”阈值水平)?
A relatively straightforward method would be to convert RGB value to HSV color space and use threshold on the saturation component, e.g. "if saturation < 0.05 then 'almost grey', else not grey".
Saturation is actually the "grayness/colorfulness" by definition.
This method is much more accurate than using differences between R, G and B channels (since human eye perceives saturation differently on light and dark colors). On the other hand, converting RGB to HSV is computationally intensive. It is up to you to decide what is of more value - precise answer (grey/not grey) or performance.
If you need an even more precise method, you may use L*a*b* color space and compute chroma as sqrt(a*a + b*b)
(see here), and then apply thresholding to this value. However, this would be even more computationally intensive.
You can also combine multiple methods:
Calculate simple differences between R, G, B components. If the color can be identified as definitely desaturated (e.g. max(abs(R-G), abs(R-B), abs(G-B)) <= 5
) or definitely saturated (e.g. max(abs(R-G), abs(R-B), abs(G-B)) > 100
), then stop.
Otherwise, convert to L*a*b*, compute chroma as sqrt(a*a + b*b)
and use thresholding on this value.
r = 160; g = 179; b = 151;
tolerance = 20;
if (Math.abs(r-g) < 20 && Math.abs(r-b) < 20) { #then perceived as gray }