天天看點

圖像的RGB顔色空間和HSI空間的轉換

來源:http://yzyanchao.blogbus.com/logs/20013780.html

//以下三個函數是用作RGB和HSI值轉化,但是有誤差。

double MinOfRGB(int R, int G, int B)

{

 if (R<G)

  if (R<B)

   return (double)R/(double)(R+G+B); //G>R,B>R 

  else

   return (double)B/(double)(R+G+B); //G>R>B

 else

  if (G>B)

   return (double)B/(double)(R+G+B); //R>G>B

  else

   return (double)G/(double)(R+G+B); //R>G, R>B

}

void RGBtoHSI(int R,int G,int B,int &H,int &S,int &I)

{

 double r,g,b;

 r = (double)R/(double)(R+G+B);

 g = (double)G/(double)(R+G+B);

 b = (double)B/(double)(R+G+B);

 double h,s,i;

 if (B<=G)

  h = acos( 0.5*(r-g+r-b) / sqrt((r-g)*(r-g)+(r-b)*(g-b)) );

 else

  h = 2*PI - acos( 0.5*(r-g+r-b) / sqrt((r-g)*(r-g)+(r-b)*(g-b)) );

 s = 1 - 3*MinOfRGB(R,G,B);

 i = (double)(R+G+B)/3/255;

 H = h*180/PI;

 S = s*100;

 I = i*255; 

}

void HSItoRGB(int H,int S,int I,int &R,int &G,int &B)

{

 double h,s,i;

 h = (double)H*PI/180;

 s = (double)S/100;

 i = (double)I/255;

 int flag;

 if ( h < (2*PI/3) )

  flag = 0;

 else if ( h >= (2*PI/3) && h < (4*PI/3) )

 {

  flag = 1;

  h -= 2*PI/3;

 }

 else

 {

  flag = 2;

  h -= 4*PI/3;

 }

 double x,y,z;

 x = i*(1-s);

 y = i*(1 + s*cos(h) / cos(PI/3-h));

 z = 3*i-x-y;

 double r,g,b;

 if ( flag == 0 )

 {

  b = x;

  r = y;

  g = z;

 }

 else if ( flag == 1 )

 {  

  r = x;

  g = y;

  b = z;

 }

 else if ( flag == 2 )

 {

  g = x;

  b = y;

  r = z;

 }

 R = r*255;

 B = b*255;

 G = g*255;

}

    這三個函數實作了一對RGB和HSI值間的轉換,對于整張圖像,一個像素一個像素地這樣轉換就可以了。

繼續閱讀