Hallo, ich beschäftige mich grad mit der Umrechnung von HSV nach RGB. Hier im Forum gibt's ja schon einige Beispiele dazu, u.a. auch eine von Benedikt K. verfasste Variante, welche ohne float-Werte zurechtkommt: Beitrag "Re: HSV RGB Led Dimmer, C Code & Video & Doku" Recht praktisch, da ich das in ASM auf einem 8051 machen will. Allerdings bräuchte ich auch den umgekehrten Weg, das heisst von RGB zu HSV. Mir ist klar, dass es natürlich Umrechnungsverluste gibt, wenn man nicht mit float o.ä. arbeitet. Diese Umrechnungsverluste an sich spielen keine Rolle. Ich bräuchte aber die beiden Berechnungen so, dass es zwischen den Umrechnungen keine Verluste gibt. Deswegen grübel ich gerade, ob es überhaupt Sinn macht, die Berechnungen auf dem Controller durchzuführen und stattdessen eher Tabellen zu verwenden (was auch der Geschwindigkeit zugute kommt). Im Wikipedia-Artikel http://de.wikipedia.org/wiki/HSV-Farbraum ist u.a. der Zusammenhang zwischen dem RGB- und dem HSV-Farbraum gezeigt: http://de.wikipedia.org/w/index.php?title=Datei:HSV-RGB-comparison.svg Was für mich dort noch nicht ersichtlich ist bzw. wobei ich die Grafik unverständlich finde ist der Zusammenhang zwischen Value- und Saturation-Wert. Hue wählt die Farbe an sich, bzw. die anteilige Zusammensetzung aus RGB. Saturation ist die Intensität der durch Hue gewählten Farbe(n). Value ist die Intensität gleichmäßig über alle drei Farben. Ist das so richtig? Bringt mir ja nix, wenn ich's noch nicht exakt verstanden habe, vorher brauch ich gar nicht weitermachen :) Wenn das soweit richtig wäre, dann bringt ein Tabellenansatz wahrscheinlich nix, denn das wären ja riesige Tabellen, da muss dann doch noch gerechnet werden, aber das wär erst mal nebensächlich. Hauptsache ich verstehe das System an sich. Über das verlustfreie Umrechnen kann man sich immer noch Gedanken machen. Ralf
Ralf schrieb: > Was für mich dort noch nicht ersichtlich ist bzw. wobei ich die Grafik > unverständlich finde ist der Zusammenhang zwischen Value- und > Saturation-Wert. > > Hue wählt die Farbe an sich, Also einen Wert am oberen Umfang des Kegels > Saturation ist die Intensität der durch Hue gewählten Farbe(n). die Farbsättigung. Was man im Bild nicht (oder nur schlecht) sieht: In der Mitte, in der Drehachse des Kegels liegen die 'unbunten' Farben. Also die Grauwerte, von weiß bis schwarz. Weiß ist oben und schwarz ist an der Spitze. Mit Saturation bestimmst du im Grunde, wie weit dein Farbpunkt von dieser Drehachse entfernt ist. Je näher in der Mitte, desto unbunter ist deine Farbe und desto mehr hast du keine Farbe mehr, sondern einfach nur einen Grauwert. > Value ist die Intensität gleichmäßig über alle drei Farben. die Helligkeit der Farbe Value ist die Höhe in der dein Punkt auf dem Kegel ist. Je weiter oben, desto mehr bist du auf deiner echten Farbe (bzw. weiß). Je weiter unten, desto näher bist du an Schwarz Wenn du dich für eine Hue entschieden hast (also die Farbe), dann kann man da einen Schnitt durch den Kegel machen und diese Schnittfläche ist ein Dreick. zb bei der Hue für Rot Rot <--0 Saturation +------------+ weiß \ | o value \ | | \ | | \ | | \ | | \ | | \ | v \ | \ | \ | \ | \| schwarz Auf dieser Schnittfläche (also alle Punkte innerhalb des Dreiecks) liegen also alle Rot-Werte die es gibt. Von reinem Rot (links oben) bis zu allen Nuancen die man in Richtung weiß bzw. in Richtung schwarz bilden kann. An der senkrechten Kante rechts sind alle Farben dann nur noch Grauschattierungen.
Ralf schrieb: > Wenn das soweit richtig wäre, dann bringt ein Tabellenansatz > wahrscheinlich nix, denn das wären ja riesige Tabellen, da muss dann > doch noch gerechnet werden, aber das wär erst mal nebensächlich. > Hauptsache ich verstehe das System an sich. Über das verlustfreie > Umrechnen kann man sich immer noch Gedanken machen. Was genau willst du machen? Wenn es darum geht einen Farbverlauf durchzudimmen, dann kann man mit dem Bild im Wiki-Artikel bei "Zusammenhang HSV-RGB" die Sache deutlich vereinfacht machen.
Man kann das HSV-System auch hinsichtlich Spektrum und Wellenlänge interpretieren: - Hue, die Farbe beginnt auf dem Kreis bei 0 Grad Rot (entspricht 700 nm) und endet bei 270 Grad Blau (entspricht ungefähr 400 nm). Der restliche Viertelkreis ist ein Zugeständnis an eine Unzulänglichkeit des menschlichen Auges: Magenta. Entsteht als Sinneseindruck durch Überlagerung von Rot und Blau, hat aber keine Wellenlänge, weil es Magenta nicht als monocrhomatisches Licht gibt. - Saturation, die Sättigung, wird manchmal auch als "Reinheit" interetiert. Stell dir vor, du sollst eine Wellenlänge in ein Spektrum von 400-700 nm einzeichenen. Du setzt einen "Nadelimpuls", dann hast du eine Saturation von 1, genau die eine Farbe. Machst du die Nadel breiter und oben rund, kommen andere Wellenlängen hinzu, die Saturation sinkt. Ziehst du eine waagerechte Linie durchs ganze Spektrum, hast du alle Farben, also keine Sättigung mehr. Je nach Höhe der Linie (Value) ists dann Weiss, Grau oder Schwarz ... Verständliche Formeln gibts hier: www.easyrgb.com/index.php?X=MATH
Von HSV nach RGB konvertieren und den RGB-Wert wieder zurück zum gleichen HSV-Wert geht prinzipbedingt nicht eindeutig. Denn für eine bestimmte Graustufe gibt es im RGB-Modell nur eine Darstellungsmöglichkeit (rot = grün = blau = Graustufe), im HSV-Modell dagegen bei 8 Bit 256 verschiedene (Helligkeit = Graustufe, Sättigung 0, Farbton beliebig). Bei der Konvertierung von HSV nach RGB geht bei einer Graustufe also die Farbton-Information verloren. Sag am besten mal, wozu Du das brauchst, es gibt bestimmt eine andere Lösung. Zum Beispiel könntest Du zu einer Farbe immer beide Repräsentationen speichern und bei Änderungen in einem Modell (z.B. im HSV-Modell Farbton + 1) den neuen Wert in das jeweils andere Modell (also hier RGB) konvertieren, so dass beide immer "synchron" bleiben. Vielleicht ist es aber nicht mal nötig, sondern geht noch viel einfacher.
Hi, ne Umwandlung von HSI nach RGB für ne Lichtsteuerung findest du auch hier,Maklerinnen für AVRs in ASM. http://falk-land.com/node/14 bzw. http://rgblightcontrol.sourceforge.net Auf der angegeben Seite (bzw im SVN) findest du auch ne Excel-Tabelle, wo die Konvertierungsfehler dargestellt werden, in dem Fall für ne 8Bit-PWM. Mir stellt sich allerdings die Frage, wozu du präzise Umrechnungen benötigst. Mit LEDs kannste die Graustufen weitgehend knicken und musst aufgrund der nichtlinearen Helligkeitsverteilung von LEDs bzw. der niedrigen Quantisierungstiefe bei PWM (im Sinne von Kompromiss zwischen hinreichend hoher PWM-Frequenz und Bitanzahl) mit Abstrichen leben. Soll heißen: ermittle die farbrelevanten Parameter deines Systems und entscheide, ob das diese Präzision überhaupt benötigt, sonst isses Quatsch. Z.B. Ist die Intensität bei RGB-LEDs nichtlinear - angenommen, eine Intensität von 127 sei maximal, dann ist 63 nicht halb so hell! Für normale Zwecke reichen aber einfache Approximationen locker aus. Und auch nicht vergessen, dass du schon alleine im RGB-Farbraum allerhand machen kannst, vielleicht kannste dir Farbraum-Umrechnungen dann schon komplett klemmen.
Hallo, vielen Dank für eure Antworten. @Karl Heinz Buchegger: Danke für die Erläuterung. Das heisst eine Sättigung von 0 führt bei Value = 1 immer zu weiss, unabhängig vom Hue, richtig? So entnehme ich das deinem Kegelschnitt. > Was genau willst du machen? > Wenn es darum geht einen Farbverlauf durchzudimmen, dann kann man mit > dem Bild im Wiki-Artikel bei "Zusammenhang HSV-RGB" die Sache deutlich > vereinfacht machen. Der Controller empfängt RGB-Werte und gibt diese per PWM aus. Die Idee war jetzt eben noch ein "Klecks Luxus", weil man mit HSV m.E. viel schneller zur Wunschfarbe kommt. Der Wunsch nach der "verlustfreien" Umrechnung war einfach die Idee, dass man ja auch mal die Werte vom Controller abfragen möchte, wenn jemandem eine RGB-Farbe gefällt und man die HSV-Werte haben möchte. @Frank: Die Erklärung mit Nadeln ist gut, danke! Der Link ist praktisch, da kann man super von-nach-Konvertierungsroutinen schreiben! Super Sache! @Fabian O.: > Von HSV nach RGB konvertieren und den RGB-Wert wieder zurück zum > gleichen HSV-Wert geht prinzipbedingt nicht eindeutig. Okay, hab ich schon befürchtet :) > Sag am besten mal, wozu Du das brauchst, es gibt bestimmt eine andere > Lösung. Wie oben erwähnt, einfach dem User die Möglichkeit geben, zu einem RGB/HSV-Farbwert das Pendant herauszufinden. > Zum Beispiel könntest Du zu einer Farbe immer beide Repräsentationen > speichern und bei Änderungen in einem Modell (z.B. im > HSV-Modell Farbton + 1) den neuen Wert in das jeweils andere Modell > (also hier RGB) konvertieren, so dass beide immer "synchron" bleiben. Das geht eben nicht, weil man dann die Berechnung schon gemacht hat, bevor der Controller die Daten bekommt - für diesen wiederum ist es ja nicht nötig, dass er beides kennt. > Vielleicht ist es aber nicht mal nötig, sondern geht noch viel > einfacher. Ja, das geht einfacher - ich kann nämlich auch ganz frech sagen, dass es nur entweder-oder gibt. Also dass der Controller die Daten entweder als HSV oder RGB interpretiert, aber das jeweilige Pendant nicht zurückliefern kann. Intern kann ich ja von HSV nach RGB konvertieren (muss ich ja eh). Ich denke, so werd ich das dann auch machen. Wer dann immer noch RGB->HSV braucht kann sich zumindest die groben RGB-Werte über die diversen Webseiten oder selbst mithilfe des von Frank genannten Links umrechnen. Ralf
@Falk: > ne Umwandlung von HSI nach RGB für ne Lichtsteuerung findest du auch > hier,Maklerinnen für AVRs in ASM. Danke, schau ich gleich mal an. > Auf der angegeben Seite (bzw im SVN) findest du auch ne Excel-Tabelle, > wo die Konvertierungsfehler dargestellt werden, in dem Fall für ne > 8Bit-PWM. Das hört sich gut an, da kann ich ein Feeling für die Umrechnungsverluste bekommen. > Mir stellt sich allerdings die Frage, wozu du präzise Umrechnungen > benötigst. Mit LEDs kannste die Graustufen weitgehend knicken und musst > aufgrund der nichtlinearen Helligkeitsverteilung von LEDs bzw. der > niedrigen Quantisierungstiefe bei PWM (im Sinne von Kompromiss zwischen > hinreichend hoher PWM-Frequenz und Bitanzahl) mit Abstrichen leben. Wie gesagt, war einfach deswegen, weil ich ursprünglich eben vorhatte, die jeweiligen Pendants ausgeben zu können. Stimmt, die Abstriche muss man auch noch mit einbeziehen. > Soll heißen: ermittle die farbrelevanten Parameter deines Systems und > entscheide, ob das diese Präzision überhaupt benötigt, sonst isses > Quatsch. Z.B. Ist die Intensität bei RGB-LEDs nichtlinear - angenommen, > eine Intensität von 127 sei maximal, dann ist 63 nicht halb so hell! Für > normale Zwecke reichen aber einfache Approximationen locker aus. Dafür verwende ich einen Ansatz hier aus dem Forum. Den Link kann ich mal raussuchen. Hab's grad nicht parat, wenn ich mich recht erinnere wird im groben die n-te Wurzel aus der PWM-Auflösung gezogen, wobei n die Anzahl der gewünschten Stufen ist. Der resultierende Wert ist ein Faktor. Stufe 0 ist 0, Stufe 1 ist F^1, usw. Damit hab ich ganz gute Erfahrungen gemacht. > Und auch nicht vergessen, dass du schon alleine im RGB-Farbraum > allerhand machen kannst, vielleicht kannste dir Farbraum-Umrechnungen > dann schon komplett klemmen. Mir erschien der HSV-Farbraum eben einfacher, wenn man eine bestimmte Farbe erzeugen möchte. Ralf
Ich verstehe jetzt nicht, wo das Problem liegt, den Controller beide Umrechungen machen zu lassen. Dann kann er von außen Farben in RGB und HSV annehmen und auch jede Farbe als RGB und HSV zurückliefern. Also im Prinzip so:
1 | color_rgb_t led_rgb; |
2 | color_hsv_t led_hsv; |
3 | |
4 | void set_rgb(color_rgb_t rgb) { |
5 | led_rgb = rgb; |
6 | led_hsv = color_rgb_to_hsv(rgb); |
7 | ]
|
8 | |
9 | color_rgb_t get_rgb(void) { |
10 | return rgb; |
11 | }
|
12 | |
13 | void set_hsv(color_hsv_t hsv) { |
14 | led_hsv = hsv; |
15 | led_rgb = color_hsv_to_rgb(hsv); |
16 | ]
|
17 | |
18 | color_hsv_t get_hsv(void) { |
19 | return hsv; |
20 | }
|
Kostet drei Byte pro Farbe, die "unnötig" gespeichert sind. Wenn Dich das stört, dann eben so:
1 | color_rgb_t led_rgb; |
2 | |
3 | void set_rgb(color_rgb_t rgb) { |
4 | led_rgb = rgb; |
5 | ]
|
6 | |
7 | color_rgb_t get_rgb(void) { |
8 | return rgb; |
9 | }
|
10 | |
11 | void set_hsv(color_hsv_t hsv) { |
12 | led_rgb = color_hsv_to_rgb(hsv); |
13 | ]
|
14 | |
15 | color_hsv_t get_hsv(void) { |
16 | return color_rgb_to_hsv(led_rgb); |
17 | }
|
Dann ist aber nicht garantiert, dass man mit get_hsv() genau den mit set_hsv() gesetzten Wert zurückbekommt. Wäre in Deinem konkreten Anwendungsbeispiel aber ja auch nicht mal schlimm.
> Ich verstehe jetzt nicht, wo das Problem liegt, den Controller beide > Umrechungen machen zu lassen. > Dann ist aber nicht garantiert, dass man mit get_hsv() genau den mit > set_hsv() gesetzten Wert zurückbekommt. Wäre in Deinem konkreten > Anwendungsbeispiel aber ja auch nicht mal schlimm. Schlimm nicht, es dürfte optisch kaum einen Unterschied machen. Vielleicht implementier ich's doch noch, mal schauen. Und um Rückfragen der Anwender zu unterbinden, warum die Konvertierungen Abweichungen voneinander haben kann ich ja auf die Umrechnungen verweisen und erläutern, dass es prinzipbedingt Abweichungen gibt. Ralf
Ralf schrieb: > Und um Rückfragen > der Anwender zu unterbinden, warum die Konvertierungen Abweichungen > voneinander haben kann ich ja auf die Umrechnungen verweisen und > erläutern, dass es prinzipbedingt Abweichungen gibt. In der ersten Variante liefert der Controller doch immer genau das zurück, was der Anwender vorgegeben hat.
Ralf schrieb: > voneinander haben kann ich ja auf die Umrechnungen verweisen und > erläutern, dass es prinzipbedingt Abweichungen gibt. Dann würde ich einfach die jeweilige Vorgabe vom Benutzer auf jeden Fall so speichern, wie ich sie kriege. Kriege ich HSV, dann rechen ich RGB aus Will der Benutzer wieder HSV, dann kriegt er die Werte die er mir gegeben hat. Will er RGB, dann kriegt er eben die errechneten Kriege ich RGB, dann rechne ich HSV aus Will der Benuter HSV, dann kriegt er die errechneten Will er aber RGB, dann kriegt er die, die er mir gegeben hat. Auf die Art ist sichergestellt, dass er auf jeden Fall wieder exakt die Werte bekommt, die er mir auch gegeben hat und 'nur' die jeweils anderen eine Approximation sind.
> Dann würde ich einfach die jeweilige Vorgabe vom Benutzer auf jeden Fall > so speichern, wie ich sie kriege. Hmmmm... das könnte klappen, die paar Bits RAM, um den Typ der Daten zu identifizieren könnte ich noch rausknautschen ;) Werd ich mal so in Angriff nehmen. Ralf
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.