CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4

Thread: HSI <-> RGB

Hybrid View

  1. #1
    Join Date
    Mar 2001
    Location
    Singapore
    Posts
    57

    HSI <-> RGB

    Hi, any one has code for HSI-&gt;RGB and RGB-&gt;HSI conversion?

    I have conversion for HSV, HSL and HWB, but cant seem to find one for HSI.


  2. #2
    Join Date
    Nov 2001
    Posts
    17
    Hi:
    I have found this somewhere:

    // Program: RGB <-> HSI conversion program
    // File: rgb2hsi.c / hsi2rgb.c
    // Description: Convert between RGB and HSI format
    // Author: Leiming Qian <lqian@uiuc.edu> (LQ)
    // Environment: ANSI C++
    // Notes: C++ version of the Javascript conversion code in
    // http://www.ndirect.co.uk/~thomas.green/
    // javascripts/hexAndRGB.html
    // REvisions: 1.0 09/01/01 (LQ) first release


    #include <iostream.h>
    #include <stdlib.h>
    #include <math.h>
    #include <string.h>

    #define MIN(x, y) ( (x)<(y) ? (x) : (y) )
    #define MAX(x, y) ( (x)>(y) ? (x) : (y) )
    #define RINT(x) ( (x)-floor(x)>0.5? ceil(x) : floor(x) )

    int main(int argc, char *argv[])
    {
    double R, G, B, H, S, I;

    // first make sure we have enough arguments
    if (argc!=4) {
    cout << "Usage: rgb2hsi R G B" << endl;
    cout << " or hsi2rgb H S I" << endl;
    return(1);
    }

    // next determine if we are calling RGB2HSI or HSI2RGB
    if ( strstr(argv[0], "rgb2hsi") != NULL ) {
    // RGB to HSI
    R = atof(argv[1]);
    G = atof(argv[2]);
    B = atof(argv[3]);

    if (R<0 || R>255 || G<0 || G>255 || B<0 || B>255) {
    cout << "Value out of range!" << endl;
    return(1);
    }

    // find out the min, mid, and max of R, G, B
    double min, mid, max;
    if (R>G && R>B) {
    max = R;
    mid = MAX(G, B);
    min = MIN(G, B);
    }
    else {
    if (G>B) {
    max = G;
    mid = MAX(R, B);
    min = MIN(R, B);
    }
    else {
    max = B;
    mid = MAX(R, G);
    min = MIN(R, G);
    }
    }

    I = max / 255;
    S = 0;
    H = 0;
    if (I==0 || max==min) {
    // this is a black image or grayscale image
    S = 0;
    H = 0;
    }
    else {
    S = (I - min/255) / I;
    // domains are 60 degrees of
    // red, yellow, green, cyan, blue or magenta
    double domainBase = 0.0;
    double oneSixth = 1.0/6.0;
    double domainOffset = ( (mid-min) / (max-min) ) / 6.0;

    if (R==max) {
    if (mid==G) { // green is ascending
    domainBase = 0; // red domain
    }
    else { // blue is descending
    domainBase = 5.0/6.0; // magenta domain
    domainOffset = oneSixth - domainOffset;
    }
    }
    else {
    if (G==max) {
    if (mid==B) { // blue is ascending
    domainBase = 2.0/6.0; // green domain
    }
    else { // red is ascending
    domainBase = 1.0/6.0; // yellow domain
    domainOffset = oneSixth - domainOffset;
    }
    }
    else {
    if (mid==R) { // red is ascending
    domainBase = 4.0/6.0; // blue domain
    }
    else { // green is descending
    domainBase = 3.0/6.0; // cyan domain
    domainOffset = oneSixth - domainOffset;
    }
    }
    }
    H = domainBase + domainOffset;
    }

    cout << "H = " << H << "\t";
    cout << "S = " << S << "\t";
    cout << "I = " << I << "\n";

    }
    else {
    // HSI to RGB
    H = atof(argv[1]);
    S = atof(argv[2]);
    I = atof(argv[3]);

    if (H<0 || H>1 || S<0 || S>1) {
    cout << "Value out of range!" << endl;
    return(1);
    }

    if (I==0.0) {
    // black image
    R = G = B = 0;
    }
    else {
    if (S==0.0) {
    // grayscale image
    R = G = B = I;
    }
    else {
    double domainOffset = 0.0;
    if (H<1.0/6.0) { // red domain; green acending
    domainOffset = H;
    R = I;
    B = I * (1-S);
    G = B + (I-B)*domainOffset*6;
    }
    else {
    if (H<2.0/6) { // yellow domain; red acending
    domainOffset = H - 1.0/6.0;
    G = I;
    B = I * (1-S);
    R = G - (I-B)*domainOffset*6;
    }
    else {
    if (H<3.0/6) { // green domain; blue descending
    domainOffset = H-2.0/6;
    G = I;
    R = I * (1-S);
    B = R + (I-R)*domainOffset * 6;
    }
    else {
    if (H<4.0/6) { // cyan domain, green acsending
    domainOffset = H - 3.0/6;
    B = I;
    R = I * (1-S);
    G = B - (I-R) * domainOffset * 6;
    }
    else {
    if (H<5.0/6) { // blue domain, red ascending
    domainOffset = H - 4.0/6;
    B = I;
    G = I * (1-S);
    R = G + (I-G) * domainOffset * 6;
    }
    else { // magenta domain, blue descending
    domainOffset = H - 5.0/6;
    R = I;
    G = I * (1-S);
    B = R - (I-G) * domainOffset * 6;
    }
    }
    }
    }
    }
    }
    }

    R = RINT(R*255);
    G = RINT(G*255);
    B = RINT(B*255);

    cout << "R = " << R << "\t";
    cout << "G = " << G << "\t";
    cout << "B = " << B << "\n";
    }

    return(0);
    }



    i hope this help you.

    Bye.

  3. #3
    Join Date
    Nov 2001
    Posts
    17
    Hi:
    One thing more, this is the matemathical description. Perhaps, it helps you:

    I = (1/3) *(R+G+B)
    S= 1 - ( (3/(R+G+B)) * min(R,G,B))
    H= cos^-1( ((1/2) * ((R-G) + (R - B))) / ((R-G)^2 + (R-B)*(G-B)) ^(1/2) )

    These equations need some corrections:

    · H = (360º - H) if (B/I) > (G/I) and H is normalized by H = H/360º

    · H is not defined if S = 0

    · S is undefined if I = 0

    good bye.

  4. #4
    Join Date
    Feb 2013
    Posts
    1

    Re: HSI <-> RGB

    can i ask for java codes with this???

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured