Überprüfen ob zwei Farben ähnlich sind

Status
Nicht offen für weitere Antworten.

The_S

Top Contributor
Hi,

kennt jemand nen guten Algorithmus/Ansatz, mit dem ich überprüfen kann, ob zwei RGB-Farben für das menschliche Auge fast identisch aussehen? Das Einzige, was mir jetzt einfallen würde, wäre die Differenz aller Kanäle zusammenzuzählen und dann überprüfen, ob sich der Wert über/unterhalb eines Richtwertes befindet. Halte ich jetzt aber für nicht so effektiv ;) .

Danke!

[edit] Hintergrund ist der, dass ich n Zufallsfarben erstellen möchte, die sich möglichst gut voneinander abheben.
 

Oni

Top Contributor
wenn die möglichst unterschiedlich sein sollen, dann nimm doch die komplementärfarben.


Farbe + Komplementärfarbe = Weiss

Weiss - Farbe = Komplementärfarbe

gilt natürlich nur für den RGB Farbraum
 

The_S

Top Contributor
Glaub du hast mein Problem n bisschen falsch interpretiert ;) .

Ich hab wie gesagt nicht nur 2 Farben, die nicht ähnlich sein dürfen, sondern N Farben, die alle zueinander nicht ähnlich sein dürfen. Und wenn ich feststellen kann, ob 2 Farben zueinander nicht ähnlich sind, kann ich das auch für alle feststellen.

Jetzt klarer?

Aber danke!
 

Der Müde Joe

Top Contributor
fällt mir gerade keine Routine ein, aber etwas hintergrundwissen

EDIT: wegeditiert...

..der muss mal wieder wegeditiert werden...!
 

0x7F800000

Top Contributor
RGB ist doch einfach isomorph zu einem R³-vektorraum, da kannst du "abstände" zwischen zwei Farben beispielsweise mit der gewöhnlichen euklidischen Norm berechnen: also einfach mit dem Satz des Pythagoras für den dreidimensionalen Fall... Nun hast du im R³ also so einen Quader [0,255]x[0,255]x[0,255], wo alle verfügbare Farben drin enthalten sind. Jetzt musst du in diesem Würfel N Punkte wählen, die voneinander einen möglischst großen Abstand haben
Code:
//abstansfunktion irgendwie aus dem satz des pythagoras basteln...
d(c1,c2)=sqrt((c1.red-c2.red)²+(c1.grün-c2.grün)²+(c1.blau-c2.blau)²)
Wie man jetzt in so einem Würfel N Punkte so anordnet ist eine verdammt gute frage, ich bezweifle, dass es da eine allgemeine Lösung gibt...

Wenn du diese farben nur selten auswählen musst (zB. einmal beim Programmstart, also nicht 100 mal pro Sekunde), würde _ich_ persönlich wie folgt verfahren: Du könntest so eine Art Simulation starten: Punkte werden anfangs zufällig im Würfel Plaziert, und diese stoßen sich alle gegenseitig ab (zB mit einer "Kraft" die proportional zu 1/r² ist: da sparst du dir das wurzelziehen) nach ein paar simulationsschritten stellt sich eine gleichgewichtslage ein, bei der die Punkte im würfel ziemlich optimal verteilt sind. Dann einfach die positionen auslesen, runden, als Farben interpretieren.

Ich hab's zwar noch nie ausprobiert, aber der Ansatz ist imho recht naheliegend:
Würde man zB N "elektronen" in ein Gebiet reinschmeissen, und dort irgendwie für "reibung" sorgen, würden diese sich dort nach einer weile recht optimal verteilen... habs irgendwo gelesen... kP, könntest das vielleicht ausprobieren... vielleicht hilfts was :lol:


edit: komplementärfarben würde ich nicht empfehlen, in der Nähe von Grau, also (127,127,127) bleibt das komplement ebenfalls einfach nur grau, da kannst du nichts mehr unterscheiden.... geht eh nur für 2 farben...
 

Marco13

