Autor Beitrag
lemming
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 470

Mac OS 10.3.1
Delphi 6 Pro, Kylix 3
BeitragVerfasst: Do 25.03.04 12:38 
Hi!

Ich will ein Bild, das mit 16mio Farben dargestellt wird, in ein Bild mit 256 Farben umändern. Wenn ich mit Canvas.Pixels[x,y] den Farbwert auslese ist dieser ja schliesslich eine zahl zwischen 0 und 16mio. Mit welcher Formel komme ich aber auf die annähernd passende Farbe bei nur 256 Farben?

danke für die Hilfe. lemming


Moderiert von user profile icontommie-lie: Topic verschoben
Udontknow
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: Do 25.03.04 13:13 
Hi!

Du solltest die Farben, die am häufigsten vorkommen, aber sich nicht zu ähnlich sind, auswählen. Also musst du eine Liste der Farben generieren und einen gewissen Toleranzwert festlegen.

Du vergleichst alle Farben miteinander, und wenn eine Farbähnlichkeit zu gross ist (abhängig vom Toleranzwert), wird die Farbe mit der geringeren Pixelanzahl aus der Liste gelöscht. Wenn nach diesem Procedere noch immer mehr als 256 Farben vorhanden sind, musst du die Toleranz erhöhen und erneut vergleichen.

Anschliessend musst du jedem Pixel die passenden RGB-Werte zuweisen, indem du für jeden Farbwert die Farbe aus den 256 ermittelst, die dem Farbton am nächsten kommt.

Hier mal eine Funktion, die sich vielleicht für den Farbvergleich eignet...

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
function FarbDistanz(Color1,Color2:Cardinal):Real;
var R1,R2,G1,G2,B1,B2:Byte;
begin
  //noch vorher Farbwerte aufsplitten, bin gerade zu faul...  :wink: 
  ...
  Result:=Sqrt(Sqr(R2-R1)+Sqr(G2-G1)+Sqr(B2-B1));
end;


Edit: Sqrt-Funktion eingefügt.

Cu,
Udontknow


Zuletzt bearbeitet von Udontknow am Do 25.03.04 16:09, insgesamt 2-mal bearbeitet
lemming Threadstarter
ontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic starofftopic star
Beiträge: 470

Mac OS 10.3.1
Delphi 6 Pro, Kylix 3
BeitragVerfasst: Do 25.03.04 14:03 
Ok, verstehe. Ich mach es so. Als Ausgangspunkt werde ich die Windows/DOS 256 Farbenpalette nehmen. Schliesslich muss das Bild unter DOS angezeigt werden. (Hab ich verheimlicht ;) ). Dann such ich aus der 16 mio Farbpalette die Ranges heraus die zu dem Bild apssen. Mir kommt es gar nicht darauf an das es perfekt wird. Die Farbgenauigkeit oder Annäherung ist also nicht so wichtig. Man sollte nur einen Kontrast sehen können. Werde deinen Code aber trotzdem ausprobieren. Danke.
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8548
Erhaltene Danke: 477

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Do 25.03.04 14:24 
Zitat:
Du solltest die Farben, die am häufigsten vorkommen, aber sich nicht zu ähnlich sind, auswählen. Also musst du eine Liste der Farben generieren und einen gewissen Toleranzwert festlegen.

Sorry, aber das is ja nun mehr als schwammig. 256 Farben auszuwählen, die das Bild gut wiedergeben können, ist ziemlich schwierig denke ich mal. Und man sieht ja auch, was einfache Programme da manchmal ür nen Murks machen. Denn es kann ja. z.b. sein, dass ein Bild am Rand irgendwo je 10 gleiche Pixel hat, aber der Hauptteil ein buntes Photo ist, bei dem jeder Farbwert höchstens 2mal genau gleich ist...und wenn die Pixel am Rand dann auch noch alles verschiedene Grüntöne sind, aber das Bild zeigt einen Sonnenuntergang am blauen Meer....

Ich würde für Probezwecke erstmal 256 feste Farben wählen, die im RGB- Würfel einigermassen gleichverteilt sind, z.b. 0,0,0 / 42,0,0 / 84,0,0,... , 0,42,0,..., 0,0,42,..... (die 42 hat nix mit meiner Signatur zu tun, aber wenn man den Würfel in ein 6x6x6 Gitter aufteilt, kommt man auf 216 (das sind fast 256) Gitterpunkte, und 256/6 sind etwas mehr als 42...)

Aber angenommen, wir hätten unsere 256 Farben schon.

Das mit der Formel kann gut gehen, muss aber nicht. Das liegt daran, dass Farben mit relativ wenig Kontrast (d.h. sie wirken irgendwie grau) und einer gewissen Helligkeit (ein mittleres Grau, nicht zu hell und nicht zu dunkel), alle sehr nah beieinander im RGB-Würfel liegen. Trotzdem wirkt die eine Farbe etwas grün, die andere etwas rot. Hab mit dieser Abstandsformel eher schlechte Erfahrungen gemacht. Damals hatte ich aber auch nur 24 Farben zur Verfügung, auf die ich das Bild reduzieren musste.
Bin dann mit der Zeit auf den Trichter gekommen, ein anderes Farbmodell zu nehmen. Helligkeit, Sättigung, Farbton. Habe dann aber keine Zeit mehr gehabt, das komplett umzusetzen. Am wichtigsten sollte sein, dass der Farbton getroffen wird, und dann mit einigermassen gleicher Priorität die Helligkeit und Sättigung.
Umrechnung RGB- Helligkeit, Sättigung, Farbton:

ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
// Stimmt nicht ganz, da die verschiedenen Farben vom menschlichem Auge anders intensiv wahrgenommen werden...
   Helligkeit:= (r+g+b) /3

