2009-11-12 16 views
11

Ich habe ein gepuffertes Bild in Java und ich möchte aufzeichnen, wie ähnlich jedes Pixel zu einem anderen ist, basierend auf dem Farbwert. also haben die Pixel mit "ähnlichen" Farben einen höheren Ähnlichkeitswert. zum Beispiel haben Rot und Rosa einen Ähnlichkeitswert von 1000, aber Rot und Blau haben ungefähr 300 oder weniger.ähnliche Farben programmgesteuert finden

Wie kann ich das tun. Wenn ich das RGB von einem gepufferten Bildpixel bekomme, gibt es eine negative Ganzzahl zurück. Ich bin mir nicht sicher, wie ich dies implementieren soll.

Antwort

18

Erstens, wie erhalten Sie den ganzzahligen Wert?

Sobald Sie die RGB-Werte zu erhalten, könnten Sie versuchen

((r2 - r1) + (g2 - g1) + (b2 - b1)) 1/2

Dies würde Ihnen die Entfernung im 3D-Raum von den zwei Punkten geben, die jeweils durch (r1, g1, b1) und (r2, g2, b2) bezeichnet werden.

Oder es gibt ausgefeiltere Möglichkeiten, den HSV-Wert der Farbe zu verwenden.

+0

ich glaube, Sie haben die^2 nach (b2-b1 weggelassen); trotzdem, +1, weil ich im Begriff war, das gleiche zu posten –

+0

Ist das wirklich, wie Sie die Entfernung im 3D-Raum messen? Ich hätte gedacht, dass es irgendwo eine Quadratwurzel einbeziehen würde? Wenn das funktioniert, könnte es im 2. Raum verwendet werden, und Sie haben gerade Pythagoras überlistet. – Breton

+7

Er nimmt die Kubikwurzel, was falsch ist; es sollte die Quadratwurzel sein. Aber es ist unnötig, die Wurzel zu nehmen, da man Quadrate von Entfernungen genauso leicht vergleichen kann wie die Abstände selbst und die Zeit sparen, die Wurzel zu nehmen. –

2

Am einfachsten ist es, beide Farben in HSV-Wert zu konvertieren und die Differenz der H-Werte zu finden. Minimale Änderungen bedeutet, dass die Farben ähnlich sind. Es liegt jedoch an Ihnen, einen Schwellenwert zu definieren.

2

Sie rufen wahrscheinlich getRGB() bei jedem Pixel auf, das die Farbe als 4 8-Bit-Byte zurückgibt, das hohe Byte Alpha, das nächste Byte rot, das nächste Byte grün, das nächste Byte blau. Sie müssen die Kanäle trennen. Selbst dann ist die Farbähnlichkeit im RGB-Raum nicht so groß - mit HSL- oder HSV-Platz könnten Sie viel bessere Ergebnisse erzielen. Den Umrechnungscode finden Sie unter here.

Mit anderen Worten:

int a = (argb >> 24) & 0xff; 
int r = (argb >> 16) & 0xff; 
int g = (argb >> 8) & 0xff; 
int b = argb & 0xff; 

Ich weiß nicht, die spezifische Byte-Reihenfolge in Java-gepufferte Bildern, aber ich denke, das ist richtig.

+1

-1 für die Empfehlung HSL oder HSV. Das sind Ad-hoc-Transformationen, die in der realen Welt nichts wirklich bedeuten. Sie wurden für frühe Grafikprogramme erfunden. Abstand im L * a * b-Raum basiert auf Messungen von Hunderten von Experimenten mit echten Augen und echten Farben. – Breton

2

Sie könnten die einzelnen Bytes erhalten wie folgt:

int rgb = bufferedImage.getRGB(x, y); // Returns by default ARGB. 
int alpha = (rgb >>> 24) & 0xFF; 
int red = (rgb >>> 16) & 0xFF; 
int green = (rgb >>> 8) & 0xFF; 
int blue = (rgb >>> 0) & 0xFF; 
9

Ich schlage vor, Sie zu lesen beginnen hier

Color difference formulas wenn Sie dieses Recht tun wollen. Es erläutert die Formeln ΔE*ab, ΔE*94, ΔE*00 und ΔE*CMC zur Berechnung der Farbdifferenz.

1

Ich finde HSL-Werte leichter zu verstehen. HSL Color erklärt, wie sie funktionieren und stellt die Umwandlungsroutinen zur Verfügung. Wie bei der anderen Antwort müssten Sie herausfinden, was Ihnen ähnlich ist.

