如何确定一种颜色更接近于白色还是黑色?

24

我正在处理图像,并希望确定一组像素是更接近白色还是黑色。

因此,给定一组颜色/像素,如何确定它们更接近白色还是黑色?

我尝试了一些新手算法,有谁知道我该如何做到这一点?


1
在 RGB 世界中,白色是 255,255,255,黑色是 0,0,0。看起来你可以简单地取三个数的平均值,并确定结果更接近于 0(黑色)还是 255(白色)。 - Chris
是的,我在我的一个“新手”解决方案中尝试过这种平均化方法,但效果不佳。 - Aziz
4个回答

45
我认为你可以先将颜色转换为灰度,然后再检查它是否更接近黑色或白色。
首先,按照以下公式将RGB颜色值转换为亮度值。
Y = 0.2126*R + 0.7152*G + 0.0722*B

然后检查该值是更接近于0还是255,并相应选择黑色或白色。

color c = Y < 128 ? black : white

请注意,如果颜色空间不是伽马压缩的,则此方法效果良好,否则您需要在计算亮度之前添加一个步骤,即进行 伽马扩展,计算 Y 值,然后执行 伽马压缩 以获得非线性亮度值,然后使用它来确定颜色是否更接近黑色或白色。


你能给我展示一个如何测试伽马压缩并获取适当亮度值的例子吗?这种方法似乎符合我的需求。 - Aziz
你无法测试伽马压缩是否存在。你必须事先知道,伽马压缩的作用是使用幂函数“去线性化”RGB值,如果这是在你的颜色上完成的,那么在计算亮度之前,你必须进行反向操作,就是这样。 - Jack
在Android中有一个内置的方法可以使用:Color.luminance()。它返回一个介于0和1之间的浮点数,其中0表示绝对黑色,1表示绝对白色。 - Charles Madere
遗憾的是,Color.luminance()是在API 24中添加的。 - Saket
你从哪里得到这个公式的权重?难道不应该是灰度=0.3 * R + 0.59 * G + 0.11 * B吗? - Mareș Ștefan
@MareșȘtefan:根据所涉及的媒体和其他参数,有多个标准。 - Jack

4

白色和黑色可能有两种潜在含义:

  • 可见光的颜色谱
  • 由种族、晒黑程度等决定的人类肤色。

前者很容易:转换为灰度范围0-255。 127或以下更接近黑色(0),128或以上更接近白色(255)。

我使用以下函数使用亮度值将其转换为灰度(假设输入颜色为int ARGB格式):

public static int getLuminance(int argb) {
    int lum= (   77  * ((argb>>16)&255) 
               + 150 * ((argb>>8)&255) 
               + 29  * ((argb)&255))>>8;
    return lum;
}

后一种定义(人类肤色)无法通过简单的算法完成,因为它取决于光照条件、相机设置、曝光等。在典型条件下,RGB值为(190,115,60)可能大致处于中点位置。


4

请查看YCbCr。由于Java和大多数计算机处理颜色的格式为RGB,因此您需要将RGB转换为YCbCr。有许多公式可将RGB转换为YCbCr。

一旦获得YCbCr值,您可以检查亮度值(YCbCr中的值Y)。


这是你要找的答案。1+1。 - Hovercraft Full Of Eels

2
  • 将颜色转换为灰度(灰度颜色的三个RGB分量相等,参见将彩色图像转换为灰度)。

  • 检查灰度是否更接近黑色(0)还是白色(255)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接