Top Contributor
RGB ist dafür ziemlich ungeeignet: Es gibt dort kein gutes "Maß" für die Ähnlichkeit. Wenn man z.B. die Manhattan-Distanz der Farbwerte verwendet, oder einen anderen "Abstand der Punkte im Farbraum", dann kann es sein, dass man zwei Farben mit Abstand "0.232" noch als "fast gleich" ansieht, und zwei andere Farben mit Abstand "0.121" als kaum unterscheidbar.

Viel näher an der menschlichen Wahrnehmung ist das HSB-Modell.
http://de.wikipedia.org/wiki/HSB-Farbraum
Dort kann man z.B. Farbton-Unterschiede SEHR stark gewichten, Helligkeitsunterschiede mittel, und Sättigungsunterschiede etwas geringer. Jedenfalls dürfte man damit leichter so ein Ähnlichkeitsmaß hinbekommen.
 

Marco13

Top Contributor
So als Nachtrag: Um möglichst unterschiedliche Farben zu generieren, würde sich dann anbieten, für den Farbton (Hue) die Farben zu nehmen, die rauskommen, wenn man auf den Farbkreis ein ... naja, vielleicht ein 8-Eck legt. Dann kann man noch jeweils mit 1.0 und 0.5 Helligkeit (oder evtl. Sättigung) große Unterschiede erreichen.

Um zu EINER Farbe eine möglichst unterschiedliche zu finden, würde man für den Hue einfach den Wert nehmen, der auf dem Farbkreis "gegenüber" der ursprünglichen Farbe liegt. Ein bißchen aufpassen muss man aber immer: Das HSB-Modell hat unten eine Spitze, d.h. mit "Helligekeit 0" sehen alle Farben gleich aus :wink:
 

0x7F800000

Top Contributor
hm... ich finds ne recht interessante frage, wie man denn sowas nun anstellen soll...

habe hier folgendes zusammengebastelt (lässt sich direkt reinkopieren, kompillieren, ausführen, ist vollständig)

Code:
import java.awt.*;
import javax.swing.*;

public class ColorRandomizer {

	public static Color[] getRandomColors(int N){
		
		//proportionalitätskonstanten. C für abstoßung, R für reibung, dt= zeitsprünge...
		final double C=1,R=-0.1, dt=10;
		double interactionRadiusSq=2*Math.pow(3d/(4*Math.PI*N), 2d/3d)*65536;
		//N zufällige Punkte im Würfel [0,255]³ erzeugen
		Vector3D[] x=new Vector3D[N];
		Vector3D[] v=new Vector3D[N];
		Vector3D[] a=new Vector3D[N];
		
		//anfängliche positionen, geschwindigkeiten und beschleunigungen initialisieren
		for(int i=0; i<N; i++){
			x[i]=new Vector3D(Math.random()*255, Math.random()*255,Math.random()*255);
			v[i]=a[i]=Vector3D.NULL;
		}
		
		Vector3D connection; //verbindungsvektor zwischen zwei punkten
		double connectionLengthSq; //länge quadriert
		//simulation 
		for(double t=0; t<10000; t+=dt){
			//gesamtbeschleunigungen mit superpositionsprinzip ausrechnen
			for(int k=0; k<N; k++){
				a[k]=new Vector3D(0,0,0);
					for(int j=0; j<N; j++){
						if(k!=j){
							connection=x[k].sub(x[j]);
							connectionLengthSq=connection.getSqLength();
							if(connectionLengthSq<interactionRadiusSq){
								a[k]=a[k].add(connection.mul(C/connectionLengthSq));
							}
						}
					}
				//geschwindigkeiten aktualisieren (coulomb+reibungskräfte berücksichtigen)
				v[k]=v[k].add((a[k].add(v[k].mul(R))).mul(dt));
			}
			
			//einfach alle punkte um v*dt verschieben
			for(int k=0; k<N; k++){
				x[k]=x[k].add(v[k].mul(dt));
				//guggen, dass alles im würfel bleibt (bissl hässlich :-/ )
				if(x[k].x<0){ x[k].x=0; }else if(x[k].x>255){x[k].x=255;}
				if(x[k].y<0){ x[k].y=0; }else if(x[k].y>255){x[k].y=255;}
				if(x[k].z<0){ x[k].z=0; }else if(x[k].z>255){x[k].z=255;}
			}
			
		}
		
		//so, jetzt sollte sich da was brauchbares eingependelt haben
		Color[] result=new Color[N];
		for(int i=0; i<N; i++){
			result[i]=new Color((int)(x[i].x),(int)(x[i].y),(int)(x[i].z));
		}
		
		return result;
	}
	
	
	public static void main(String[] args){
		int N=30;
		
		Color[] colors=getRandomColors(N);
		
		JFrame f=new JFrame("zufallsfarben");
		f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		f.setBounds(10,200,1000,70);
		f.setVisible(true);
		

		Graphics g=f.getGraphics();
		
		for(int warumSehIchNIX=0; warumSehIchNIX<10000; warumSehIchNIX++){
		for(int i=0; i<N; i++){
			g.setColor(colors[i]);
			g.fillRect((int)(1000*i/(float)N), 0, 1000/N, 100);
		}
		}
		
		for(int i=0; i<N; i++){
			System.out.println(colors[i]);
		}
	}
	
}