8

HSL ist ein schlechter Zug. L * a * b ist ein Farbraum, der entworfen wurde, um darzustellen, wie Farbe tatsächlich wahrgenommen wird, und basiert auf Daten von Hunderten von Experimenten mit Menschen mit echten Augen, die verschiedene Farben betrachten und sagen: "Ich kann den Unterschied zwischen diesen beiden unterscheiden diese zwei".

Die Entfernung im L * a * b-Raum entspricht der tatsächlichen wahrgenommenen Entfernung gemäß den aus diesen Experimenten abgeleiteten Vorhersagen.

Sobald Sie in L * a * b konvertieren, müssen Sie nur die lineare Entfernung in einem 3D-Raum messen.

+0

+1 schöner Gedanke. Weitere Informationen: http://en.wikipedia.org/wiki/Lab_color_space – BalusC

0

Dies ist eine ähnliche Frage zu #1634206.

Wenn Sie nach der Entfernung im RGB-Raum suchen, wird die euklidische Entfernung funktionieren, vorausgesetzt, dass Sie alle roten, grünen und blauen Werte gleich behandeln.

Wenn Sie sie anders gewichten möchten, wie es bei der Konvertierung von Farbe/RGB in Graustufen üblich ist, müssen Sie jede Komponente um einen anderen Betrag gewichten. Um zum Beispiel der beliebte Umwandlung von RGB mit Graustufen von 30% rot + 59% grün + 11% blau:

d2 = (30*(r1-r2))**2 + (59*(g1-g2))**2 + (11*(b1-b2))**2; 

Je kleiner der Wert von d2, je näher die Farben (r1,g1,b1) und (r2,g2,b2) zueinander sind.

Aber es gibt andere Farbräume als nur RGB, die möglicherweise besser zu Ihrem Problem passen.

+0

Die Gewichte dort sind Gammakorrekturgewichte.Während die Blautöne (11) keinen großen Beitrag zur menschlichen Wahrnehmung von Helligkeit leisten, machen sie tatsächlich eine große Diskriminierung in der menschlichen Bestimmung der Farbentfernung. http://www.comphase.com/cmetric.htm Die Gewichte 2,4,3 sind besser für den angegebenen Zweck. Ich ließ LAB (Delta E) durch jede Permutation des Farbabstandes (2^24 * 2^24) laufen und gemittelt werden. Und die Gewichte 22, 43, 35 sind besser (mit LAB als Ersatz für das menschliche Auge). Außerdem habe ich diesen gewichteten euklidischen Algorithmus implementiert, es ist scheiße! – Tatarize

-2

Ich habe es ausprobiert. der HSL/HSV-Wert ist definitiv nicht sinnvoll. zum Beispiel:

  • alle Farben mit L = 0 'schwarz' (RGB 000000), obwohl ihre HSL Differenz eine hohe Farbabstand verwickeln kann.

  • Alle Farben mit S = 0 sind eine Grautönung, obwohl ihre HSL-Differenz einen hohen Farbabstand bedeuten kann.

  • der H (Farbton) Bereich beginnt und endet mit einem Farbton von 'rot', also sind H = 0 und H = [max] (360 ° oder 100% oder 240, je nach Anwendung) rot und relativ ähnlich, aber die Euklidische HSL-Distanz ist nahe am Maximum.

so meine Empfehlung ist die euklidische RGB Abstand (r2-r1) ² + (g2-g1) ² + (b2-b1) ² ohne Wurzel zu verwenden. Die (subjektive) Schwelle von 1000 funktioniert dann für ähnliche Farben gut. Farben mit Unterschieden> 1000 sind vom menschlichen Auge gut zu unterscheiden. zusätzlich kann es hilfreich sein, die Komponenten unterschiedlich zu gewichten (siehe vorheriger Beitrag).

+0

Farbton ist ein Winkel. Sie können es nicht einfach in die euklidische Abstandsgleichung werfen. Sie müssen es als eine Position im Raum innerhalb einer Art von Form (Zylinder, Kegel) plotten und dann die Abstände zwischen diesen Positionen innerhalb dieser Form finden. Wenn Sie versuchen, es zu tun, würden Sie HSV (360 °, 1, 1) und HSV (0 °, 1, 1) HUGELY unterschiedlich finden, wenn sie wirklich die exakt gleiche Farbe (festes Rot) haben. – Tatarize

