【问题标题】:Color detection algorithm - How should I do this?颜色检测算法 - 我应该怎么做?
【发布时间】:2011-03-18 03:50:43
【问题描述】:

我在设计颜色检测系统方面有点卡住 - 我不太想办法轻松做到这一点。

-

基本上,我有一个图像库,我想按颜色排序。因此,如果用户指定“按蓝色排序”,那么蓝色最多的图像将出现在结果的顶部,而蓝色最少的图像将出现在底部。

问题是图像不都是一种颜色,所以它同时做两件事:

1 - 找到图像中最蓝的部分
2 - 对该蓝色进行排名(基于色调和该颜色的数量)。

我尝试了大约 3 或 4 种不同的方法,但结果各不相同 - 但没有一种效果很好,其中 2 种是相当数学的算法(它们在纸上的效果都比在实践中好得多哈哈)。

-

我可以通过哪些不同的方式来处理整个过程?我可能错过了一些非常明显的方法 - 任何帮助或想法将不胜感激:)

-

编辑:感谢所有回复 - 这是我迄今为止尝试过的:

  • 获取整个图像的平均 rgb 值并将其与蓝色进行比较。使用归一化 rgb 3 空间向量进行比较并找出它们之间的距离。这效果最差,没有蓝色的图像很容易出现在具有部分非常强烈的蓝色的图像之上。

  • 找到主要颜色并将其与蓝色进行比较(再次使用 3 个空间矢量距离)。这不起作用,因为图像中可能有一个大的蓝色部分不是主要颜色部分中最多(或顶部一对)的部分。

  • 找到接近蓝色的像素,对所有这些像素进行平均并将结果与​​实际蓝色进行比较。

  • 查找所有接近蓝色的像素,增加计数并根据计数/总像素查找百分比。

【问题讨论】:

    标签: c++ algorithm colors detection


    【解决方案1】:

    想到两个想法:

    便宜的版本:将图像转换为 HSV 颜色空间,并为每个像素计算 cos(H - target_hue) 或合理的近似值(对于蓝色,target_hue 将是 240 度),乘以饱和度,然后在所有像素上平均该数量图像中的像素。高值是最好的。请注意,比蓝色更接近黄色的颜色具有“负蓝色”,而黑色、白色和纯灰色同样具有“零蓝色”。请注意,在这种情况下,您确实需要 HSV,而不是 HSL,因为 HSL 中的“S”不能很好地映射到感知饱和度。例如,颜色 #f8f8ff(RGB 248、248、255)在 HSL 中的饱和度为 100%(即纯蓝色),但看起来几乎是白色。 HSV中相同颜色的“S”坐标只有3%,这是合理的。

    更便宜的版本:将图像转换为 CIELAB 颜色空间,丢弃 L,并计算 a*b* 空间中每个像素与目标颜色之间的距离,然后对每个像素进行平均或 RMS。低值是最好的。

    【讨论】:

    • 哇,谢谢——这两种方法看起来都很有前途。一定会给他们一个机会。
    【解决方案2】:

    我认为要衡量“蓝色”,您需要考虑所有三个组成部分,而不仅仅是蓝色。举个例子,[255,255,255] 是纯白色,而不是蓝色——但 [0, 0, 30] 是纯蓝色,尽管它的蓝色分量的值要低得多。

    或者,您可以转换为 HSL 或 HSV 之类的东西,在这种情况下,“蓝色”应该更易于测量(仅色相和饱和度)。

    【讨论】:

    • 将尝试转换为 HSL,我猜 rgb 可能不是最好的方法。我目前的算法正在考虑所有 3 个组件 - 我正在使用 rgb 向量并比较向量距离 - 但由于某种原因,灰蓝色比浅蓝色更接近蓝色,所以也许 HSL 会解决这个问题。
    【解决方案3】:

    我会用谷歌搜索从 24 位图像创建 256 个调色板的算法(有关更多信息,请参阅http://en.wikipedia.org/wiki/Color_quantization),然后查看如果图像映射到该调色板中哪些颜色占主导地位。即,为每个 256 个调色板条目计算映射到其中的像素数。

    注意事项, 你当然不需要整个256,只是说256来帮助解释我的想法。 同样通过直接研究这个调色板生成的算法可能会直接给你一个答案。

    【讨论】:

    • 希望我早点找到那个页面,谢谢。将最佳结果量化并与蓝色进行比较听起来就像它完全可以满足需要:)
    【解决方案4】:

    您真的需要找到图像中最蓝的部分吗?为什么不将图像的“蓝色”列为所有像素的平均蓝色分量值?

    另一种可能性是找到超过阈值的像素密度,或成为蓝色像素所需的最小蓝色值。

    【讨论】:

    • 我试过这个,但它似乎不像你想象的那样工作。半纯蓝色图像将出现在具有半蓝色分量(例如浅绿色、紫色)的纯色图像下方。如果没有其他工作,我会再试一次并进行一些修改。基本的想法就在那里,只是它没有我希望的那么好。
    • @Jordan:考虑一下这个想法。如果这仍然不能满足您的要求,那么如果您列出您已经尝试过的其他事情将会很有帮助。
    【解决方案5】:

    如果你有一个像素,我会说它在 RGB 方面的蓝色是 B / (R + G + B) 的值,所以 1 完全是蓝色,0 根本不是蓝色,白色是 1 /3 蓝色。 (注意黑色,这是一种特殊情况。)图像的蓝色度是其像素的平均蓝色度。如果成本太高,只需取固定数量的随机选择像素的平均值即可。

    【讨论】:

    • 谢谢,这实际上与最有效的方法非常相似 - 我使用了一种稍微不同的方法来找到蓝色,所以会尝试这种方法,看看它是否效果更好。
    • @Jordan:这个方法的好处是它可以很好地映射到 [0,1],您可以使用函数对其进行调整。例如,如果您想偏爱中蓝色和折扣蓝色,请使用蓝色的平方根的平均值。每个仍将在 [0,1] 中。或者,如果您只关心严重蓝色的像素,请使用平方而不是平方根。
    【解决方案6】:

    我会说在整个图片上取 RGB 值本身的平均值。我会说下面的伪应该给你图片的“平均蓝色”。

    SUMr
    SUMg
    SUMb    
    for pixel <- image
      SUMr += pixel.r
      SUMg += pixel.g
      SUMb += pixel.b    
    SUMr / pixelcount
    SUMg / pixelcount
    SUMb / pixelcount
    

    如果这不成功;那么我认为您需要根据 G/B 值将“蓝色”像素排名为更高/更低的权重。然后将您的加权值相加并进行比较。

    weight
    for pixel <- image
      tweight = b
      b -= r
      b -= g
      b = 0 if b < 0
      weight += tweight
    compare weights of all images.
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-16
      • 1970-01-01
      • 2012-02-11
      • 2021-12-13
      • 2015-09-29
      • 2012-05-26
      相关资源
      最近更新 更多