Page 1 of 1

Color saturation

Posted: Thu Jul 11, 2024 8:39 pm
by Natter
There are several different colors. Is there a way to determine which one is more saturated ?

Re: Color saturation

Posted: Thu Jul 11, 2024 9:31 pm
by Antonio Linares
An example using C code:

Code: Select all | Expand

#include <stdio.h>
#include <math.h>

typedef struct {
    double r;
    double g;
    double b;
} RGB;

typedef struct {
    double h;
    double s;
    double v;
} HSV;

HSV rgb_to_hsv(RGB rgb) {
    HSV hsv;
    double min, max, delta;

    min = rgb.r < rgb.g ? rgb.r : rgb.g;
    min = min < rgb.b ? min : rgb.b;

    max = rgb.r > rgb.g ? rgb.r : rgb.g;
    max = max > rgb.b ? max : rgb.b;

    hsv.v = max;
    delta = max - min;

    if (max > 0.0) {
        hsv.s = (delta / max);
    } else {
        hsv.s = 0.0;
        hsv.h = NAN;
        return hsv;
    }

    if (rgb.r >= max)
        hsv.h = (rgb.g - rgb.b) / delta;
    else if (rgb.g >= max)
        hsv.h = 2.0 + (rgb.b - rgb.r) / delta;
    else
        hsv.h = 4.0 + (rgb.r - rgb.g) / delta;

    hsv.h *= 60.0;

    if (hsv.h < 0.0)
        hsv.h += 360.0;

    return hsv;
}

void compare_saturation(RGB color1, RGB color2) {
    HSV hsv1 = rgb_to_hsv(color1);
    HSV hsv2 = rgb_to_hsv(color2);

    if (hsv1.s > hsv2.s) {
        printf("Color 1 (%.0f, %.0f, %.0f) is more saturated\n", color1.r * 255, color1.g * 255, color1.b * 255);
    } else if (hsv2.s > hsv1.s) {
        printf("Color 2 (%.0f, %.0f, %.0f) is more saturated\n", color2.r * 255, color2.g * 255, color2.b * 255);
    } else {
        printf("Both colors have the same saturation\n");
    }
}

int main() {
    RGB color1 = {1.0, 0.0, 0.0}; // Pure red
    RGB color2 = {0.78, 0.39, 0.39}; // Less saturated red

    compare_saturation(color1, color2);

    return 0;
}

Re: Color saturation

Posted: Fri Jul 12, 2024 9:27 am
by Natter
Thank you, Antonio! Could you show the use of this example in FWH ?

Re: Color saturation

Posted: Fri Jul 12, 2024 11:15 am
by Antonio Linares
Here you have it. Please test it and let me know your results:

Code: Select all | Expand

#include "FiveWin.ch"

function Main()

    local nRed := CLR_RED
    local nRedLessSaturated := RGB( 255, 1, 1 )

    MsgInfo( RGBTOHSV( nRed ) > RGBTOHSV( nRedLessSaturated ) )

return nil 

#pragma BEGINDUMP

#include <hbapi.h>
#include <math.h>

typedef struct {
    double r;
    double g;
    double b;
} RGB;

typedef struct {
    double h;
    double s;
    double v;
} HSV;

HSV rgb_to_hsv(RGB rgb) {
    HSV hsv;
    double min, max, delta;

    min = rgb.r < rgb.g ? rgb.r : rgb.g;
    min = min < rgb.b ? min : rgb.b;

    max = rgb.r > rgb.g ? rgb.r : rgb.g;
    max = max > rgb.b ? max : rgb.b;

    hsv.v = max;
    delta = max - min;

    if (max > 0.0) {
        hsv.s = (delta / max);
    } else {
        hsv.s = 0.0;
        hsv.h = NAN;
        return hsv;
    }

    if (rgb.r >= max)
        hsv.h = (rgb.g - rgb.b) / delta;
    else if (rgb.g >= max)
        hsv.h = 2.0 + (rgb.b - rgb.r) / delta;
    else
        hsv.h = 4.0 + (rgb.r - rgb.g) / delta;

    hsv.h *= 60.0;

    if (hsv.h < 0.0)
        hsv.h += 360.0;

    return hsv;
}

HB_FUNC( RGBTOHSV )
{
   int color = hb_parnl( 1 );
   RGB rgbColor;
   HSV hsvColor; 

   rgbColor.r = (double)( color & 255 );
   rgbColor.g = (double)( ( color >> 8 ) & 255 );
   rgbColor.b = (double)( ( color >> 16 ) & 255 );
   hsvColor = rgb_to_hsv( rgbColor );

   hb_retnd( hsvColor.s );
}

#pragma ENDDUMP

Re: Color saturation

Posted: Fri Jul 12, 2024 11:30 am
by Natter
Okay, I'll try

Re: Color saturation

Posted: Sat Jul 13, 2024 7:50 pm
by Natter
When compiling, I get the error: Undefined symbol 'NAN' in function rgb_to_hsv

Re: Color saturation

Posted: Sat Jul 13, 2024 8:04 pm
by Antonio Linares
The code requires math.h, if you don't find it then add this code:

Code: Select all | Expand

#if !defined(NAN)
extern float _RTLENTRY _EXPDATA __ieee_32_p_nanq;
#define NAN __ieee_32_p_nanq
#endif

Re: Color saturation

Posted: Sat Jul 13, 2024 8:48 pm
by Natter
I tried both options. Anyway, I get an error: Unresolved external '__ieee_32_p_nanq' :(

Re: Color saturation

Posted: Sat Jul 13, 2024 9:05 pm
by Antonio Linares
look for math.h and provide its path when compiling the C code

-Ic:\bcc77\include\windows\crtl

Re: Color saturation

Posted: Mon Jul 15, 2024 1:33 pm
by Natter
Antonio, thank you, program is quite working.
For example, I read pixel gaps (contours of areas on the map) with increasing red saturation and confidently received the most brightly colored pixel.
It would be quite good to specify the boundaries of the contour brightness. For example, when reading a contour, there is a sharp turn/break. In this case, I have to find a continuation of the contour (on maps, the contour does not consist of a single color )

Re: Color saturation

Posted: Mon Jul 22, 2024 1:38 pm
by Natter
For example, the pixel color is one of the shades of red. Is it possible to find out that this color is basically red? (similar to green, blue, etc.)

Re: Color saturation

Posted: Mon Jul 22, 2024 2:35 pm
by Antonio Linares
You could compare the red, green and blue values and check if they are near values

Re: Color saturation

Posted: Mon Jul 22, 2024 9:04 pm
by Natter
Thanks, I get it! How can I convert a color from a number to an RGB array ?

Re: Color saturation

Posted: Tue Jul 23, 2024 3:43 am
by Lailton
You can use it:
Hex: #d3d3d3
Int: 13882323

Code: Select all | Expand

? hb_jsonEncode( int2rgb( 13882323 ) )

function Int2RGB( nColor )
    
    local aRGB := { 0, 0, 0 }
    
    aRGB[1] := Int( nColor / 65536 )
    aRGB[2] := Int( ( nColor / 256 ) % 256 )
    aRGB[3] := Int( nColor % 256 )
    
return aRGB
RGB Expected { 211, 211, 211 }

8)

Re: Color saturation

Posted: Tue Jul 23, 2024 7:06 am
by Natter
Thank you, Lailton !