【问题标题】:How to determine colors in an Array in Java如何在Java中确定数组中的颜色
【发布时间】:2017-09-11 21:26:41
【问题描述】:

我有一个程序,它可以拍摄一张照片,然后确定我感兴趣的部分像素的 RGB 值。我取区域的平均 RGB 并将它们放入一个数组中。我想要做的是通过该数组并根据它的 RGB 值说它是例如“橙色”。我想在不限制这样的 RGB 值的情况下做到这一点。 if(r > 10 && g < 200 && b < 200) color is green. 原因是图像中的光照变化很大。所以如果我给它严格的限制,它可能会超出范围。我正在尝试考虑如何做到这一点,以便它是动态的,并且无论照片中的光线如何都能正常工作。

这并不是一个真正的代码问题,我正在尝试思考如何解决这个问题。如上所述,如果不使用约束,似乎无法想到其他方法,这就是我来到这里的原因。

这是一个颜色数组的例子。 (里面有24种颜色)

Color Array: [java.awt.Color[r=6,g=115,b=77], java.awt.Color[r=6,g=115,b=77], java.awt.Color[r=6,g=115,b=77], java.awt.Color[r=6,g=115,b=77], java.awt.Color[r=248,g=184,b=40], java.awt.Color[r=241,g=26,b=27], java.awt.Color[r=0,g=38,b=183], java.awt.Color[r=0,g=38,b=183], java.awt.Color[r=178,g=168,b=204], java.awt.Color[r=198,g=148,b=22], java.awt.Color[r=185,g=140,b=6], java.awt.Color[r=0,g=38,b=183], java.awt.Color[r=241,g=26,b=27], java.awt.Color[r=236,g=212,b=255], java.awt.Color[r=237,g=70,b=20], java.awt.Color[r=237,g=70,b=20], java.awt.Color[r=237,g=70,b=20], java.awt.Color[r=237,g=70,b=20], java.awt.Color[r=0,g=38,b=183], java.awt.Color[r=236,g=212,b=255], java.awt.Color[r=241,g=26,b=27], java.awt.Color[r=255,g=189,b=71], java.awt.Color[r=241,g=26,b=27], java.awt.Color[r=236,g=212,b=255]]

所以数组中的前 4 个索引将映射到 ["Green","Green","Green","Green"]

【问题讨论】:

  • 例如根据你的定义,R = 11, g = 199, b =11 是红色的,但在我看来它确实是绿色的
  • 这是一个例子,不实用我只是用它来解释我在说什么。 @HovercraftFullOfEels
  • 什么没有意义?使用约束来确定每种颜色是什么? @HovercraftFullOfEels
  • 所以您想在不使用 RGB 值的情况下确定颜色?
  • 您必须定义要检测的基色。 RGB 是矢量,因此您可以尝试计算基色和数组列表中颜色之间的距离(欧几里得距离),然后选择距离最小的颜色,即最接近给定基色。

标签: java arrays colors


【解决方案1】:

因为不能发表评论。

如果您认为检查所有 r、g、b 和 alpha 将需要太多的处理过程并且需要时间。所以你是对的。但是你错了,因为对于 OpenCL/CUDA(或通常是 GPGPU)程序来说,这项工作就像 ABC 一样简单。

一种解决方案是将RGB 表单转换为HSL 表单,只需将L 更改为100%,然后再次将其转换回RGB
例如,给定 rgb 格式的颜色 [3,50,2],可能是深绿色,HSL 值为 [119,96,20]
现在将L 值更改为100%,并将值转换回RGB,即[14,255,10]。所以现在它已经为你提到的约束检查做好了准备。

另一种解决方案是将约束值更改为与给定颜色的最小值和最大值相关的值。
例如,不要假设 g 必须超过 200 才能将颜色标记为绿色,而是找到所有 r、g 和 b 值的最大值和最小值,现在检查 g 是否更多大于70% 的最大值。
示例(编辑):
给定颜色值为[3,50,2]。现在不是假设检查颜色的最小值(这里是 const 200),而是找到给定颜色的最大值(这里是 50)并假设最小值为 max val 的 70%(或任何值)。检查下面的示例。

int given_color=0x00033202;//3,50,2 in ARGB form in hex
int relative_max=(given_color&0xff);//not 200, default assume blue is max
int relative_min=(given_color&0xff);//not 200, default assume blue is min
int tmp;
for(int a=8;a<=16;a+=8){//check for red and green too
 tmp=(given_color>>a)&0xff;
 if(tmp<relative_min){relative_min=tmp;}
 if(tmp>relative_max){relative_max=tmp;}
}//now you have max and min of given color, here 50 and 2
//now assume the 74% of real max value is const val 200
//and the value you want to check for color
relative_max*=0.74;
relative_min*=0.74;
//now check over real amx and rel min over const values
if( (r<relative_min) && (g>relative_max) && (b>relative_max) ){}//could be cyan
//...etc

【讨论】:

  • 我喜欢你的第二个解决方案。你能解释一下我如何使我的标记相对吗?使用最小最大颜色?
  • 更新了一个简单的示例,但我建议第一个更准确、更容易的解决方案@cuber
  • 好的,我将使用您所说的第一个解决方案。所以要做的是遍历颜色数组,将 RGB 更改为 HSL。调高亮度?然后回到 RGB,然后我可以使用我的约束?
  • 我真的不知道从 RGB 更改为 HSL 的算法是什么,但我知道它应该已经在 java API 中实现(不确定)。对于像素循环,大文件可能需要相当长的时间,所以选择 GPGPU,它将是火箭!你猜对了,RGBHSL,然后将 L 值更改为 100%(完全亮),然后将表单从 HSL 更改回 RGB,现在您将通过约束检查你用过。请注意,在这种形式下,黑色像素可以转换为白色,因此在所有阶段都非常好地检查数据。 @cuber
  • 我知道算法,我之前做过转换,但我会使用原始约束。我确实循环超过 400 像素,这不需要很长时间。因此,只需调高亮度并将其设置为 100%,然后将其恢复为 RGB。
猜你喜欢
  • 2016-02-01
  • 2012-12-16
  • 2023-03-29
  • 2017-09-02
  • 2014-12-26
  • 1970-01-01
  • 2017-03-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多