leider scheinen sich diese farbwerte immer auf dem rand des Würfels zu verteilen, das find ich jetzt ein wenig doof :autsch: bei wenigen farben (bis 8) sucht das programm sich, wie erwartet, die "ecken" des würfels aus, also farben mit werten 0 oder 255... sonst funktioniert es nicht so toll wie erhofft... kA, was haltet ihr denn davon? :bahnhof:

edit: eeeheheh, hab da grad noch einen guten einfall :idea: :bae: moment...

edit2: so, habs jetzt nachgebessert, jetzt wird auch das innere des verfügbaren farbwürfels gut ausgefüllt...

edit3: hoppla, hab ja ganz vergessen, dass Vector3D mein eigener mist ist, schuldigung^^ :oops:

Code:
//3D-Vector that represents a point in cartesian coords

public class Vector3D {
	
	//xyz
	double x,y,z;
	
	//constructors
	public Vector3D(){
		x=y=z=0.0;
	}
	
	public Vector3D(double _x,double _y,double _z){
		x=_x; y=_y; z=_z;
	}
	
	public Vector3D(Vector3D v){
		x=v.x; y=v.y; z=v.z;
	}
	
	//getLength, getSqrLength
	public double getLength(){
		return Math.sqrt(x*x+y*y+z*z);
	}
	
	public double getSqLength(){
		return x*x+y*y+z*z;
	}
	
	// v+v v-v 
	public Vector3D add(Vector3D v){
		return new Vector3D(x+v.x, y+v.y, z+v.z);
	}
	
	public Vector3D sub(Vector3D v){
		return new Vector3D(x-v.x, y-v.y, z-v.z);
	}
	
	//v*d v/d
	public Vector3D mul(double d){
		return new Vector3D(x*d, y*d, z*d);
	}
	
	public Vector3D div(double d){
		return new Vector3D(x/d, y/d, z/d);
	}
	
	//scalar and cross products
	public double dot(Vector3D v){
		return x*v.x+y*v.y+z*v.z;
	}
	
	public Vector3D cross(Vector3D v){
		return new Vector3D(y*v.z-z*v.y,
							z*v.x-x*v.z,
							x*v.y-y*v.x);
	}
	
	//getCos getSin getAngle
	public double getCos(Vector3D v){
		return this.dot(v)/Math.sqrt(this.getSqLength()*v.getSqLength());
	}
	
	public double getSin(Vector3D v){
		return Math.sqrt(this.cross(v).getSqLength()/(this.getSqLength()*v.getSqLength()));
	}
	
	public double getAngle(Vector3D v){
		return Math.acos(this.getCos(v));
	}
	
	//some useful static constants and functions
	public static final Vector3D NULL=new Vector3D(0,0,0);
	public static final Vector3D eX=new Vector3D(1,0,0);
	public static final Vector3D eY=new Vector3D(0,1,0);
	public static final Vector3D eZ=new Vector3D(0,0,1);
}
so, jetzt dürfte es laufen^^
 

0x7F800000

