# Conversion from RGB to HSI

Hi to all! I need a color conversion from RGB (or BGR) color space into HSI color space. But openCV implements only RGBtoHSV or RGBtoHLS color conversion. Is there a function, a plugin or something else that could make this conversion??

edit retag close merge delete

Sort by » oldest newest most voted

Apparently it does not, however if you follow the equations to convert RGB/BGR values to HSI values, it should not be that hard. If we suppose R, G, and B are the red, green, and blue values of a color and H,S, and I the hue, saturation and intensity respectively then:

which can be translated into:

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{

if(src.empty())
Mat hsi(src.rows, src.cols, src.type());

float r, g, b, h, s, in;

for(int i = 0; i < src.rows; i++)
{
for(int j = 0; j < src.cols; j++)
{
b = src.at<Vec3b>(i, j)[0];
g = src.at<Vec3b>(i, j)[1];
r = src.at<Vec3b>(i, j)[2];

in = (b + g + r) / 3;

int min_val = 0;
min_val = std::min(r, std::min(b,g));

s = 1 - 3*(min_val/(b + g + r));
if(s < 0.00001)
{
s = 0;
}else if(s > 0.99999){
s = 1;
}

if(s != 0)
{
h = 0.5 * ((r - g) + (r - b)) / sqrt(((r - g)*(r - g)) + ((r - b)*(g - b)));
h = acos(h);

if(b <= g)
{
h = h;
} else{
h = ((360 * 3.14159265) / 180.0) - h;
}
}

hsi.at<Vec3b>(i, j)[0] = (h * 180) / 3.14159265;
hsi.at<Vec3b>(i, j)[1] = s*100;
hsi.at<Vec3b>(i, j)[2] = in;
}
}

namedWindow("RGB image", CV_WINDOW_AUTOSIZE);
namedWindow("HSI image", CV_WINDOW_AUTOSIZE);

imshow("RGB image", src);
imshow("HSI image", hsi);

waitKey(0);
return 0;
}


it is an old code of mine, but I think it will serve you purposes.

more

@theodore: Just curious but what crime did HSI model do to not be included in heavenly Opencv library?

( 2016-06-17 07:50:37 -0600 )edit
1

to be honest I do not know the answer to this, but I guess it just didn't happen someone to make a PR with it upstream. I am sure that if someone does it the developers would be glad to add it in the library.

( 2016-06-17 15:27:01 -0600 )edit
1

Though I am under a lot of work, I will try to submit a PR. Thank you.

( 2016-06-25 10:53:39 -0600 )edit

that would be perfect. Go for it ;-)...

( 2016-06-25 15:03:08 -0600 )edit

Great work. But I know that rgb to hsi conversation means h channel takes places of the r channel, s channel takes places of the g channel and i channel takes places of the b channel. In opencv first channel of a pixel of a rgb formatted image is b. The second one is g and the last one is r. I think at the last of your code should be like this:

      hsi.at<Vec3b>(i, j)[2] = (h * 180) / 3.14159265;
hsi.at<Vec3b>(i, j)[1] = s*100;
hsi.at<Vec3b>(i, j)[0] = in;


Maybe I thing wrong. Thanks.

( 2017-01-13 21:39:14 -0600 )edit

Can anyone explain why there is a multiplication for s with factor 100?

( 2017-04-11 02:39:06 -0600 )edit

Thanks so much! It works! :)

more

Official site

GitHub

Wiki

Documentation