加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

RGB转HSI公式及C++代码

(2015-08-06 21:58:08)
标签:

hsi

颜色空间

分类: 图像处理

以下文字部分大都摘录于《HSI与RGB颜色模型的转换方法对比研究》 刘华波
孟塞尔系统和较晚出现的Ostwald(1923年,德国)和PCCS(1964年,日本)等颜色表示系统都符合二个基本原则,一是颜色恒常性原则,即将亮度和色度(色调+饱和度)独立表示; 二是色度二极渐弱原则,即亮度适中时人眼对色彩的分辨力最强,颜色的种类最多,而亮度趋强或趋弱时,分辨力会降低,直至为零。

HSI色彩空间是从人的视觉系统出发,用色调(Hue)、色饱和度(Saturation或Chroma)和亮度 (Intensity 或Brightness)来描述色彩。HSI色彩空间可以用一个圆锥空间模型来描述。用这种描述HIS色彩空间的圆锥模型相当复杂,但确能把色调、亮度和色饱和度的变化情形表现得很清楚。通常把色调和饱和度通称为色度,用来表示颜色的类别与深浅程度。由于人的视觉对亮度的敏感程度远强于对颜色浓淡的敏感程度,为了便于色彩处理和识别,人的视觉系统经常采用HSI色彩空间,它比RGB色彩空间更符合人的视觉特性。在图像处理和计算机视觉中大量算法都可在HSI色彩空间中方便地使用,它们可以分开处理而且是相互独立的。因此,在HSI色彩空间可以大大简化图像分析和处理的工作量。
以下代码部分,是由本人写出,供大家参考
typedef unsigned char uint8;
 const   uint8  RGBMAX = 255;
void CvtRGBToHSI(uint8 R, uint8 G, uint8 B, uint8& H, uint8& S, uint8& I)
{
 const   float PI2 = 2*3.1415926;
 float r = float(color.R)/RGBMAX;
 float g = float(color.G)/RGBMAX;
 float b = float(color.B)/RGBMAX;
 float maxVal = Max(Max(r, g), b);
 float minVal = Min(Min(r, g), b);
 
float   i = (r + g + b)/3;
float   s = 0.0f;
float   h = 0.0f;
 if(!EqualZero(i) && !EqualZero(maxVal -minVal))
 {
  float   diff  = 0.5f*(r-g + r-b);
  float   diff2 = (r-g)*(r-g) + (r-b)*(g-b);  //diff2 永远 > 0
  float   sita  = acos(diff/sqrt(diff2))/PI2;
        = (g>=b) ? sita : 1.0f - sita;
      = 1.0f - minVal/i;
 }
 if  (h < 0.0f )       h += 1.0f;
 else if (h > 1.0f ) h -= 1.0f;
H = (unsigned char)Round(h*RGBMAX);    //range: 0 to 255;
S = (unsigned char)Round(s*RGBMAX);     //range: 0 to 255;
I =  (unsigned char)Round(i*RGBMAX);     //range:  0 to 255;
}
 
 
PelHSL24 TColorCvtor::CvtRGBToHSL(uint8 R, uint8 G, uint8 B, uint8& H, uint8& S, uint8& L)
{
 float r = float(R)/RGBMAX;
 float g = float(G)/RGBMAX;
 float b = float(B)/RGBMAX;
 float maxVal = Max(Max(r, g), b);
 float minVal = Min(Min(r, g), b);
 float delt   = maxVal - minVal;
 float l = (maxVal + minVal)/2;
 float s = 0.0f;
 float h = 0.0f;
 
 if (maxVal != minVal) //作为unsigned char,浮点数是可以精确表示
 {
  if (l < 0.5f)
  s = delt / (maxVal + minVal);   }
  else
  s = delt / (2.0f - maxVal - minVal); }
  unsigned char maxV = Max(color.R, Max(color.G, color.B));
 
  if(R == maxV)
    h = (g - b)/delt;  }
  else if (color.G == maxV)
    h = 2.0f + (b - r)/delt;  }
  else if (color.B == maxV)
    h = 4.0f + (r - g)/delt;  }
 
   = h < 0 ? 6.0f + h : h;  //[-1 to 5] => [0 to 6], h==0, then red
  if  (h < 0.0f )       h += 1.0f;
  else if (h > 1.0f ) h -= 1.0f;
}
H = (unsigned char)Round(h*RGBMAX);    //range: 0 to 255;
S = (unsigned char)Round(s*RGBMAX);     //range: 0 to 255;
L=  (unsigned char)Round(l*RGBMAX);     //range:  0 to 255;
}
 
温馨提示:如果你要对多幅图像进行转换,例如相机一边实时采集一边进行转换,则可以生成颜色转换表,图像颜色空间转换时直接查表即可,速度快;当然是要消耗内存的(48M内存,对于现在的计算机配置,这不算什么)。如果您是高性能PC,并且使用并行编程,N个核一起工作,另当别论。
 
 
 
 

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有