【问题标题】:Determine which color (red, blue, green or other) would be visible for a given RGB value combination?确定对于给定的 RGB 值组合,哪种颜色(红色、蓝色、绿色或其他)可见?
【发布时间】:2020-05-08 10:13:18
【问题描述】:

所以基本上,我需要一种方法,我可以在其中传递红色、绿色和蓝色的值,并且该方法应该返回 RGB 值的组合是否会导致明显的红色绿色或蓝色.如果组合没有产生这三种颜色中的任何一种,它应该返回 false。

我尝试通过使用条件语句来做到这一点,尝试了一些变体,但没有什么是准确的。

例如我试过:

if (B > 100 && B > G / 2 && B > R / 2)
{
    blueCount++;
}
else if (G > 100 && G > G / 2 && G > B / 2)
{
    greenCount++;
}
else if (R > 100 && R > G / 2 && R > B / 2)
{
    redCount++;
}

// R , G , B contains 0-255 values 

【问题讨论】:

  • 这有很多边缘情况,让我头晕目眩,你会说什么黑色?什么是灰色?当GB都是100时呢?会说它比 B 更 G
  • 您可能想要使用HSV 颜色模型并检查H (Hue) 并且可能是S (Saturation):如果我们有权利Hue (比如说,Green)而且不是很低Saturation(不是太无色的湖灰、白色、黑色)我们可以说我们有一个绿色
  • 你看this answer
  • @MarkDavies "如果组合没有产生这三种颜色中的任何一种,它应该返回 false" - 但我明白你的意思是应该定义 什么时候是颜色 [red|green|blue]-ish
  • 您是否考虑过您的方法,而不是返回真/假,可以返回所提供颜色的“纯度”百分比?例如,255;0;0 是 100% 纯色,128;0;0 是 50% 纯色,255;128;128 是 50% 纯色......我不知道,类似的东西跨度>

标签: c# algorithm colors pixel


【解决方案1】:

如果您将“有色”定义为:

  • 颜色值在100以上
  • 颜色值至少是其他 2 个值的 两倍
    • 您当前的代码声明“至少 一半 的 2 个其他值”,但这不起作用,因为如果您有“R:199 G: 101 B:102”,你可以说它是 green-ish,因为 G 高于 100,超过一半 199 和一半 102(当它明显是 red-ish)

那么您的代码看起来几乎不错(只需将/ 替换为*)。

我只会使用enum 来表示结果:

enum Ish
{
    Other, // 0 so this would be false if you convert it to bool
    Red,   // 1
    Green, // 2
    Blue   // 3
}
if (R>100 && R>G*2 && R>B*2)
    return Ish.Red;
if (G>100 && G>R*2 && G>B*2) // you had G>G/2 here /!\
    return Ish.Green;
if (B>100 && B>G*2 && B>R*2)
    return Ish.Blue;
return Ish.Other;

我用了 2 两次,但我认为你可以使用其他值,只要它是 >1(例如,如果 B <= R,你不能说蓝色是 主导

这将是 R=100 可能的偏红值(左图为 2,右图为 1):

对于 R=200(左图为 2,右图为 1):

因此,您可能会使用 1 到 2 之间的因子

对于 R=200,您可以看到红色,具体取决于以下因素:

【讨论】:

  • 哦...简单的数学,愚蠢的错误..感谢您的指出。!
  • @kas 不客气,这样做很有趣(我扩展了最后一个屏幕截图,以便您真正看到当因子低于 1 时会发生什么)
  • @kas 我还修正了你在第二个 if (G>G..) 中的一个错字
  • 你是如何获得色彩空间图像的,@Rafalon?
  • @CălinDarie 我实际上是用 Excel VBA 创建的(您可以在最后一个屏幕截图中看到我用于参数的 2 个文本框 - 红色值和因子),我使用 MS Paint 添加箭头和“彩色”文本
【解决方案2】:

我建议使用不同的色彩空间HSV or HSL 而不是RGB

现在,要声明 color绿色,您必须检查

  1. 如果color 在某个范围内有H (Hue)(Green 色调支配其他颜色)
  2. 如果colorS (Saturation) 高于某个阈值,以免太无色(灰色)
  3. 如果colorVLValueLuminocity)高于一些阈值,以免太(黑色)

https://vignette.wikia.nocookie.net/psychology/images/e/e0/HSV_cylinder.png/revision/latest?cb=20071105130143

【讨论】:

  • 如果你想给颜色命名,你可以参考xkcd.com/color/rgb并沿着列表往下走,直到找到合适的匹配。
【解决方案3】:

不要试图为此找到一个完全准确的答案。毕竟,红色和非红色之间没有完美的界限。

我的处理方法是:首先,检查颜色不是太灰/黑。这可以使用三个分量的总和来完成(请记住,RGB 上的全黑是 0;0;0,灰色通常是 55;55;55)。例如,您可以将分量总和小于 300 的任何颜色视为太暗。使用任何 RGB 选择器工具试一试,找到您最喜欢的阈值。

编辑:从下面的评论中,我看到三个组件的总和不起作用,例如 255;0;0 会被认为太灰色。所以你必须使用三个组件的最大值。例如,20;0;0 仍然会很暗,但 100;0;0 不会那么暗。感谢@rafalon 指出这一点。

然后,您需要检查此颜色是否接近“纯”颜色,即红色、绿色或蓝色。为此,您需要将最突出的组件与其他两个组件进行比较。您必须将这个最高组件与其他两个单独进行比较。这是因为像 255;0;255 这样的颜色根本不偏红,而 255;128;128 则可以这样认为。因此,将这两个不太突出的组件组合起来是行不通的。

如果绿色和蓝色的值都低于红色的某个百分比,您可以认为颜色偏红。以这个百分比为 50% 为例。然后,您需要检查绿色是否小于 0.5 * 红色且蓝色是否小于 0.5 * 红色。同样,您应该尝试使用 RGB 颜色来找到您认为合适的百分比。

TL;DR:对于具有 r、g 和 b 分量的颜色,如果满足以下条件,该颜色将是“纯”颜色:

  1. Max(r, g, b) > tooDarkValue

  2. r > somePercentage * Max(r, g, b) AND g > somePercentage * Max(r, g, b) AND b > somePercentage * Max(r, g, b)

    李>

请注意,对于 Max(r, g, b),第二个条件始终为真,(任何数字都大于其自身的百分比),因此无需评估哪个分量最高,然后有 3 个不同的条件

【讨论】:

  • "你可以认为任何分量总和小于 300 的颜色都太暗" - 所以你会认为 255;0;0 太暗 b>?
猜你喜欢
  • 2011-10-31
  • 1970-01-01
  • 2015-09-29
  • 2014-08-26
  • 2016-01-01
  • 1970-01-01
  • 2011-10-28
  • 2013-12-19
  • 1970-01-01
相关资源
最近更新 更多