// Die Sättigung ist der Abstand des Wertes RGB zum Lotpunkt auf die "GraueDiagonale" im RGB-Würfel von 0,0,0 nach 255,255,255
    m:=(r+g+b)/3//=Helligkeit
    //Richtungsvektor von Lotpunkt zum Punkt RGB
    mb:=b-m;
    mg:=g-m;
    mr:=r-m;
    saettigung := sqrt((mb*mb)+(mg*mg)+(mr*mr));

Zum Farbton finde ich grade keine Formel mehr. Hab da nur ne Formel, wie man den Farbton eines Bildes ändert...den Farbton selbst bestimmt habe ich noch nicht. Aber der Farbton ist der Winkel zwischen folgenden beiden Ebenen:
Die erste ist gegeben durch die Punkt 0,0,0 255,255,255 und r,g,b deiner Farbe
Die zweite durch 0,0,0 255,255,255 255,0,0 (das sollte die "rote Ebene" sein, d.h alle Farben auf dieser Ebene nehmen wir als rot wahr.)
Such mal in einem Mathebuch der Oberstufe oder im Netz nach "Winkelberechnung zwischen Ebenen". Mit ein bissel Mathe-Grundkenntnissen kommt man da durch.

Wenn du nun eine bestimmte Farbe ersetzen willst, solltest du eine nehmen, die am ehsten dem Farbwert entspricht, und dann Helligkeit- und Sättigungsdifferenz minimieren.


Aber vielleicht reicht es dir ja auch, das Bild in ein TBitmap zu laden, und dann die Eigenschaft "pixelformat" zu ändern...

_________________
We are, we were and will not be.
Udontknow
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2596

Win7
D2006 WIN32, .NET (C#)
BeitragVerfasst: Do 25.03.04 14:35 
Zitat:
Sorry, aber das is ja nun mehr als schwammig.


Du musst dich nicht entschuldigen. :wink: Ich habe habe es extra so "schwammig" geschrieben, weil ich selber auch weiss, daß das Thema nicht einfach ist. Deshalb schrieb ich ja auch "Hier mal eine Funktion, die sich vielleicht für den Farbvergleich eignet... ". Das Hauptaugenmerk richtete ich eigentlich auch auf den Algo, die Liste zusammenzustellen und je nach Häufigkeit und Farbabstand die Farben zu ermitteln. Ausserdem braucht er es ja auch nicht so genau.

Edit: Hmmm, irgendwie habe ich vergessen die Wurzel zu ziehen, damit die Funktion oben auch wirklich dementsprechend die Distanz im RGB-Würfel zurückgibt.

Cu,
Udontknow
DaRkFiRe
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 526

WinXP Home & Professional
C, C++, Delphi
BeitragVerfasst: Do 25.03.04 16:47 
Um Farben und ähnliche Farben zusammenzufassen, würde sich dann wohl eher das HSL Farbmodell eignen - dafür gibt es auch entsprechende Umrechnungsformeln.

Da das HSL nach Hue (Farbton), Saturation (Sättigung) und Helligkeit (Luminance) unterscheidet, eignet sich es für die Darstellung ähnlicher Farben besser, da man eine Farbe als Mensch so besser darstellen und unterscheiden kann.

_________________
Lang ist der Weg durch Lehren - kurz und wirksam durch Beispiele! Seneca
Matthias
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 121



BeitragVerfasst: Do 25.03.04 17:42 
Hallo,

Das mit dem Mensch und Farben ist nicht so einfach. Ein mathematisches Modell zu erstellen, welches für den Menschen ähnliche Farben auch dicht in einem Fabmodel neben einander darstellt, zu erstellen ist recht komplex. Dies wurde natürlich schon experimentell ermittelt. Als Ergebnis ist das Fabmodell CIELAB mit den Parametern L A B herausgekommen.

Alle schon genannten Modelle sind nicht geeignet ähnliche Farben durch Ihren vektoriellen Absand zu ermitteln.

Die diskutierten Möglichkeiten halte ich schon mal für sehr interessant. Ich denke das es zudem Hilfreich sein könnte über ein Histogramm die Häufigkeit von verwendetn Farben zu ermitteln. Hier lässt sich bestimmt schon eine Reduktion erreichen.

Matthias
Keldorn
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 2266
Erhaltene Danke: 4

Vista
D6 Prof, D 2005 Pro, D2007 Pro, DelphiXE2 Pro
BeitragVerfasst: Do 25.03.04 19:23 
Hallo

auf der efg-seite findest sich auch was dazu :
www.efg2.com/Lab/Gra...lors/ShowDemoOne.htm
www.efg2.com/Lab/Gra...olors/PaletteLab.htm

Mfg Frank

_________________
Lükes Grundlage der Programmierung: Es wird nicht funktionieren.
(Murphy)