5

Wenn Sie HSV verwenden, müssen Sie erkennen, dass HSV keine Punkte in einem dreidimensionalen Raum sind, sondern eher der Winkel, die Größe und die Entfernung von oben von einem Kegel. Um den Abstand eines HSV-Wertes zu berechnen, müssen Sie entweder Ihre Punkte im 3D-Raum durch Transformieren bestimmen.

X = Cos (H) * S * V

Y = Sin (H) * S * V

Z = V

für beide Punkte und dann die euklidische Entfernung zwischen ihnen unter :

Sqrt((X0 - X1)*(X0 - X1) + (Y0 - Y1)*(Y0 - Y1) + (Z0 - Z1)*(Z0 - Z1)) 

Zu einem Preis von 2 Cos, 2 Sin und einer Quadratwurzel.

Alternativ können Sie die Entfernung auch etwas einfacher berechnen, wenn Sie so geneigt sind, wenn Sie in 2D-Raum abgeflacht sind, haben Sie einfach zwei Vektoren vom Ursprung und wenden das Cosinus-Gesetz an, um den Abstand im XY-Raum zu finden :

C² = A² + B² + 2*A*B*Cos(Theta) 

wobei A = S * V des ersten Werts und B = S * V des zweiten und Cosinus ist der Unterschied Theta oder H0-H1

Dann man in Z-Faktor, zu erweitern der 2D-Raum in den 3D-Raum.

A = S0*V0 
B = S1*V1 
dTheta = H1-H0 
dZ = V0-V1 
distance = sqrt(dZ*dZ + A*A + B*B + 2*A*B*Cos(dTheta); 

Beachten Sie, dass, weil das Gesetz von cosigns uns gibt C² wir gerade stecken Sie es direkt dort mit der Änderung in Z. Welche 1 Cos und 1 Sqrt kostet. HSV ist sehr nützlich, Sie müssen nur wissen, welche Art von Farbraum es beschreibt. Sie können sie nicht einfach in eine euklidische Funktion bringen und etwas kohärentes daraus ziehen.

1

Es ist ein interessantes Papier auf genau dieses Problem:

A New wahrnehmungs Uniform Farbraum mit zugehörigen Farb Ähnlichkeitsmaß für Content-basierte Bild- und Videowieder von M. Sarifuddin und Rokia Missaoui

Sie können dies leicht mit Google oder insbesondere [Google Scholar.] Finden [1]

Zusammengefasst, einige Farbräume (zB RGB, HSV, Lab) und Distanzmessung res (wie der geometrische Mittelwert und der euklidische Abstand) sind bessere Darstellungen der menschlichen Wahrnehmung der Farbähnlichkeit als andere. Die Arbeit spricht von einem neuen Farbraum, der besser ist als der Rest, bietet aber auch einen guten Vergleich der gängigen Farbräume und Distanzmaße. Qualitativ * scheint es das beste Maß für die Wahrnehmungsdistanz unter Verwendung von allgemein verfügbaren Farbräumen zu sein: der HSV-Farbraum und ein zylindrisches Abstandsmaß.

* Zumindest laut Abbildung 15 in dem referenzierten Papier.

Das zylindrische Abstandsmaß ist (in Latex-Notation):

D_ {} cyl = \ sqrt {\ Delta V^{2} + S_1^{2} + S_2^{2} -2S_1S_2cos (\ Delta H)}

+2

Nachdem ich das Papier gelesen und den Algorithmus implementiert habe. Es ist im Grunde Mist. Es ist nicht schrecklich, aber es ist wirklich nicht besser als der HSV. Die Ableitung der C- und L-Variablen ist in Ordnung, das Papier listet den Farbton falsch auf (wenn Sie die Werte als grün = rot angegeben haben). Die Nähe von Abbildung 15 ist auf eine fehlerhafte Methodik zurückzuführen. Es wies Farben zurück, bis es genug hatte, um diesen Bereich zu füllen. So wird jeder Farbraum an der Schwelle der Ablehnung bewertet, die ihm gegeben wurde, und * NOT * ist die Fähigkeit, angemessen zu reflektieren, was der durchschnittliche Mensch als die unterschiedlichsten Farben beurteilen würde. Und das sind nicht einmal alle Fehler. – Tatarize

Verwandte Themen