您的位置:首页 > 其它

RGB转HSI

2015-11-13 11:46 162 查看
1. RGB 向HSI 模型的转换是由一个基于笛卡尔直角坐标系的单位立方体向基于圆柱极坐标的双锥体的转换。基本要求是将RGB
中的亮度因素分离,将色度分解为色调和饱和度,并用角向量表示色调,如下图所示。



2. RGB 转换至HSI的几种常见方法,下图列出几种常用的RGB-HSI转换公式:


#if 1
#include<iostream>
#include<stdio.h>
#include<opencv2\opencv.hpp>
#include<math.h>

int rgb2hsi(IplImage *,IplImage *,IplImage *,IplImage * );
int min(int, int, int);

int main()
{
IplImage *Img=cvLoadImage("Desert.jpg", 1);
IplImage *HImg=cvCreateImage(cvGetSize(Img), IPL_DEPTH_8U, 1);
IplImage *SImg=cvCreateImage(cvGetSize(Img), IPL_DEPTH_8U, 1);
IplImage *IImg=cvCreateImage(cvGetSize(Img), IPL_DEPTH_8U, 1);

cvNamedWindow("src", 1);
cvNamedWindow("HImg", 1);
cvNamedWindow("SImg", 1);
cvNamedWindow("IImg", 1);

if(rgb2hsi(Img, HImg, SImg, IImg))
printf("convert successfully\n");
else
{
printf("convert failed\n");
exit(-1);
}

cvShowImage("src", Img);
cvShowImage("HImg", HImg);
cvShowImage("SImg", SImg);
cvShowImage("IImg", IImg);

cvWaitKey(0);
cvReleaseImage(&HImg);
cvReleaseImage(&SImg);
cvReleaseImage(&IImg);
cvDestroyAllWindows();
}

int rgb2hsi(IplImage *Img, IplImage *HImg, IplImage *SImg, IplImage *IImg)
{
uchar* srcData = (uchar*)Img->imageData;//数据的起始地址
uchar* HImgData = (uchar*)HImg->imageData;
uchar* SImgData = (uchar*)SImg->imageData;
uchar* IImgData = (uchar*)IImg->imageData;

int srcStep = Img->widthStep;//图像的行长度,即多少个字节
int HImgStep = HImg->widthStep;
int SImgStep = SImg->widthStep;
int IImgStep = IImg->widthStep;
int r, g, b, minrgb, S;
double sum, num, den, cosThita;

for (int row = 0; row < Img->height; row++)
{
for (int col = 0; col < Img->width; col++)
{
r = srcData[ row*srcStep + col*Img->nChannels + 0];//Blue通道
g = srcData[ row*srcStep + col*Img->nChannels + 1];//Green通道
b = srcData[ row*srcStep + col*Img->nChannels + 2]; //Red通道

IImgData[row*IImgStep + col*1]=(int)(r+g+b)/3; //亮度I

num=(r-g+r-b)/2;
sum=(double)((r-g)*(r-g)+(r-b)*(g-b));
den=sqrt(sum);
cosThita=acos(num/den);
if (g>=b)
cosThita = cosThita/(2*3.14);
else
cosThita = (2*3.14-cosThita)/(2*3.14);
HImgData[row*HImgStep + col*1] = (int)(cosThita*255); //色调H, 顺便将H分量都扩充到[0,255]区间以便于显示, 一般H分量在[0,2pi]之间

minrgb=min(r, g, b);
if ((r+g+b) == 0)
den=0.01;
else
den=r+g+b;
q S=1-3*minrgb/den;
SImgData[row*SImgStep + col*1] = (int)(S*255+0.5);//饱和度S, 顺便将S分量都扩充到[0,255]区间以便于显示,一般S在[0,1]之间
}
}
return 1;
}

int min(int a, int b, int c)
{
int temp=a;
if (temp > b)
temp = b;
if (temp >c)
temp = c;
return temp;
}
#endif
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: