2010-04-05 269 views
4

我想查看图像中存在的颜色。这将被存储在数据库中并用于搜索表单。 (红= 1,绿= 1,蓝= 0,黄色= 1,黑色= 1,白色= 1等)从图像中获取使用的颜色名称

img = Magick::Image.read('phosto-file.jpg').first 
img = img.quantize(10 
h = img.color_histogram 
pp h 
{red=12815, green=18494, blue=15439, opacity=0=>13007, 
red=44662, green=47670, blue=51967, opacity=0=>18254, 
red=17608, green=43331, blue=48321, opacity=0=>11597, 
red=21105, green=25865, blue=39467, opacity=0=>10604, 
red=15125, green=36629, blue=22824, opacity=0=>10223, 
red=52102, green=42405, blue=10063, opacity=0=>12928, 
red=39043, green=28726, blue=40855, opacity=0=>7728, 
red=10410, green=8880, blue=7826, opacity=0=>13795, 
red=25484, green=25337, blue=24235, opacity=0=>7351, 
red=44485, green=12617, blue=11169, opacity=0=>14513} 

如何将10个值转换为彩色的名字呢?红色,绿色,NOMATCH,黄色,黑色,白色等。只需要粗糙的颜色名称 - 不是LimeGreen,而是绿色等。

此致敬意。 AsbjørnMorell

+0

您示例中的ruby代码无效:opacity = 0 => 13007无效。 – kikito 2010-04-05 20:54:23

回答

1

如果您可以用ImageMagick返回的相同数字格式表示您正在查找的所有颜色。然后,您可以比较RGB值,找出最接近的值。

因此,举例来说,如果你有一个直方图值(假设每种颜色255个值,因人而异)

{ red => 10, green => 255, blue => 10 } 

然后,你可以,如果你添加比较每个

{ 
    red => {red => 255, green => 0, blue => 0}, 
    green => {red => 0, green => 255, blue => 0}, 
    blue => {red => 0, green => 0, blue => 255} 
} 

所以你会得到所有元素之间的差异

{ 
    red => 510, 
    green => 20, 
    blue => 510, 
} 

所以你可以清楚地看到col或者是最接近绿色

UPDATE:已在红宝石


def compare_color(color_val) 
    colors = { 
    :red => [255,0,0], 
    :green => [0,255,0], 
    :blue => [0,0,255] 
    } 

    difference = {} 

    def compare_array(a1,a2) 
    total = 0 
    a1.each_index do |x| 
     total += (a1[x]-a2[x]).abs 
    end 
    total 
    end 

    colors.each do |color,hex| 
    difference[color] = compare_array(color_val,hex) 
    end 

    closest = difference.sort{|a,b| a[1] b[1]}.first                  [closest,difference] 
end 

p compare_color([10,255,10]) 
# [[:green, 20], {:red=>510, :green=>20, :blue=>510}] 
+0

如果代码是数组而不是散列,这段代码可能会更容易(从数学的角度来看),但这样可以得到更好的结果 – Fotios 2010-04-06 13:50:09

+0

非常好。谢谢你的例子。 :) – atmorell 2010-04-06 21:13:49

1

简单的方法是获得一个RGB值列表和相应的名称,然后选择最接近的匹配颜色(在一些可接受的误差范围内)。对于基本颜色,即使每个RGB通道的差异总和也可以得到可行的结果,但是如果数据看起来像这样,我怀疑你会用尽颜色名称。你可以在网上找到一个list of colour names,也许剥夺一个这样的列表可能会有所帮助。 (请注意,这些颜色的颜色范围通常为0..255,因此您需要从数据范围较宽的范围中进行转换。)

稍微更高级的方法可能是将RGB值转换成色调,饱和度和亮度,并使用它们来生成名称,例如当色调是红色时,“暗红色”,饱和度足够高而不是灰色,并且亮度低(但不够低,不足以成为黑色)。

1

解决您可能会发现this post在我的博客有趣。它解释了如何解决你的问题。我还发布了​​,它可以使您从RGB值或HTML哈希中获得最接近的命名颜色。您也可以使用任何Color对象