2010-03-11 6 views
8

Ich möchte die am häufigsten verwendete Farbe in einem Bild mit Python finden. B. die Farbe des Objekts in der folgenden Abbildung erkennenerkennen Sie die am häufigsten verwendete Farbe in einem Bild mit Python

http://www.shopcrazy.com.ph/wp-content/images/2007/02/shiny-bags-01.jpg.

Wie erkennt man die Grundfarbe aus den RGB-Codes (Beispiel - rot im obigen Bild).

+0

Siehe http://stackoverflow.com/questions/2270874/image-color-detection-using-python/2271013#2271013 – luc

Antwort

5

Da Sie höchstwahrscheinlich kein Histogramm aller Millionen Farben wünschen, die mit einem 24-Bit-Farbraum möglich sind, empfehle ich, stattdessen das Bild in den HSV-Raum zu transformieren. Dann können Sie den Farbtonteil dieses Raums in eine Anzahl von Behältern partitionieren, die die gewünschten Farbtöne beschreiben ("dunkelrot", "orange rot" oder was auch immer). Dann machen Sie ein Histogramm dieser Fächer und finden Sie heraus, welches der dominierende Farbton ist, welches die "Farbe" ist.

Der Wikipedia-Artikel http://en.wikipedia.org/wiki/HSL_and_HSV sollte Sie beginnen. Wenn Sie eine Bildverarbeitungsbibliothek verwenden, besteht die Chance, dass eine rgb-to-hsv/hsl-Funktion existiert.

Wenn die Bilder groß sind und die Geschwindigkeit ein Problem darstellt, sollten Sie das Bild vor dem Histogramm auf eine kleinere Größe verkleinern.

+0

Guter Rat, obwohl auf H allein Sie den Unterschied zwischen tiefem Rot und Rosa zum Beispiel nicht sehen können. – AVB

+0

Wahr. Aber ich denke, es ist einfacher, die Bins auf Basis von H und S zu teilen, anstatt R, G und B zu partitionieren: –

+1

Wie konvertiert man das Bild mit Python-Code in HSV? –

3

Der Brute-Force-Ansatz besteht darin, alle Pixel im Bild zu durchlaufen und die R-, G- und B-Werte zu zählen. Ein raffinierterer Ansatz besteht darin, die Histogrammfunktion Python Image Library zu verwenden und den Durchschnitt aller Farben zu berechnen.

+0

Es könnte ausreichen, nur eine zufällige Stichprobe der Pixel zu nehmen und diese zu zählen. –

1

Wenn Sie wirklich sicher sind, dass Sie immer nur eine dominante Farbe haben (keine Taschen in zwei Farben, zum Beispiel), dann ein rohes Histogramm auf den H & S Dimensionen HSV sollte ausreichen. Sie können (und sollten) mean shift verwenden. Es ist ziemlich einfach, tut genau das, was Sie wollen, und es gibt Bibliotheken, die Sie verwenden können, obwohl ich in Python nichts finden konnte. Sie können es entweder implementieren oder C++ - Code aufrufen.

Der Grundgedanke des Algorithmus ist folgender: Jedes Pixel betrachtet benachbarte Pixel mit ähnlicher Farbe und ändert seine Farbe in das gewichtete Mittel aller ihrer Farben; spülen und wiederholen. Sehr bald haben Sie alle Farben im Bild sehr eng um einige vorherrschende Farben gruppiert.

0

Sortieren Sie die Pixel an Ort und Stelle, durchlaufen Sie dann das Bild und suchen Sie den längsten Lauf.

+0

-1: Dies liefert keine guten Ergebnisse für natürliche Bilder. Bei einem 24-Bit-Farbraum haben Sie 16 Millionen Farben. Ein großes Foto hat vielleicht 10 Millionen Pixel, was bedeutet, dass es eine ziemlich große Chance gibt, dass jedes Pixel eine einzigartige Farbe hat. Ohne Schwellenwertbildung denke ich nicht, dass dies das erwartete Ergebnis liefern wird. –

+0

Ich beantwortete die Frage wie gefragt - wenn das Problem schlecht angegeben ist, wählen Sie das Problem, nicht die Lösung. Auch Ihre Behauptung, dass ein 10M-Pixel eine erhebliche Chance hat, dass jedes Pixel eine eindeutige Farbe hat, ist flach falsch. Sie benötigen nur 12-13 tausend zufällige Pixel für die Wahrscheinlichkeit, weniger als 1% zu sein, und 10M gibt eine Chance viele Größenordnungen kleiner. –

0

Wie vorgeschlagen, ist es praktischer, Ihr Bild von RGB in HSV zu konvertieren. Das Standardbibliotheksmodul colorsys enthält dazu die Funktion rgb_to_hsv. Dann können Sie Farben auf einem Bild abbilden, sagen wir mit H als x und S als y. Wähle Punkte in diesem Raum und gib ihnen Namen. Je mehr Punkte, desto besser. Suchen Sie dann für jedes Pixel in Ihrem Bild den nächsten der von Ihnen ausgewählten Punkte und verwenden Sie seinen Namen als Pixelwert. Zählen Sie, welcher Name am häufigsten vorkommt.

Soll ich Code liefern?

2

Ich würde die Python Image Library verwenden. Dies ist ein Stück Code, der die Anzahl der weißen Pixel/nicht-weißen Pixel in einem Bild berechnet.

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 

In Ihrem Fall würde ich ein Wörterbuch tun jeden rgb triple gegen einen Zähler zu halten, so würde ich das Programm wie folgt (nicht getestet)

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 

Sie können sich nun die eine Nacharbeit mit der höchsten Zählung und erhalten Sie die am häufigsten verwendeten RGB Triple. Natürlich, wenn Sie auch vicinal Farben überprüfen möchten, müssen Sie in HSV konvertieren und überprüfen Sie die Abstände zwischen verschiedenen HSV-Punkten, dann entscheiden, welche Entfernung zu viel ist. Punkte, die dem HSV-Raum (und insbesondere der Farbtonkomponente) ausreichend nahe sind, haben höchstwahrscheinlich die gleiche Farbe und können folglich summiert werden.

Verwandte Themen