前言
Opencv中有多种颜色空间的转换,唯独没有RGB与HSI的转换,这在遥感影像处理中至关重要,所以写了这个,这个转换有多种方法,我用两种方法实现了,但是方法1算出来不正确,还未找到原因,方法二经过改进结果正确,解决了网上代码存在的一些问题,应该是全网(百度、Google)差不多是最好的了,欢迎打脸。
算法介绍,看这里:http://blog.sina.com.cn/s/blog_a5b3ed560100yo26.html
他博客的算法图片:

其中算法1,我没做出来,做了算法2。
/*
作者:山科_xxin
时间:2017-03-27 23:08:26
功能:<a href="https://www.ixxin.cn/tag/rgb2hsi/" title="查看更多关于RGB2HSI的文章" target="_blank">RGB2HSI</a>
类别:图像融合算法
*/
int rgb2hsi(Mat Rgbimg,Mat HV,Mat SV,Mat IV)
{
int row = Rgbimg.rows;
int col = Rgbimg.cols;
/*
vector<Mat> channels;
HV = channels.at(0);
SV = channels.at(1);
IV = channels.at(2);
*/
for(int i =0;i<row;i++)
for(int j = 0;j<col;j++)
{
float H = 0.0,S = 0.0,I = 0.0;
float BV = Rgbimg.at<Vec3b>(i,j)(0);
float GV = Rgbimg.at<Vec3b>(i,j)(1);
float RV = Rgbimg.at<Vec3b>(i,j)(2);
float num = (float)(RV-GV+RV-BV)/2.0;
float den = (float)std::sqrt((double)((RV-GV)*(RV-GV)+(RV-BV)*(GV-BV)));
if(den!=0)
{
float cosTA = acos(num/den);
if(BV<=GV)
{
H = cosTA/(CV_PI*2);
}
else
{
H = (2*CV_PI-cosTA)/(2*CV_PI);
}
}
else
{
H = 0;
}
float minv = min(min(BV,GV),RV);
den = BV+GV+RV;
if(den ==0)
S = 0;
else
S = 1-(float)(3*minv/den);
I = ((RV+BV+GV)/3)/255;
HV.at<float>(i,j) = H;
SV.at<float>(i,j) = S;
IV.at<float>(i,j) = I;
}
return 0;
}
RGB:

HSI:

后语
我这个目前还存在一个问题就是,不是用指针遍历的,所以说相对于指针慢一些,我已经写好了指针遍历的,感兴趣的可以自己写一下。目前HSI2RGB还没写出来,HistMatch还没写出来,行百里者半九十!!!



