Programm von [Java] in [C++]

M--G

Lieutenant
Registriert
Dez. 2006
Beiträge
762
Guten Abend,

mein Programm läuft inzwischen nahezu fehlerfrei, nur die Umrechnung von HSV in das RGB-Spektrum klappt nicht ganz :(

Habe das ganze aus wikipedia umgesetzt:
http://de.wikipedia.org/wiki/HSV-Farbraum

Hier mein Code:
Code:
							//dominate Farbe V, abgewandte Farbe p (bei 360°)
							if (hi <= 1) {
								Rdurchschnitt = Vdurchschnitt;
								Gdurchschnitt = ti;
								Bdurchschnitt = pi;}
							else if (hi <= 2) {
								Rdurchschnitt = qi;
								Gdurchschnitt = Vdurchschnitt;
								Bdurchschnitt = pi;}
							else if (hi <= 3) {
								Rdurchschnitt = pi;
								Gdurchschnitt = Vdurchschnitt;
								Bdurchschnitt = ti;}
							else if (hi <= 4) {
								Rdurchschnitt = pi;
								Gdurchschnitt = qi;
								Bdurchschnitt = Vdurchschnitt;}
							else if (hi <= 5) {
								Rdurchschnitt = ti;
								Gdurchschnitt = pi;
								Bdurchschnitt = Vdurchschnitt;}
							else //(hi <= 6) 
								{Rdurchschnitt = Vdurchschnitt;
								Gdurchschnitt = pi;
								Bdurchschnitt = qi;}

							Rdurchschnitt = (Rdurchschnitt*255);
							Gdurchschnitt = (Gdurchschnitt*255);
							Bdurchschnitt = (Bdurchschnitt*255);

Irgendwas kann da aber nicht stimmen, da ich das Bild 1:1 umgesetzt habe
d7b2f4f5b3d0c3781ca6713512d9b1bc.png

Allerdings macht das keinen Sinn für mich, da dann ja f immer null wäre?!?!

Vielleicht kann mir ja einer von euch helfen?`
Da ich aus dem Englischen-Kram nicht schlau werde:
http://en.wikipedia.org/wiki/HSL_and_HSV

Und mit der Java-Programmierung auch nichts anfangen kann:
http://snipplr.com/view/14590/hsv-to-rgb/

Vielen Dank schonmal :)
M--G
 
Zuletzt bearbeitet:
Und was heißt das? ^^
 
M--G schrieb:
Und was heißt das? ^^

Dafür war der Link da. Floor liefert bei positiven Zahlen banal ausgedrückt die Stellen vor dem Komma, und dafür stehen die L förmigen Klammern bei der Berechnung von hi.
Wie sieht denn dein Code zur Berechnung von hi bisher aus?
 
Stimmt, den oberen Teil hatte ich gar nicht reinkopiert.
Schonmal danke! :)

Code:
//HSV in RGB:
							double hi = 0; double fi = 0;
							double pi = 0; double qi = 0; double ti = 0;
							
							hi = Hdurchschnitt/60;
							fi = (Hdurchschnitt/60)-hi;

							pi = Vdurchschnitt*(1-Sdurchschnitt);
							qi = Vdurchschnitt*(1-(Sdurchschnitt*fi));
							ti = Vdurchschnitt*(1-(Sdurchschnitt*(1-fi)));

							//dominate Farbe V, abgewandte Farbe p (bei 360°)
							if (hi <= 1) {
								Rdurchschnitt = Vdurchschnitt;
								Gdurchschnitt = ti;
								Bdurchschnitt = pi;}
							else if (hi <= 2) {
								Rdurchschnitt = qi;
								Gdurchschnitt = Vdurchschnitt;
								Bdurchschnitt = pi;}
							else if (hi <= 3) {
								Rdurchschnitt = pi;
								Gdurchschnitt = Vdurchschnitt;
								Bdurchschnitt = ti;}
							else if (hi <= 4) {
								Rdurchschnitt = pi;
								Gdurchschnitt = qi;
								Bdurchschnitt = Vdurchschnitt;}
							else if (hi <= 5) {
								Rdurchschnitt = ti;
								Gdurchschnitt = pi;
								Bdurchschnitt = Vdurchschnitt;}
							else //(hi <= 6) 
								{Rdurchschnitt = Vdurchschnitt;
								Gdurchschnitt = pi;
								Bdurchschnitt = qi;}

							Rdurchschnitt = (Rdurchschnitt*255);
							Gdurchschnitt = (Gdurchschnitt*255);
							Bdurchschnitt = (Bdurchschnitt*255);
 
Dann probier es mal mit:
Code:
#include <math.h>

hi = floor(Hdurchschnitt/60);
 
Danke :)
Kompiliert erfolgreich, die Werte sind aber immernoch der gleiche Müll...
Irgendwo stimmt immernoch was nicht ;)

Morgen in aller Ruhe nochmal durchgehen.
Gute Nacht
 
M--G schrieb:
Und mit der Java-Programmierung auch nichts anfangen kann:
http://snipplr.com/view/14590/hsv-to-rgb/

Man sollte vielleicht auch mal alles lesen, was dort steht
1. Hast du dort auch den HSVtoRGB Algorithmus. Du wolltest aber den RGBtoHSV. Also den komplett falschen Algorithmus. Kein Wunder, dass die Resultate falsch sind.
2. Ist das nicht Java, sondern JavaScript
3. Ist dort ein Link, der zu der Quelle führt:
HSV to RGB color conversion. Ported from the excellent java algorithm by Eugene Vishnevsky at: http://www.cs.rit.edu/~ncs/color/t_convert.html.

4. Hatte der Typ, der den JavaScript Code geschrieben hat, da genauso wenig Ahnung gehabt, da das C-Code ist. Unter Java sind diese Algorithmen schon in der java.awt.Color Klasse implementiert.

5. Deine Aufgabe besteht jetzt nur noch, den Quellcode zu kopieren und ihn für dich anzupassen.
 
Zuletzt bearbeitet:
Whiz-zarD schrieb:
Man sollte vielleicht auch mal alles lesen, was dort steht
1. Hast du dort auch den HSVtoRGB Algorithmus. Du wolltest aber den RGBtoHSV. Also den komplett falschen Algorithmus. Kein Wunder, dass die Resultate falsch sind.
2. Ist das nicht Java, sondern JavaScript
3. Ist dort ein Link, der zu der Quelle führt:


4. Hatte der Typ, der den JavaScript Code geschrieben hat, da genauso wenig Ahnung gehabt, da das C-Code ist. Unter Java sind diese Algorithmen schon in der java.awt.Color Klasse implementiert.

5. Deine Aufgabe besteht jetzt nur noch, den Quellcode zu kopieren und ihn für dich anzupassen.

Ich meinte Schon HSV zu RGB ;)
Habe eine neue Idee, probiere sie gleich mal aus.
EDIT: fehlgeschlagen :(
versuche nun den Snippler Code zu nutzen.
Ergänzung ()

So einen Fehler gefunden.
S und V hätte ich noch durch 100 teilen müssen, da ich es für Gimp... ausgeben lasse.

Zahlen passen nun halbwegs, nur dass die Zuordnung noch falsch zu sein scheint. Rot ist manchmal der Blauwert.... (mehr als 2 Werte stimmen aber nie).
Naja nacher nochmal reinschauen ;)
Ergänzung ()

So den Fehler weiter eingegränzt.
hi scheint bei mir immer 1 zu werden :(

Kann das sein, dass das daran liegt, dass H bei mir ein double und kein Integer ist?

Code:
//HSV in RGB:
							double hi = 0; double fi = 0;
							double pi = 0; double qi = 0; double ti = 0;
							
							hi = floor(Hdurchschnitt/60);
							fi = (Hdurchschnitt/60)- hi;
                            
                            Sdurchschnitt=Sdurchschnitt/100;
                            Vdurchschnitt=Vdurchschnitt/100;
                            
							pi = Vdurchschnitt*(1-Sdurchschnitt);
							qi = Vdurchschnitt*(1-(Sdurchschnitt*fi));
							ti = Vdurchschnitt*(1-(Sdurchschnitt*(1-fi)));

							//dominante Farbe V, abgewandte Farbe p (bei 360°)
							if (hi = 0) {
								Rdurchschnitt = Vdurchschnitt;
								Gdurchschnitt = ti;
								Bdurchschnitt = pi;}
							else if (hi = 1) {
								Rdurchschnitt = qi;
								Gdurchschnitt = Vdurchschnitt;
								Bdurchschnitt = pi;}
							else if (hi = 2) {
								Rdurchschnitt = pi;
								Gdurchschnitt = Vdurchschnitt;
								Bdurchschnitt = ti;}
							else if (hi = 3) {
								Rdurchschnitt = pi;
								Gdurchschnitt = qi;
								Bdurchschnitt = Vdurchschnitt;}
							else if (hi = 4) {
								Rdurchschnitt = ti;
								Gdurchschnitt = pi;
								Bdurchschnitt = Vdurchschnitt;}
							else //(hi = 5) 
								{Rdurchschnitt = Vdurchschnitt;
								Gdurchschnitt = pi;
								Bdurchschnitt = qi;}

							Rdurchschnitt = (Rdurchschnitt*255);
							Gdurchschnitt = (Gdurchschnitt*255);
							Bdurchschnitt = (Bdurchschnitt*255);

							//Daten speichern:

							//Daten ausgeben:
							cout << endl <<"_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _" << endl << endl;
							cout << "resultierende durschnittliche Farbwerte" << endl;
							cout << "   H(res) = " << Hdurchschnitt << "   S(res) = " << Sdurchschnitt << "   V(res) = " << Vdurchschnitt << endl;
							cout << "   R(res) = " << Rdurchschnitt << "   G(res) = " << Gdurchschnitt << "   B(res) = " << Bdurchschnitt << endl; 
							cout << "_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _" << endl << endl; 
							
							cout << "hi=" << hi << endl;
 
Zuletzt bearbeitet:
Du suchst an der richtigen Stelle...
Hdurchschnitt/60 ist eine Integer Division.
 
selbst wenn ich manuell HSV-Werte in mein Programm füttere, wobei H ein integer ist, kommt trotz neuem Code mist raus.
Im grünen Bereich liegen die RGB, Werte jeweils 35 zu hoch.
Wo anders 20 zu hoch.
Und mal sind sie totaler Schwachsinn :(

Egal ob ich es mit break und switch wie hier probiere:
http://ilab.usc.edu/wiki/index.php/HSV_And_H2SV_Color_Space

oder etwas umständlicher mit if in meiner neuen Funktion:

Code:
void HSVinRGB (double Hbuffer[buff], double Vbuffer[buff], double Sbuffer[buff], double Rbuffer[buff], double Gbuffer[buff], double Bbuffer[buff])
{Rbuffer[0] = 0;
 Gbuffer[0] = 0; 
 Bbuffer[0] = 0;    
     
    if( Vbuffer[0] == 0 ) //unerwünscht (schwarz weiß)
        { Rbuffer[0] = 0; Gbuffer[0] = 0; Bbuffer[0] = 0;
        } 
    else if( Sbuffer[0] == 0 ) //unerwünscht (schwarz weiß)
         {Rbuffer[0] = Vbuffer[0];
         Gbuffer[0] = Vbuffer[0];
         Bbuffer[0] = Vbuffer[0];
         }
    else
        { const double hf = Hbuffer[0] / 60; 
          const int    i  = (int) floor( hf );
          const double f  = hf - i; 
          const double pv  = Vbuffer[0] * ( 1 - Sbuffer[0] ); 
          const double qv  = Vbuffer[0] * ( 1 - Sbuffer[0] * f );
          const double tv  = Vbuffer[0] * ( 1 - Sbuffer[0] * ( 1 - f ) ); 
          
          //Rot ist dominant:          
          if (Hbuffer[0] >=0 && Hbuffer[0] < 60)
             {Rbuffer[0] = Vbuffer[0];
              Gbuffer[0] = tv;
              Bbuffer[0] = pv;
             }
             
          //Grün ist dominant:    
          else if (Hbuffer[0] >=60 && Hbuffer[0] < 120)    
              {Rbuffer[0] = qv;
              Gbuffer[0] = Vbuffer[0]; 
              Bbuffer[0] = pv;
              }  
          else if (Hbuffer[0] >=120 && Hbuffer[0] < 180)  
              {Rbuffer[0] = pv; 
              Gbuffer[0] = Vbuffer[0];
              Bbuffer[0] = tv;
              }
              
          //Blau ist dominant:
          else if (Hbuffer[0] >=180 && Hbuffer[0] < 240)
              {Rbuffer[0] = pv; 
              Gbuffer[0] = qv;
              Bbuffer[0] = Vbuffer[0]; 
              }
               
         else if (Hbuffer[0] >=240 && Hbuffer[0] < 300)
              {Rbuffer[0] = tv; 
              Gbuffer[0] = pv; 
              Bbuffer[0] = Vbuffer[0];
              }
              
          //Rot ist dominant: 
          else if (Hbuffer[0] >=300 && Hbuffer[0] < 360)      
              {Rbuffer[0] = Vbuffer[0]; 
              Gbuffer[0] = pv; 
              Bbuffer[0] = qv;
              }           
        }
Rbuffer[0] = Rbuffer[0]*255;
Gbuffer[0] = Gbuffer[0]*255; 
Bbuffer[0] = Bbuffer[0]*255;      
}
Ergänzung ()

Habe den Fehler gefunden! :)
Die Funktion funktioniert irgendwie nicht, wenn S und V mit 5 Nachkommastellen genau angegeben wird.
 
Zuletzt bearbeitet:
Ein Problem ist, dass du Fließkommazahlen auf 0 prüfst.
Das kann wegen den Ungenauigkeiten zu Problemen führen.
Die float.h besitzt deshalb die Konstante DBL_EPSILON.
Fließkommawerte sollen immer mit dieser Konstante geprüft werden und nicht mit 0.

Also, um eine Fließkommazahl auf 0 zu prüfen:
Code:
if (z1 < DBL_EPSILON) { ... }

Um zu prüfen, ob zwei Fließkommazahlen gleich sind:
Code:
if (fabs(z1 - z2) < DBL_EPSILON) { ... }

Gerade Double ist da sehr tricky, da nicht alle Nachkommazahlen auf dem Bildschirm angezeigt werden. Reicht da nicht ein Float?
(Ich hab ich da schon meine Verfahrung, dass ein Wert nicht so ganz mitspielte, da der Wert nicht vollständig auf dem Bildschirm gezeigt wurde. Anzeigt wurden da 10 Nachkommastellen aber erst die 20ste Nachkommastelle war entscheidend, warum der Algorithmus nicht so richtig wollte)
 
Zuletzt bearbeitet:
Nun läuft es :)
Danke.

(die ganzen Kleinigkeiten, die einen zum Wahnsinn treiben ^^)
 
Zurück
Oben