Top Contributor
Wenn mir jetzt irgendwer erklären könnte, wie ich denn nun von RGB in dieses L*a*b umrechne, und vor allem: wie geht es umgekehrt... :### :autsch:
 

The_S

Top Contributor
Uff ... da habt ihr ja ganz schön viel zusammen getragen :-D . Danke dafür, werd ich mir mal alles in Ruhe durchlesen.
 

tincup

Bekanntes Mitglied
Andrey hat gesagt.:
Wenn mir jetzt irgendwer erklären könnte, wie ich denn nun von RGB in dieses L*a*b umrechne, und vor allem: wie geht es umgekehrt... :### :autsch:

Zumindest die Hinrichtung ist bei Wiki beschrieben:
http://de.wikipedia.org/wiki/Lab-Farbraum#Umrechnung_von_RGB_zu_Lab

6f6e2bca59dabf55f415025cfeedf36b.png

d82578e40ba624e2b7d8ecac1979ea01.png

625c2e634ca390f313fce5f3ab527c57.png


Andersrum müsste jetzt mal einer seine algebraischen Fähigkeiten oder sein Computeralgebra-Programm benutzen. :wink: (also entsprechend die Matrix invertieren)
 

Marco13

Top Contributor
Andrey hat gesagt.:
Code:
		Graphics g=f.getGraphics();
		
		for(int warumSehIchNIX=0; warumSehIchNIX<10000; warumSehIchNIX++){
Ggf. wird die drei mal gestellte Frage durch die Zeile darüber schon beantwortet :wink:
 

0x7F800000

Top Contributor
Marco13 hat gesagt.:
Andrey hat gesagt.:
Code:
		Graphics g=f.getGraphics();
		
		for(int warumSehIchNIX=0; warumSehIchNIX<10000; warumSehIchNIX++){
Ggf. wird die drei mal gestellte Frage durch die Zeile darüber schon beantwortet :wink:

jaja, schon klar, aber ich kenne bisher keine kürzere, hässlichere und dreckigere möglichkeit irgendetwas auf dem bildschirm darzustellen. :autsch: :bae: Aber ich nehme mal schwer an dass der Hobbit_Im_Blutrausch weiss wie er alles sauber und doppelt gepuffert zeichnet, allgemeine fragen zum zeichnen stehen hier eh nicht zur debatte, es sollte halt irgendwie laufen, und möglichst wenig von der eigentlich interessanten funktion ablenken. Aber du hast natürlich recht Marco13, ich hätte irgendetwas wie
"Code nicht für Programmierer unter 18 geeignet"
oder
"Dieser Stunt wurde vom speziell ausgebildeten Personal erstellt, versuchen Sie es nicht zuhause nachzumachen!"
dahinschreiben sollen :lol:
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
M Java Überprüfen ob .exe-Datei bereits ausgeführt wird Allgemeine Java-Themen 2
F Überprüfen ob es Überschneidungen von Uhrzeiten (vom Typ Calendar) gibt Allgemeine Java-Themen 10
S Überprüfen, ob 5 Zahlen nebeneinander liegen Allgemeine Java-Themen 5
S Applet Überprüfen ob ein Objekt angeklickt wurde Allgemeine Java-Themen 2
J Überprüfen ob URL eine HTML Datei referenziert Allgemeine Java-Themen 4
T Überprüfen mathematischer Bedingungen Allgemeine Java-Themen 9
S Überprüfen von Datums/zeitwerten Allgemeine Java-Themen 4
simon1101 Überprüfen ob Dateiendung stimmt Allgemeine Java-Themen 4
M Eingabe Überprüfen Allgemeine Java-Themen 3
A Überprüfen, ob ein File eine Verknüpfung / Link ist Allgemeine Java-Themen 3
G Überprüfen, ob Variable ein Array ist? Allgemeine Java-Themen 5
S Überprüfen, ob ein Shell Befehl existiert! Allgemeine Java-Themen 4
D Überprüfen ob Superuser Allgemeine Java-Themen 7
S Überprüfen von Intervallen Allgemeine Java-Themen 4
M Überprüfen, ob ein Bit gesetzt ist Allgemeine Java-Themen 3
G Überprüfen ob ein String in einem anderen String vorhanden? Allgemeine Java-Themen 2
G Überprüfen, ob Datei geöffnet ist! Allgemeine Java-Themen 3
M Überprüfen einer zur Laufzeit geladenen Klasse Allgemeine Java-Themen 3
P Überprüfen, ob Datentyp ein Objekt ist Allgemeine Java-Themen 17
O Text aus einer Textdatei rausholen, der zwischen zwei Schlüsselworten steht Allgemeine Java-Themen 4
D Zwei Listen vergleichen Allgemeine Java-Themen 7
Tobero Wie berechnet man ob zwei Linien sich schneiden? Allgemeine Java-Themen 2
kodela Zwei gleichzeitig gedrückte Steuertasten Allgemeine Java-Themen 10
X Bedingung zwei mal überprüfen Allgemeine Java-Themen 4
Zrebna Random Number - Generische Formel zwischen zwei INKLUSIVEN Werten Allgemeine Java-Themen 16
D Input/Output Zwischen zwei ID-Räumen unterscheiden und Objekt löschen Allgemeine Java-Themen 16
D OOP Gemeinsamen ID-Raum für zwei Klassen implementieren Allgemeine Java-Themen 7
S Wenn eine Klasse zwei Interfaces mit derselben Methodensignatur implementiert: welche wird aufgerufen? Allgemeine Java-Themen 15
S Kann man Variablen oder Felder definieren deren Typ zwei Interfaces ist..? Allgemeine Java-Themen 9
K Aus String zwei Jahreszahlen auslesen Allgemeine Java-Themen 18
M Wie kann man eine void Methode mit Variablen von zwei verschiedenen Objekten ausführen? Allgemeine Java-Themen 15
VfL_Freak Double mit zwei festen NK-Stellen ausgeben Allgemeine Java-Themen 9
Neoline Methoden Zwei Arrays abwechselnd zusammenführen Allgemeine Java-Themen 15
J Zwei Wavdateien gleichzeitig mit SourceDataLine abspielen Allgemeine Java-Themen 0
D Best Practice Die niedrigste Differenz zwischen zwei Listen ermitteln. Allgemeine Java-Themen 10
J Fahrroute zwischen zwei Punkten finden Allgemeine Java-Themen 1
J Kollision von zwei Kreisen Allgemeine Java-Themen 15
J Transfer von Integer zwischen zwei Clients - RMI Allgemeine Java-Themen 4
S Variablen split-Funkton mit zwei Variabeln verwenden? Allgemeine Java-Themen 4
T Alle Kombinationen aus zwei Arrays Allgemeine Java-Themen 8
G Liste zwischen zwei Kalenderdaten erstellen Allgemeine Java-Themen 3
AssELAss Zwei Arrays / ArrayLists inhaltlich vergleichen Allgemeine Java-Themen 2
H RegularExpression zwischen zwei Strings Allgemeine Java-Themen 2
P Zwei Applikationen mit einem Job Allgemeine Java-Themen 0
A Lineare Interpolation mit zwei Arrays Allgemeine Java-Themen 4
E Berechnung des Schnittpunktes von zwei Geraden Allgemeine Java-Themen 1
S Zwei String vergleichen, Fehler markieren Allgemeine Java-Themen 3
G Matrix reduzieren zwei Methoden Allgemeine Java-Themen 2
Dechasa Vergleichen von zwei Arrays Allgemeine Java-Themen 4
P Zwei ArrayLists: Ohne die eine überhaupt anzurühren, wird sie verändert Allgemeine Java-Themen 2
S Anwendung zum ausrechnen der Differenz von zwei Tagen Allgemeine Java-Themen 9
F Zwei LinkedHashMaps iterieren und vergleichen Allgemeine Java-Themen 2
M Zwei unterschiedliche JAR Dateien mit ANT erstellen Allgemeine Java-Themen 8
B Fehler beim Auslesen von Einstellungen. Zwei ähnliche Blöcke, nur eins geht. Allgemeine Java-Themen 5
L Zwei Files miteinander vergleichen und Grafisch darstellen Allgemeine Java-Themen 1
T Zwei Wortendungen vergleichen ohne .equals Allgemeine Java-Themen 10
F Webstart zwei Java Versionen / aktivieren bzw deaktivieren Allgemeine Java-Themen 2
S Zwei Comparable (compareTo) vergleichen Allgemeine Java-Themen 6
E zwei Gleitkommazahlen durcheinander dividieren Allgemeine Java-Themen 2
X Generic muss zwei Klassen/Interfaces erfüllen Allgemeine Java-Themen 5
turmaline OOP zwei gleiche Methoden mit kleinen Unterschieden Allgemeine Java-Themen 15
C Threads Zwei Threads greifen auf LinkedList zu. Allgemeine Java-Themen 12
T Wie heißt ein Binärbaum, dessen Knoten immer zwei Kinder haben müssen? Allgemeine Java-Themen 2
C ActionListener zwei Buttons zuweisen Allgemeine Java-Themen 11
M Eclipse drei slashs durch zwei ersetzen? Allgemeine Java-Themen 3
1 zwei Strings vergleichen Allgemeine Java-Themen 16
C Buchstaben, die in zwei Wörtern vorkommen Allgemeine Java-Themen 13
J Gleiche Packagestruktur in zwei *.jar Dateien Allgemeine Java-Themen 4
G Zwei bytes vergleichen Allgemeine Java-Themen 2
B zwei-dimensionale Collections bzw. Array mit Indizes Allgemeine Java-Themen 3
C Zwei Arrays vereinen Allgemeine Java-Themen 3
K Objekt-Austausch zwischen zwei Programmen über System-Clipboard Allgemeine Java-Themen 5
H Zwei verschiedene Dateien mittels einem Binärstream übertragen? Allgemeine Java-Themen 13
N hashCode() für zwei ints Allgemeine Java-Themen 5
turmaline Gleichheit von zwei Maps Map <String, Map <String, String>> Allgemeine Java-Themen 30
N Wie Listenabgleich auf zwei CPU Cores auslagern? Allgemeine Java-Themen 6
D Zufall wahr bzw. falsch mit zwei Faktoren Allgemeine Java-Themen 10
H Datenaustausch zwischen zwei Java-Programmen Allgemeine Java-Themen 5
H Ausgabe von zwei Textfeldern Allgemeine Java-Themen 3
H Zwei unabhängige Threads miteinander kommunizieren lassen Allgemeine Java-Themen 3
G zwei mal synchronized Allgemeine Java-Themen 5
Z zwei Daten vergleichen Allgemeine Java-Themen 4
C ArrayList anhand von zwei Attributen sortieren Allgemeine Java-Themen 4
S Alle Elemente von zwei Listen vergleichen Allgemeine Java-Themen 10
T IText: Zwei A4 PDF´s auf ein A3 PDF´s Allgemeine Java-Themen 2
J Verschachtelte ListIteratoren um in zwei Listen hin und herzugehen Allgemeine Java-Themen 5
A Differenz zwischen zwei Uhrzeiten Allgemeine Java-Themen 7
H Shortcut ruft zwei Menu-punkte auf Allgemeine Java-Themen 5
J Zwei konstruktoren? Allgemeine Java-Themen 8
A zwei listen vergleichen und unterschiede anzeigen Allgemeine Java-Themen 3
J Zwei sortierte Listen zusammenfassen Allgemeine Java-Themen 8
G Linked List zwischen zwei Threds übergeben Allgemeine Java-Themen 11
J zwei HashMaps vereinen Allgemeine Java-Themen 3
C Viele Informationen aus zwei Collections vergleichen Allgemeine Java-Themen 2
G Jfreechart zwei charts Allgemeine Java-Themen 2
S Zwei Anwendungen unter Tomcat Allgemeine Java-Themen 4
T Anzahl Tage zwischen zwei Daten - Stunde fehlt? Allgemeine Java-Themen 2
V Zwei ArrayList(s) vergleichen Allgemeine Java-Themen 6
M zwei main-Methoden Allgemeine Java-Themen 7
P zwei JFrames zusammenhängen Allgemeine Java-Themen 4

Ähnliche Java Themen

Neue Themen


Oben