Sunday, February 19, 2012

HSI - RGB Conversion Algorithms in C

In order to understand this article you should probably read this article first:

If you are curious about the theory behind the HSI and RGB color spaces, you can read this articles:

1.RGB to HSI Conversion

This function will create a HSI model from a RGB model. The algorithm behind the conversion is described by the formulas below:
RGB to HSI conversion formulas
The meaning of the variables:
M - the RGB component with the greatest value
m - the RGB component with the smalles value
c - chroma
rf,gf,bf - the components of the RGB model (red, green, blue)
h,s,i - the components of HSL model (hue, saturation, intensity)

The components of the RGB model (r,g,b), saturation (S)  and intensity (I) should have values in the range [0,1], while the hue (h) should have values in the range [0,360].

The prototype of the function is:
/* Description:
 *  Creates a HsiColor structure from RGB components
 * Parameters:
 *  r,g,b - the components of an RGB model expressed
 *          as real numbers
 * Returns:
 *  A pointer to the HsiColor is the parameters are
 * correct. Otherwise returns NULL.
 */
HsiColor* Hsi_CreateFromRgbF(double r, double g, double b);
The function can be implemented as:
HsiColor* Hsi_CreateFromRgbF(double r, double g, double b)
{
    HsiColor* color = NULL;
    double m = Double_GetMinimum(r,g,b);
    double M = Double_GetMaximum(r,g,b);
    double c = M-m;
    if(RgbF_IsValid(r,g,b)==true)
    {
        color = (HsiColor*)malloc(sizeof(HsiColor));
        color->I = (1.0/3.0)*(r+g+b);
        if(c==0)
        {
            color->H = 0.0;
            color->S = 0.0;
        }
        else
        {
            if(M==r)
            {
                color->H = fmod(((g-b)/c), 6.0);
            }
            else if(M==g)
            {
                color->H = (b-r)/c + 2.0;
            }
            else if(M==b)
            {
                color->H = (r-g)/c + 4.0;
            }
            color->H *=60.0;
            color->S = 1.0 - (m/color->I);
        }
    }
    return color;
}
2.HSI to RGB Conversion 
This function will create a RGB model from a HSI model. The algorithm behind the conversion is described by the formulas below:
HSI to RGB conversion formulas
The meaning of the variables:
h, s, i - the components of the HSI model (hue, saturation, intensity)
hr - the hue component expressed in radians
k - the correcting coefficient for hr
x,y,z - intermediary values
x',y',z' - intensity-compensated intermediary values
Rf, Gf, Bf - the components of the RGB model (red, green blue)

The components of the RGB model (r,g,b), saturation (S) and intensity (I) should have values in the range [0,1], while the hue (h) should have values in the range [0,360].

The prototype of the function is:
/*
 * Description:
 *  Creates a RgbFColor structure from HSI components
 * Parameters:
 *  h,s,i - the components of an HSI model expressed
 *          as real numbers
 * Returns:
 *  A pointer to the RgbFColor is the parameters are
 * correct. Otherwise returns NULL.
 */
RgbFColor* RgbF_CreateFromHsi(double h, double s, double i);
The function can be implemented as:
RgbFColor* RgbF_CreateFromHsi(double h, double s, double i)
{
    RgbFColor* color = NULL;
    if(Hsi_IsValid(h,s,i)==true)
    {
        color = RgbF_Create(0.0,0.0,0.0);
        if(h>=0.0 && h<=(HUE_UPPER_LIMIT/3.0))
        {
            color->B = (1.0/3.0)*(1.0-s);
            color->R = (1.0/3.0)*((s*cos(h))/cos(60.0-h));
            color->G = 1.0-(color->B + color->R);
        }
        else if(h>(HUE_UPPER_LIMIT/3.0) && h<=(2.0*HUE_UPPER_LIMIT/3.0))
        {
            h-=(HUE_UPPER_LIMIT/3.0);
            color->R = (1.0/3.0)*(1.0-s);
            color->G = (1.0/3.0)*((s*cos(h))/cos(60.0-h));
            color->B = 1.0-(color->G + color->R);

        }
        else /* h>240 h<360 */
        {
            h-=(2.0*HUE_UPPER_LIMIT/3.0);
            color->G = (1.0/3.0)*(1.0-s);
            color->B = (1.0/3.0)*((s*cos(h))/cos(60.0-h));
            color->R = 1.0-(color->G + color->B);
        }
    }
    return color;
}
3. Example
#include<stdio.h>
#include"colorspace.h"

int main(int argc, char** argv)
{
    HsiColor* hsi = NULL;
    RgbFColor* rgbF = NULL;
    RgbIColor* rgbI = NULL;

    /*HSI to RGB*/
    hsi = Hsi_Create(30.0, 0.3, 0.2);
    rgbF = RgbF_CreateFromHsi(hsi->H, hsi->S, hsi->I);
    rgbI = RgbI_CreateFromRealForm(rgbF->R, rgbF->G, rgbF->B);
    printf("\nHSI : %f %f %f", hsi->H, hsi->S, hsi->I);
    printf("\nRGBf : %f %f %f", rgbF->R, rgbF->G, rgbF->B);
    printf("\nRGBi : %d %d %d", rgbI->R, rgbI->G, rgbI->B);

    /*Frees the resources*/
    free(hsi);
    free(rgbF);
    free(rgbI);

    /*RGB to HSI*/
    rgbI = RgbI_Create(34U, 50U, 98U);
    rgbF = RgbF_CreateFromIntegerForm(rgbI->R, rgbI->G, rgbI->B);
    hsi = Hsi_CreateFromRgbF(rgbF->R, rgbF->G, rgbF->B);
    printf("\nHSI : %f %f %f", hsi->H, hsi->S, hsi->I);
    printf("\nRGBf : %f %f %f", rgbF->R, rgbF->G, rgbF->B);
    printf("\nRGBi : %d %d %d", rgbI->R, rgbI->G, rgbI->B);
    return 0;
}
/*
 HSI : 30.000000 0.300000 0.200000
 RGBf : 0.100000 0.666667 0.233333
 RGBi : 26 170 60
 HSI : 225.000000 0.439560 0.237909
 RGBf : 0.133333 0.196078 0.384314
 RGBi : 34 50 98
 */

4 comments:

  1. Replies
    1. Hello!

      I don't have a Java implementation for this algorithm, but you can use the formulas in the article to make your own implementation.

      Delete
    2. you dont have references, in what book is that transformation?

      Delete
    3. I found the formulas on a website, but since it was a while I don't remember which one was it.

      Currently I'm planning to start a new blog and I'll move my content there and redo most of my articles (including adding references).

      New address is : http://iskernel.blogspot.ro/

      P.S. Sorry for responding so late.

      Delete

Got a question regarding something in the article? Leave me a comment and I will get back at you as soon as I can!

Related Posts Plugin for WordPress, Blogger...
Recommended Post Slide Out For Blogger