前言
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还没写出来,行百里者半九十!!!