Color similarity lazarus / 39-Graphics ---------------------------------------------------------------------- bigeno · 2013-10-18 19:43 Hi, I need assign to my base colors (red,pink,yellow,blue,...) some imported colors (TColor). This colors have various hex, but I need assign to my set of base colors. Is there some  "similarity function" to assign a color? ---------------------------------------------------------------------- engkin · 2013-10-18 22:24 If I understood your question right. You have a variable of type TColor and you want to find the nearest "color" of your fixed "base colors" to this variable. Your "base colors" are stored in an array of TColor as well. My suggestion is to compare your colors based on hue values. That means you need to convert your TColor (red, green , blue values) to hue value (byte or single) . You can do a search for that if you care to code it yourself, or you could use Graphics32 it has a procedure to do that conversion in a unit called GR32.pas Code: [Select]procedure RGBtoHSL(RGB: TColor32; out H, S, L: Byte); var   R, G, B, D, Cmax, Cmin, HL: Integer; begin   R := (RGB shr 16) and $ff;   G := (RGB shr 8) and $ff;   B := RGB and $ff;   Cmax := Max(R, G, B);   Cmin := Min(R, G, B);   L := (Cmax + Cmin) div 2;   if Cmax = Cmin then   begin     H := 0;     S := 0   end   else   begin     D := (Cmax - Cmin) * 255;     if L <= $7F then       S := D div (Cmax + Cmin)     else       S := D div (255 * 2 - Cmax - Cmin);     D := D * 6;     if R = Cmax then       HL := (G - B) * 255 * 255 div D     else if G = Cmax then       HL := 255 * 2 div 6 + (B - R) * 255 * 255 div D     else       HL := 255 * 4 div 6 + (R - G) * 255 * 255 div D;     if HL < 0 then HL := HL + 255 * 2;     H := HL;   end; end; or Code: [Select]procedure RGBtoHSL(RGB: TColor32; out H, S, L : Single); var   R, G, B, D, Cmax, Cmin: Single; begin   R := RedComponent(RGB) / 255;   G := GreenComponent(RGB) / 255;   B := BlueComponent(RGB) / 255;   Cmax := Max(R, Max(G, B));   Cmin := Min(R, Min(G, B));   L := (Cmax + Cmin) / 2;   if Cmax = Cmin then   begin     H := 0;     S := 0   end   else   begin     D := Cmax - Cmin;     if L < 0.5 then S := D / (Cmax + Cmin)     else S := D / (2 - Cmax - Cmin);     if R = Cmax then H := (G - B) / D     else       if G = Cmax then H  := 2 + (B - R) / D       else H := 4 + (R - G) / D;     H := H / 6;     if H < 0 then H := H + 1   end; end; It shouldn't be difficult for you to adjust either procedures above to use TColor instead of TColor32. Your target is H. Then your problem should be more or less finding where does your variable color H value fit among your base colors H values. ---------------------------------------------------------------------- engkin · 2013-10-18 23:05 I attached an image here as an example. The gradient part on the left has the same hue value (would be considered identical color), while the small section on the right has increasing hue value going up. ---------------------------------------------------------------------- avra · 2013-10-21 07:20 If simple colors similarity is needed with just a little variance over RGB, CMYK or some other color space, then classic algorithms would do the job. Unfortunatelly, if you do a lot of color mixing, and you would like to guess that some color is skin color, earth color, yelowish green, bluish green, or whatever color names we have in use today, then you should study fuzzy logic to implement a smart human like color recognizer. Once you understand the principles, it is not hard to implement it. In short, any human experience that can be written down as a set of rules can be used to develop fuzzy rules for a simple fuzzy logic engine. It's powerful and not resource hungry - even 8-bit microcontrollers can use it. It's common use is in various 'smart' devices (air conditioner, washer machine, refrigirator), games AI, autonomous vehicles, optimal control loops... http://en.wikipedia.org/wiki/Fuzzy_control ---------------------------------------------------------------------- bigeno · 2013-10-21 21:34 Thanks for help guys, I've "fuzzy logic" on studying "long time ago"  but I think I do work on expand my base colors to RGB, it would be simpler and better. ---------------------------------------------------------------------- wp · 2013-10-21 23:02 A comment on engkin's posting at the top: Procedures for rgb-to-hls conversion and vice versa are available also in GraphUtils (ColorToHLS, RGBToHLS, HLSToColor, HLSToRGB) ---------------------------------------------------------------------- engkin · 2013-10-21 23:25 Quote from: wp on October 22, 2013, 01:02:56 amA comment on engkin's posting at the top: Procedures for rgb-to-hls conversion and vice versa are available also in GraphUtils (ColorToHLS, RGBToHLS, HLSToColor, HLSToRGB) Thank you so much for letting me know. I had used Graphics32 before knowing about Lazarus/FPC. Everyday I learn something I like here. Thanks again. Edit: The unit name is GraphUtil (graphutil.pp) without the s. These functions did exist in Delphi as well. ---------------------------------------------------------------------- circular · 2013-10-26 23:24 If you are not looking for maximum speed but for best quality, BGRABitmap provides BGRADiff and BGRAWordDiff, and conversions between RGB and HSL taking into account gamma correction and hue correction. You could just copy those functions without using BGRABitmap library, in this case however you need also GammaExpansion function which needs GammaExpansionTab array.