Farbgewicht Denkanstoß



  • Hallo,

    ich handtiere gerade mit RGB Werten und dabei komme ich auf ein
    Problem.

    Ich habe eine Liste mit r,g,b Werten nebst Farbnamen.

    Ich erstelle für einen RGB Wert eine Wichtung nach :

    sqrtf((r*r) + (g*g) + (b*b)) < sqrtf((rL*rL) + (gL*gL) + (bL*bL))

    und suche die Farbe in der Liste die am besten passt,

    Funktioniert schon, aber wenn ich die Farbe "Maron" teste RGB(128,0,0)
    gegen ein ähnliches braun RGB(50,27,20)

    erhalte ich logischerweise schwarz RGB(0,0,0) als "Antwort" da ja
    die Testfarbe (düsterrot) RGB(50,0,0) besser zu null passt als zu 128
    (stimmt aber in dem Fall gar nicht ^^)

    Hat jemand eine Idee wie ich drei Ordinaten für den Farbraum besser wichte ?

    Sollte man das HSL Verfahren anwenden ?

    grübel..

    Danke für Hinweise
    K.



  • Eine HSL Wichting bringt nun nicht gerade bessere Ergebnisse:

    void RGBtoHSL(COLORREF rgb, double *H, double *S, double *L)
    {
    	double delta;
    	double r = (double)GetRValue(rgb) / 255;
    	double g = (double)GetGValue(rgb) / 255;
    	double b = (double)GetBValue(rgb) / 255;
    
    	double cmax = max(r, max(g, b));
    	double cmin = min(r, min(g, b));
    	*L = (cmax + cmin) / 2.0;
    
    	if (cmax == cmin)
    	{
    		*S = 0;
    		*H = 0;
    	}
    	else
    	{
    		if (*L < 0.5)
    			*S = (cmax - cmin) / (cmax + cmin);
    		else
    			*S = (cmax - cmin) / (2.0 - cmax - cmin);
    
    		delta = cmax - cmin;
    		if (r == cmax)
    			*H = (g - b) / delta;
    		else if (g == cmax)
    			*H = 2.0 + (b - r) / delta;
    		else
    			*H = 4.0 + (r - g) / delta;
    		*H /= 6.0;
    		if (*H < 0.0)
    			*H += 1;
    	}
    }
    


  • Was willst du denn machen? Die "ähnlichste" Farbe aus deiner Liste finden oder was?
    Dann wäre natürlich gleich die nächste Frage: was ist eine ähnliche Farbe? Ist Helligkeit wichtiger, oder der Farbton? Usw.

    Eine Möglichkeit dazu wäre auf jeden Fall den Fehler folgendermassen zu berechnen:
    Fehler = abs(X1-X2) * A + abs(Y1-Y2) * B + abs(Z1-Z2) * C

    X1, Y1, Z1 wären dabei die Farbkoordinaten der ersten Farbe im Farbraum deiner Wahl und X2, Y2, Z2 die Farbkoordinaten der zweiten Farbe im selben Farbraum.
    A, B und C sind einfach Gewichtungsfaktoren mit denen du die Wichtigkeit der einzelnen Komponenten bestimmen kannst.

    Welcher Farbraum sich dafür dann am besten eigenet wäre die nächste Frage. RGB eignet sich vermutlich nicht gut. Möglich wären z.B. YUV, HSV, HSL oder L*a*b*.

    So berechnest du für jeden Kandidaten aus deiner Liste einen Fehlerwert zur aktuellen Farbe, und wählst dann einfach den Eintrag mit dem kleinsten Fehler aus.

    ps: Die Frage hat nix mit MFC oder MSVC zu tun, die gehört eher nach "Rund um die Programmierung".



  • Danke für deinen Hinweis,

    es stellt sich heraus das die Anzahl der Suchklassen sowie die Abstandsberechnung über double die besten Ergebnisse liefert.

    Die Suchklassen sind alle möglichen Namen ca. 142 die man sinnvoll
    aufzählen kann.

    Das Dotprodukt liefert dann hinreichende Ergebnisse, die sehr knapp
    ausfallen können.

    typedef struct ColorName
    {
    	char enname[80];
    	char dename[80];
    	COLORREF  rgb;
    	int     b, g, r;
    }COLORNAME;
    
    typedef class ColorText
    {
    public:
    	ColorText(){};
    	~ColorText(){};
    public:
    	static int   GetIndex(COLORREF rgb);
    	static char *GetText(int Id, bool DeEn);
    	static COLORREF GetRGB(int Id);
    }COLTXT;
    
    COLORNAME coldata[] = {
    	{ { "aliceblue" }, { "eisfarben" }, 0x00f0f8ff, 240, 248, 255 },
    	{ { "antiquewhite" }, { "Antikweiß" }, 0x00faebd7, 250, 235, 215 },
    	{ { "aqua" }, { "Wasser" }, 0x0000ffff, 0, 255, 255 },
    	{ { "aquamarine" }, { "Aquamarinblau" }, 0x007fffd4, 127, 255, 212 },
    	{ { "azure" }, { "Himmelblau" }, 0x00f0ffff, 240, 255, 255 },
    	{ { "beige" }, { "Beige" }, 0x00f5f5dc, 245, 245, 220 },
    	{ { "bisque" }, { "Biskuit" }, 0x00ffe4c4, 255, 228, 196 },
    	{ { "black" }, { "Schwarz" }, 0x00000000, 0, 0, 0 },
    	{ { "blanchedalmond" }, { "Mandelweiß" }, 0x00ffebcd, 255, 235, 205 },
    	{ { "blue" }, { "Blau" }, 0x000000ff, 0, 0, 255 },
    	{ { "blueviolet" }, { "Blauviolett" }, 0x008a2be2, 138, 43, 226 },
    	{ { "brown" }, { "Braun" }, 0x00a52a2a, 165, 42, 42 },
    	{ { "burlywood" }, { "Gelbbraun" }, 0x00deb887, 222, 184, 135 },
    	{ { "cadetblue" }, { "Kadettenblau" }, 0x005f9ea0, 95, 158, 160 },
    	{ { "chartreuse" }, { "Hellgrün" }, 0x007fff00, 127, 255, 0 },
    	{ { "chocolate" }, { "Schokolade" }, 0x00d2691e, 210, 105, 30 },
    	{ { "coral" }, { "Koralle" }, 0x00ff7f50, 255, 127, 80 },
    	{ { "cornflowerblue" }, { "Kornblumenblau" }, 0x006495ed, 100, 149, 237 },
    	{ { "cornsilk" }, { "Mais" }, 0x00fff8dc, 255, 248, 220 },
    	{ { "crimson" }, { "Karmesinrot" }, 0x00dc143c, 220, 20, 60 },
    	{ { "cyan" }, { "Türkis" }, 0x0000ffff, 0, 255, 255 },
    	{ { "darkblue" }, { "Dunkelblau" }, 0x0000008b, 0, 0, 139 },
    	{ { "darkcyan" }, { "Dunkeltürkis" }, 0x00008b8b, 0, 139, 139 },
    	{ { "darkgoldenrod" }, { "dunkle Goldrutenfarbe" }, 0x00b8860b, 184, 134, 11 },
    	{ { "darkgreen" }, { "Dunkelgrün" }, 0x00006400, 0, 100, 0 },
    	{ { "darkgrey" }, { "Dunkelgrau" }, 0x00a9a9a9, 169, 169, 169 },
    	{ { "darkkhaki" }, { "Dunkelkhaki" }, 0x00bdb76b, 189, 183, 107 },
    	{ { "darkmagenta -Dunkelmagenta" }, 0x008b008b, 139, 0, 139 },
    	{ { "darkolivegreen" }, { "dunkles Olivgrün" }, 0x00556b2f, 85, 107, 47 },
    	{ { "darkorange" }, { "dunkles Orange" }, 0x00ff8c00, 255, 140, 0 },
    	{ { "darkorchid" }, { "dubkle Orchidee" }, 0x009932cc, 153, 50, 204 },
    	{ { "darkred" }, { "Dunkelrot" }, 0x008b0000, 139, 0, 0 },
    	{ { "darksalmon" }, { "dunkle Lachsfarbe" }, 0x00e9967a, 233, 150, 122 },
    	{ { "darkseagreen" }, { "dunkles Seegrün" }, 0x008fbc8f, 143, 188, 143 },
    	{ { "darkslateblue" }, { "dunkles Schieferblau" }, 0x00483d8b, 72, 61, 139 },
    	{ { "darkslategrey" }, { "dunkles Schiefergrau" }, 0x002f4f4f, 47, 79, 79 },
    	{ { "darkturquoise" }, { "Dunkeltürkis" }, 0x0000ced1, 0, 206, 209 },
    	{ { "darkviolet" }, { "Dunkelvilolett" }, 0x009400d3, 148, 0, 211 },
    	{ { "deeppink" }, { "Tiefrosa" }, 0x00ff1493, 255, 20, 147 },
    	{ { "deepskyblue" }, { "tiefes Himmelblau" }, 0x0000bfff, 0, 191, 255 },
    	{ { "dimgrey" }, { "Dunkelgrau" }, 0x00696969, 105, 105, 105 },
    	{ { "dodgerblue -Persenningblau" }, 0x001e90ff, 30, 144, 255 },
    	{ { "firebrick" }, { "Backstein" }, 0x00b22222, 178, 34, 34 },
    	{ { "floralwhite" }, { "Blütenweiß" }, 0x00fffaf0, 255, 250, 240 },
    	{ { "forestgreen" }, { "Waldgrün" }, 0x00228b22, 34, 139, 34 },
    	{ { "fuchsia" }, { "Fuchsie" }, 0x00ff00ff, 255, 0, 255 },
    	{ { "gainsboro" }, { "Gainsboro" }, 0x00dcdcdc, 220, 220, 220 },
    	{ { "ghostwhite" }, { "Geisterweiß" }, 0x00f8f8ff, 248, 248, 255 },
    	{ { "gold" }, { "Gold" }, 0x00ffd700, 255, 215, 0 },
    	{ { "goldenrod" }, { "Goldrute" }, 0x00daa520, 218, 165, 32 },
    	{ { "gray " }, { "Grau" }, 0x00808080, 128, 128, 128 },
    	{ { "green" }, { "Grün" }, 0x00008000, 0, 128, 0 },
    	{ { "greenyellow" }, { "Grüngelb" }, 0x00adff2f, 173, 255, 47 },
    	{ { "grey" }, { "Grau" }, 0x00808080, 128, 128, 128 },
    	{ { "honeydew" }, { "Honigmelone" }, 0x00f0fff0, 240, 255, 240 },
    	{ { "hotpink" }, { "leuchtendes Rosa" }, 0x00ff69b4, 255, 105, 180 },
    	{ { "indianred" }, { "Indischrot" }, 0x00cd5c5c, 205, 92, 92 },
    	{ { "indigo" }, { "Indigo" }, 0x004b0082, 75, 0, 130 },
    	{ { "ivory" }, { "Elfenbein" }, 0x00fffff0, 255, 255, 240 },
    	{ { "khaki" }, { "staubfarben" }, 0x00f0e68c, 240, 230, 140 },
    	{ { "lavender" }, { "Lavendel" }, 0x00e6e6fa, 230, 230, 250 },
    	{ { "lavenderblush" }, { "- Lavendelrosa" }, 0x00fff0f5, 255, 240, 245 },
    	{ { "lawngreen" }, { "Rasengrün" }, 0x007cfc00, 124, 252, 0 },
    	{ { "lemonchiffon" }, { "Chiffongelb" }, 0x00fffacd, 255, 250, 205 },
    	{ { "lightblue" }, { "Hellblau" }, 0x00add8e6, 173, 216, 230 },
    	{ { "lightcoral" }, { "helles Korallenrot" }, 0x00f08080, 240, 128, 128 },
    	{ { "lightcyan" }, { "helles Cyan" }, 0x00e0ffff, 224, 255, 255 },
    	{ { "lightgoldenrodyellow" }, { "helles Goldrutengelb" }, 0x00fafad2, 250, 250, 210 },
    	{ { "lightgray" }, { "Hellgrau" }, 0x00d3d3d3, 211, 211, 211 },
    	{ { "lightgreen" }, { "Hellgrün" }, 0x0090ee90, 144, 238, 144 },
    	{ { "lightgrey -Hellgrau" }, 0x00d3d3d3, 211, 211, 211 },
    	{ { "lightpink" }, { "Hellrosa" }, 0x00ffb6c1, 255, 182, 193 },
    	{ { "lightsalmon" }, { "helle Lachsfarbe" }, 0x00ffa07a, 255, 160, 122 },
    	{ { "lightseagreen" }, { "helles Seegrün" }, 0x0020b2aa, 32, 178, 170 },
    	{ { "lightskyblue" }, { "helles Himmelblau" }, 0x0087cefa, 135, 206, 250 },
    	{ { "lightslategrey" }, { "helles Schiefergrau" }, 0x00778899, 119, 136, 153 },
    	{ { "lightsteelblue" }, { "helles Stahlblau" }, 0x00b0c4de, 176, 196, 222 },
    	{ { "lightyellow" }, { "Hellgelb" }, 0x00ffffe0, 255, 255, 224 },
    	{ { "lime" }, { "Limone" }, 0x0000ff00, 0, 255, 0 },
    	{ { "limegreen" }, { "Limonengrün" }, 0x0032cd32, 50, 205, 50 },
    	{ { "linen" }, { "Leinen" }, 0x00faf0e6, 250, 240, 230 },
    	{ { "magenta" }, { "Magenta" }, 0x00ff00ff, 255, 0, 255 },
    	{ { "black" }, { "Schwarz" }, 0x00000000, 0, 0, 0 },
    	{ { "maroon" }, { "Kastanie" }, 0x00800000, 128, 0, 0 },
    	{ { "dark maroon" }, { "dunkel Kastanie" }, 0x001e0a0a, 30, 10, 10 },
    	{ { "mediumaquamarine" }, { "mittleres Aquamarin" }, 0x0066cdaa, 102, 205, 170 },
    	{ { "mediumblue" }, { "mittleres Blau" }, 0x000000cd, 0, 0, 205 },
    	{ { "mediumorchid" }, { "mittlere Orchedee" }, 0x00ba55d3, 186, 85, 211 },
    	{ { "mediumpurple" }, { "mittleres Violett" }, 0x009370db, 147, 112, 219 },
    	{ { "mediumseagreen" }, { "mittleres Seegrün" }, 0x003cb371, 60, 179, 113 },
    	{ { "mediumslateblue" }, { "mittleres Schieferblau" }, 0x007b68ee, 123, 104, 238 },
    	{ { "mediumspringgreen" }, { "mittleres Frühlingsgrün" }, 0x0000fa9a, 0, 250, 154 },
    	{ { "mediumturquoise" }, { "mittlere Türkis" }, 0x0048d1cc, 72, 209, 204 },
    	{ { "mediumvioletred" }, { "mittleres Violettrot" }, 0x00c71585, 199, 21, 133 },
    	{ { "midnightblue" }, { "Mitternachtsblau" }, 0x00191970, 25, 25, 112 },
    	{ { "mintcream" }, { "cremige Minze" }, 0x00f5fffa, 245, 255, 250 },
    	{ { "mistyrose" }, { "Altrosa" }, 0x00ffe4e1, 255, 228, 225 },
    	{ { "moccasin" }, { "Mokassin" }, 0x00ffe4b5, 255, 228, 181 },
    	{ { "navajowhite" }, { "Navajoweiß" }, 0x00ffdead, 255, 222, 173 },
    	{ { "navy" }, { "Marinenblau" }, 0x00000080, 0, 0, 128 },
    	{ { "oldlace" }, { "alte Spitze" }, 0x00fdf5e6, 253, 245, 230 },
    	{ { "olive" }, { "Olivgrün" }, 0x00808000, 128, 128, 0 },
    	{ { "olivedrab " }, { "Olivgraubraun" }, 0x006b8e23, 107, 142, 35 },
    	{ { "orange" }, { "Orange" }, 0x00ffa500, 255, 165, 0 },
    	{ { "orangered" }, { "Orangerot" }, 0x00ff4500, 255, 69, 0 },
    	{ { "orchid" }, { "Orchidee" }, 0x00da70d6, 218, 112, 214 },
    	{ { "palegoldenrod" }, { "blasse Goldrutenfarbe" }, 0x00eee8aa, 238, 232, 170 },
    	{ { "palegreen" }, { "Blassgrün" }, 0x0098fb98, 152, 251, 152 },
    	{ { "paleturquoise" }, { "Blasstürkis" }, 0x00afeeee, 175, 238, 238 },
    	{ { "palevioletred" }, { "blasses Violettrot" }, 0x00db7093, 219, 112, 147 },
    	{ { "papayawhip" }, { "Papayacreme" }, 0x00ffefd5, 255, 239, 213 },
    	{ { "peachpuff" }, { "Pfirsich" }, 0x00ffdab9, 255, 218, 185 },
    	{ { "peru -Peru" }, 0x00cd853f, 205, 133, 63 },
    	{ { "pink" }, { "Rosa" }, 0x00ffc0cb, 255, 192, 203 },
    	{ { "plum" }, { "Pflaume" }, 0x00dda0dd, 221, 160, 221 },
    	{ { "powderblue" }, { "Taubenblau" }, 0x00b0e0e6, 176, 224, 230 },
    	{ { "purple" }, { "Violett" }, 0x00800080, 128, 0, 128 },
    	{ { "red" }, { "Rot" }, 0x00ff0000, 255, 0, 0 },
    	{ { "rosybrown" }, { "rosiges Braun" }, 0x00bc8f8f, 188, 143, 143 },
    	{ { "royalblue" }, { "Königsbalu" }, 0x004169e1, 65, 105, 225 },
    	{ { "saddlebrown" }, { "Sattelbraun" }, 0x008b4513, 139, 69, 19 },
    	{ { "salmon" }, { "lachsfarben" }, 0x00fa8072, 250, 128, 114 },
    	{ { "sandybrown" }, { "Sandbraun" }, 0x00f4a460, 244, 164, 96 },
    	{ { "seagreen" }, { "Seegrün" }, 0x002e8b57, 46, 139, 87 },
    	{ { "seashell" }, { "Muschel" }, 0x00fff5ee, 255, 245, 238 },
    	{ { "sienna" }, { "Siennaerde" }, 0x00a0522d, 160, 82, 45 },
    	{ { "silver" }, { "SIlber" }, 0x00c0c0c0, 192, 192, 192 },
    	{ { "skyblue" }, { "Himmelblau" }, 0x0087ceeb, 135, 206, 235 },
    	{ { "slateblue" }, { "Schieferblau" }, 0x006a5acd, 106, 90, 205 },
    	{ { "slategrey" }, { "Schiefergrau" }, 0x00708090, 112, 128, 144 },
    	{ { "snow" }, { "Schneeweiß" }, 0x00fffafa, 255, 250, 250 },
    	{ { "springgreen" }, { "Frühlingsgrün" }, 0x0000ff7f, 0, 255, 127 },
    	{ { "steelblue" }, { "Stahlblau" }, 0x004682b4, 70, 130, 180 },
    	{ { "tan" }, { "hautfarben" }, 0x00d2b48c, 210, 180, 140 },
    	{ { "teal" }, { "Krickentengrün" }, 0x00008080, 0, 128, 128 },
    	{ { "thistle" }, { "Distel" }, 0x00d8bfd8, 216, 191, 216 },
    	{ { "tomato" }, { "Tomate" }, 0x00ff6347, 255, 99, 71 },
    	{ { "turquoise" }, { "Türkis" }, 0x0040e0d0, 64, 224, 208 },
    	{ { "violet" }, { "Veilchen" }, 0x00ee82ee, 238, 130, 238 },
    	{ { "wheat" }, { "Weizen" }, 0x00f5deb3, 245, 222, 179 },
    	{ { "white" }, { "Weiß" }, 0x00ffffff, 255, 255, 255 },
    	{ { "whitesmoke" }, { "rauchfarben" }, 0x00f5f5f5, 245, 245, 245 },
    	{ { "yellow" }, { "Gelb" }, 0x00ffff00, 255, 255, 0 },
    	{ { "yellowgreen" }, { "Gelbgrün" }, 0x009acd32, 154, 205, 50 },
    	{ { "unknow" }, { "unbekannt" }, 0x00, 0, 0, 0 }
    };
    
    int ColorText::GetIndex(COLORREF rgb)
    {
    	int b(GetBValue(rgb)), g(GetGValue(rgb)), r(GetRValue(rgb));
    
    	short bestidx  = 0;
    	double bestlen = 255;
    
    	for (register short n = 0; n < sizeof(coldata) / sizeof(coldata[0]); n++)
    	{
    		int rr(max(coldata[n].r,10)), gg(max(coldata[n].g,10)), bb(max(coldata[n].b,10));
    		double len = sqrt((double)
    
    			(r - rr) * (r - rr) +
    			(g - gg) * (g - gg) +
    			(b - bb) * (b - bb)
    
    			);
    
    		if (len < bestlen)
    		{
    			bestlen = len;
    			bestidx = n;
    		}
    	}
    
    	return bestidx;
    }
    
    char *ColorText::GetText(int Id, bool DeEn)
    {
    	if (Id > -1 && Id < (sizeof(coldata) / sizeof(coldata[0])))
    	 return !DeEn ? &coldata[Id].enname[0] : &coldata[Id].dename[0];
    
    	return 0;
    }
    
    COLORREF ColorText::GetRGB(int Id)
    {
    	if (Id > -1 && Id < (sizeof(coldata) / sizeof(coldata[0])))
    		return coldata[Id].rgb;
    
    	return 0;
    }
    

    Und Ja MFC .



  • Coole Daten

    Verbesserungsvorschlag ?

    (max 10) ist vorbeugend da nur +/- 10 vom Auge erkannt werden, und einige mit
    Null definiert sind , wie Schwarz oder Rot, damit ist die Rechnung günstiger.

    Danke für Hinweise
    Gruß
    K.



  • Verbesserungsvorschlag hab ich eh schon geliefert: andere Farbräume probieren.
    Was du schon machst, nämlich die summe der Fehlerquadrate statt der Summe der Fehler zu vergleichen, ist vermutlich auch eine gute Idee.

    Nochwas: wenn du an dem Algorithmus etwas verbessern willst, wäre es vermutlich gut wenn du dir nen graphischen Output bastelst.
    Du könntest z.B. eine Bitmap generieren in der du alle möglichen Farben mit gleicher Helligkeit aufträgst (z.B. HSL System, L = Fix 0.5, H = X-Achse, S = Y-Achse).
    Dann lässt du dein Programm eine zweite Bitmap generieren in der du jeden Pixel in der Farbe einfärbst die dein Programm aus der Liste aussucht.

    Dann kannst du die beiden Bitmaps in z.B. Paint .NET als Layer übereinanderlegen, und einfach mal gucken. Und dann verschiedene Änderungen ausprobieren (z.B. anderer Farbraum, Rumschrauben an diversen Parametern), und gucken ob es besser oder schlechter wird.
    Ohne so ein Feedback bzw. so einen Vergleichsmechanismus kannst du ja praktisch nur rumraten.

    Wobei ich natürlich nicht weiss ob sich das wirklich auszahlt - ich weiss ja nicht wie wichtig diese Funktions ist. Wenns reicht dass einfach nur überhaupt irgendwas halbwegs brauchbares rauskommt, also dass er nicht Knallgelb aus der Liste auswählt wenn man mit Himmelblau reinfährt, dann wird es vermutlich übertrieben sein.

    ps: Nochwas

    Achromat schrieb:

    Und Ja MFC .

    Äh. Nein, nix MFC! Wo hat die Fragestellung bitte mit MFC zu tun? Die Frage ist nichtmal wirklich C++-spezifisch.



  • Hi,

    danke für deine Hinweise, man sucht ja doch auch Austausch mit anderen,
    um Holzwege zu steinigen.

    Och jo.. testen kann ich das wunderbar, dies ist nur ein Fragment.

    Normal verwende ich 3D-Farbräume, sog. JetColorFarbraum dies funktioniert natürlich auch in 2D.

    Hier ab 1:30 zu sehen : http://youtu.be/w8yvP00JiJI

    Grüße und Erfolg
    K.

    (ps.MFC alles für CDC)



  • Hallo,

    ich hätte folgenden Vorschlag anzubieten.
    Wenn man die Farben auf einem Kreis anordnet und den Nullpunkt bei
    Rot(255, 0, 0) setzt kann man jedem Farbton einen Winkel zuordnen.
    Durch Vergleich der Winkel lassen sich Ähnlichkeiten bestimmen, die
    recht gut mit der Wahrnehmung des Auges einhergehen:

    float Farbwinkel_ermitteln(float fR, float fG, float fB)
    {
    float f_Winkel = -1;
    double pi = 3.1415926535;
    double da, db, dw;

    if(fR > fB && fG >= fB)//Farbe liegt im Bereich zwischen Rot und Grün
    {
    da = fR - fB; db = fG - fB;
    dw = atan(db / da);
    f_Winkel = (dw / pi * 180) * 120/90;
    }

    if(fG > fR && fB >= fR)//Farbe liegt im Bereich zwischen Grün und Blau
    {
    da = fG - fR; db = fB - fR;
    dw = atan(db / da);
    f_Winkel = (dw / pi * 180) * 120/90;
    f_Winkel += 120;
    }
    if(fB > fG && fR >= fG)//Farbe liegt im Bereich zwischen Blau und Rot
    {
    da = fB - fG; db = fR - fG;
    dw = atan(db / da);
    f_Winkel = (dw / pi * 180) * 120/90;
    f_Winkel += 240;
    }
    return f_Winkel;
    }

    void Test()
    {
    //Funktioniert schon, aber wenn ich die Farbe "Maron" teste RGB(128,0,0)
    //gegen ein ähnliches braun RGB(50,27,20)
    float f1 = Farbwinkel_ermitteln(128, 0, 0);
    float f2 = Farbwinkel_ermitteln(50, 27, 20);

    float fdif = f1 - f2;

    }

    Gruß!
    KS



  • @ks
    http://en.wikipedia.org/wiki/HSL_and_HSV
    😉

    @Achromat

    Achromat schrieb:

    (ps.MFC alles für CDC)

    Du verstehst echt nicht worauf ich hinaus will.
    Das Thema deiner Frage hat nix mit MFC zu tun.
    Ob du in deinem Programm MFC verwendest oder nicht ist dabei doch vollkommen egal.



  • Hallo KS,

    das ist die Farbscheibe, das hast Du jetzt sehr gut dargestellt, ich habe
    das mal integriert und liefere diesen Winkel als Zusatzergebnis
    (Letzter Wert der blauen Liste) in dem Video zurück.

    Da kannst Du sehen wie fein das auflöst, so kann man z.B. eine ohmschen Wiederstands -Erkennung aus einer frei definierten Winkelgültigkeitstabelle entschlüsseln.

    Kannst Du den Rückweg Winkel zu RGB auch darstellen ?

    sehr gut Danke das habe ich mal so integriert.

    http://www.youtube.com/watch?v=Eq-eRoxV7ho&feature=youtu.be

    Gruß
    K.



  • Hallo,

    Du müsstest den Spezialfall, daß die RGB Werte gleich sind (Schwarz, Grautöne, Weiß) noch abfangen, da meine Funktion dann -1 zurück gibt.
    Eine Alternative wäre es den Betrag des Differenzvektors zur Ähnlichkeitsprüfung zu nutzen:

    float Farbwinkel_ermitteln(float fR, float fG, float fB)
    {
    float f_Winkel = -1;
    double pi = 3.1415926535;
    double da, db, dw;

    if(fR > fB && fG >= fB)//Farbe liegt im Bereich zwischen Rot und Grün
    {
    da = fR - fB; db = fG - fB;
    dw = atan(db / da);
    f_Winkel = (dw / pi * 180) * 120/90;
    }

    if(fG > fR && fB >= fR)//Farbe liegt im Bereich zwischen Grün und Blau
    {
    da = fG - fR; db = fB - fR;
    dw = atan(db / da);
    f_Winkel = (dw / pi * 180) * 120/90;
    f_Winkel += 120;
    }
    if(fB > fG && fR >= fG)//Farbe liegt im Bereich zwischen Blau und Rot
    {
    da = fB - fG; db = fR - fG;
    dw = atan(db / da);
    f_Winkel = (dw / pi * 180) * 120/90;
    f_Winkel += 240;
    }
    return f_Winkel;
    }

    float Betrag_Differenz_Vector(float fR0, float fG0, float fB0, float fR1, float fG1, float fB1)
    {
    float fdifR = fR0 - fR1;
    float fdifG = fG0 - fG1;
    float fdifB = fB0 - fB1;

    fdifR = fdifR * fdifR;
    fdifG = fdifG * fdifG;
    fdifB = fdifB * fdifB;

    float fbetr = fdifR + fdifG + fdifB;
    fbetr = sqrt(fbetr);
    return fbetr;
    }

    void Test()

    {
    //Funktioniert schon, aber wenn ich die Farbe "Maron" teste RGB(128,0,0)
    //gegen ein ähnliches braun RGB(50,27,20)

    float f1 = Farbwinkel_ermitteln(128, 0, 0);
    float f2 = Farbwinkel_ermitteln(50, 27, 20);
    float f3 = Farbwinkel_ermitteln(110, 110, 110);// -1!

    float fdif0 = f1 - f2;
    float fdif1 = f1 - f3;

    float fb0 = Betrag_Differenz_Vector(128, 0, 0, 50, 27, 20);
    float fb1 = Betrag_Differenz_Vector(128, 0, 0, 0, 0, 0);

    return;



  • Hi KS

    Ok das ist der Abstand zu einer anderen Angabe, interessant wäre
    über die Winkelangabe nun wieder einen RGB Wert zu erhalten.

    Die Klassifizierungsversion löst etwas besser auf, aber die Fehler
    sind größer bezüglich das ein rosa hauch gern als grau indiziert wird.

    Man kann wohl nur durch die Anzahl der Klassen eine möglichst hohe Treffer
    Zuverlässigkeit erlangen. Das ganze scheint sehr tiefgründig zu sein, da hier
    der Menschliche Augenschein der Farberkennung durchwirkt.

    gerade im Nachkomma Bereich kann man mit Fehlern rechnen.

    Jedenfalls sehr guter Hinweis mit der Winkellage über atan.

    Über die Lamina also HSL erreicht man eine Sättigungsempfindlchkeit
    ggf. müssen mehrere Verfahren zusammen wirken.

    Grüße und Erfolg
    K.



  • Hallo,

    man kann aus der Winkelangabe (ein Wert) nicht mehr die RGB Einagbe (drei Werte) zurück rechnen.
    Der RGB Wert beinhaltet auf dem Farbkreis auch den Abstand zum Mittelpunkt, diese Angabe geht
    verloren.
    Ich bei einer ähnlichen Aufgabenstellung (Bildähnlichkeiten) eine Kombination der gezeigten Funktionen verwendet.

    Gruß!
    KS



  • Hallo zusammen,

    es gab schon mal ein ähnliches Thema dazu: Ähnlichste Farbe aus vielen finden

    Siassei schrieb:

    Und noch mals, vergiss RGB und HSV. Für einen Vergleich mit aktzeptablen Ergebnisse musst du zu Lab, LCh oder einen vergleichbaren Farbsystem gehen.

    Für Umrechnungen von RGB nach (CIE)Lab habe ich z.B. Farbkonvertierung RGB <-> HSV und RGB <-> CIE-Lab gefunden (ist zwar C# Code, kann aber einfach nach C++ portiert werden, da es ja nur Formeln sind ;-).



  • @Th69
    Ich hab ihm schon alles mögliche geschrieben, unter anderem auch dass er mal andere Farbräume versuchen soll (in der Liste der Kandidaten war auch L*a*b*).
    Der Herr scheint aber zu faul dafür zu sein auch nur irgendwas zu probieren, wenn man es ihm nicht wie "ks" vorkaut.
    Was ich sicher nicht machen werde, bin ja nicht total bescheuert.


Anmelden zum Antworten