# HSI <-> RGB

• May 19th, 2001, 09:36 PM
lorba
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.

• March 1st, 2004, 06:47 AM
Andonic
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);
}

Bye.
• March 1st, 2004, 07:00 AM
Andonic
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.
• February 26th, 2013, 01:42 AM
khael
Re: HSI <-> RGB
can i ask for java codes with this???