2010-03-11 161 views

回答

5

由於您很可能不想使用24位色彩空間的所有百萬種顏色的直方圖,我建議將圖像轉換爲HSV空間。 然後,您可以將該空間的Hue部分分割成多個描述您想要查找的色調(「深紅色」,「橙紅色」或其他)的bin。然後製作這些垃圾箱的直方圖,並找出哪個是主色調,即「顏色」。

維基百科文章http://en.wikipedia.org/wiki/HSL_and_HSV應該讓你開始。如果您正在使用圖像處理庫,可能會出現rgb-to-hsv/hsl功能。另外,如果圖像很大並且速度有問題,則可以考慮在直方圖形成之前將圖像下采樣到較小的尺寸。

+0

很好的建議,儘管只有H,但你不能看到深紅和粉紅色之間的區別。 – AVB 2010-03-11 14:15:38

+0

是的。但我想這是更容易劃分垃圾箱基於H和S,而不是分區R,G和B :) – 2010-03-12 07:04:55

+1

如何使用python代碼將圖像轉換爲HSV? – 2010-03-16 04:56:10

3

蠻力的方法是循環圖像中的所有像素,並保持R,G,B值的計數。更精細的方法是使用直方圖函數並計算所有顏色的平均值。

+0

只需隨機抽取像素並對其進行計數就足夠了。 – 2010-03-11 09:36:27

1

如果您確定您將始終只有一種主色(例如,沒有兩種顏色的包),則的S尺寸上的原始直方圖應該就足夠了。

否則,您可以(也應該)使用mean shift。它非常簡單,完全符合你的要求,並且可以使用庫,儘管我無法在Python中找到任何東西。你可以實現它,或者調用C++代碼。

該算法的基本思想是:每個像素查看相似顏色的附近像素,並將其顏色更改爲所有顏色的加權平均值;沖洗並重復。很快你就會將圖像中的所有顏色聚集在一些主要顏色上。

0

就地排序像素,然後遍歷圖像並找到最長的運行。

+0

-1:這不會對自然圖像產生良好效果。給定24位色彩空間,你有1600萬色。一張大照片可能有1000萬像素,這意味着每個像素都有獨特的顏色的可能性非常大。沒有閾值我不認爲這會給出預期的結果。 – 2010-03-15 10:50:25

+0

我回答了這個問題 - 如果問題嚴重,則表決問題,而不是解決方案。此外,您認爲10M像素具有使每個像素具有獨特顏色的可能性很大的說法是錯誤的。你只需要12-13個隨機像素,概率小於1%,而10M給出的機會要小很多個數量級。 – 2010-03-16 22:51:41

0

如上所述,將圖像從RGB轉換爲HSV會更方便。標準庫模塊colorsys包含該功能的功能rgb_to_hsv。然後,您可以映射圖像上的顏色,例如H表示x,S表示y。選擇該空間中的點,並給他們的名字;越多點越好。然後,對於圖像中的每個像素,找到您選擇的最接近的點並將其名稱用作像素值。計算哪個名稱出現次數最多。

你要我提供代碼嗎?

2

我會使用Python圖像庫。這是計算圖像中白色像素/非白色像素數的一段代碼。

import sys 

from PIL import Image 

im = Image.open(sys.argv[1]) 
white = 0 
black = 0 
for i in im.getdata(): 
    if i == (255,255,255): 
    white += 1 
    else: 
    # we assume black everything that is not white: 
    black += 1 
print im.size[0],im.size[1],white,black 

在你的情況,我會做一本字典,以保持每個RGB對反三倍,所以我會返工這樣的(未測試)程序

import sys 

from PIL import Image 

im = Image.open(sys.argv[1]) 
count= {} 
for i in im.getdata(): 
    if not count.has_key(i): 
     count[i] = 0 

    count[i] += 1 

現在,您可以檢查一個計數最高,並獲得最常用的rgb三元組。當然,如果你想檢查附近的顏色,你將不得不轉換成HSV並檢查不同HSV點之間的距離,然後確定哪個距離太大。 HSV空間中足夠接近的點(特別是色調分量)最有可能是相同的顏色,因此可以相加在一起。