Opencv中HIS和RGB图像互转代码,添加一个类名为:HSI_RGB_TRAN,以下分别为.h .cpp文件
 
HSI_RGB_TRAN.h 
#include <cv.h>
#include <math.h>
#include <highgui.h>
#include <vector>
using namespace std;
 
typedef struct HSI_Data
{
    int H;
    int S;
    int I;
 
}HSI_Data;
 
 
typedef struct HSI_Data_Uchar
{
    uchar H;
    uchar S;
    uchar I;
}HSI_Data_Uchar;
 
 
class HSI_RGB_TRAN
{
public:
    HSI_RGB_TRAN(void);
    ~HSI_RGB_TRAN(void);
 
    IplImage*HSI_RGB_TRAN::HSI2RGBImage(CvMat* HSI_H, CvMat* HSI_S, CvMat* HSI_I);
 
    void HSI_RGB_TRAN::RGB2HSImage(IplImage*img,CvMat* HSI_H, CvMat* HSI_S, CvMat* HSI_I);
 
    IplImage*HSI_RGB_TRAN:: catHSImage(CvMat* HSI_H, CvMat* HSI_S, CvMat* HSI_I);
 
};
 
HSI_RGB_TRAN.cpp
 
#include "stdafx.h"
#include "HSI_RGB_TRAN.h"
 
 
HSI_RGB_TRAN::HSI_RGB_TRAN(void)
{
}
 
 
HSI_RGB_TRAN::~HSI_RGB_TRAN(void)
{
}
 
 IplImage*HSI_RGB_TRAN::HSI2RGBImage(CvMat* HSI_H, CvMat* HSI_S, CvMat* HSI_I)
 {
     IplImage * RGB_Image = cvCreateImage(cvGetSize(HSI_H), IPL_DEPTH_8U, 3 );
 
     int iB, iG, iR;
     for(int i = 0; i < RGB_Image->height; i++)
     {
         for(int j = 0; j < RGB_Image->width; j++)
         {
             // 该点的色度H
             double dH = cvmGet( HSI_H, i, j );
             // 该点的色饱和度S
             double dS = cvmGet( HSI_S, i, j );
             // 该点的亮度
             double dI = cvmGet( HSI_I, i, j );
 
             double dTempB, dTempG, dTempR;
             // RG扇区
             if(dH < 120 && dH >= 0)
             {
                 // 将H转为弧度表示
                 dH = dH * 3.1415926 / 180;
                 dTempB = dI * (1 - dS);
                 dTempR = dI * ( 1 + (dS * cos(dH))/cos(3.1415926/3 - dH) );
                 dTempG = (3 * dI - (dTempR + dTempB)); 
             }
             // GB扇区
             else if(dH < 240 && dH >= 120)
             {
                 dH -= 120;
 
                 // 将H转为弧度表示
                 dH = dH * 3.1415926 / 180;
 
                 dTempR = dI * (1 - dS);
                 dTempG = dI * (1 + dS * cos(dH)/cos(3.1415926/3 - dH));
                 dTempB = (3 * dI - (dTempR + dTempG));
             }
             // BR扇区
             else 
             {
                 dH -= 240;
 
                 // 将H转为弧度表示
                 dH = dH * 3.1415926 / 180;
 
                 dTempG = dI * (1 - dS);
                 dTempB = dI * (1 + (dS * cos(dH))/cos(3.1415926/3 - dH));
                 dTempR = (3* dI - (dTempG + dTempB));
             }
 
             iB = dTempB * 255;
             iG = dTempG * 255;
             iR = dTempR * 255;
 
             cvSet2D( RGB_Image, i, j, cvScalar( iB, iG, iR ) );
         }
     }
 
     return RGB_Image;
 }
 
 void HSI_RGB_TRAN::RGB2HSImage(IplImage*img,CvMat* HSI_H, CvMat* HSI_S, CvMat* HSI_I)
 {
     // 原始图像数据指针, HSI矩阵数据指针
     uchar* data;
 
     // rgb分量
     byte img_r, img_g, img_b;
     byte min_rgb;  // rgb分量中的最小值
     // HSI分量
     double fHue, fSaturation, fIntensity; 
 
     for(int i = 0; i < img->width; i++)
     {
         for(int j = 0; j < img->height; j++)
         {
             data = cvPtr2D(img, j, i, 0);  
             img_b = *data;
             data++;
             img_g = *data;
             data++;
             img_r = *data;
 
             // Intensity分量[0, 1]
             fIntensity = (float)((img_b + img_g + img_r)/3)/255;
 
             // 得到RGB分量中的最小值
             float fTemp = img_r < img_g ? img_r : img_g;
             min_rgb = fTemp < img_b ? fTemp : img_b;
             // Saturation分量[0, 1]
             fSaturation = 1 - (float)(3 * min_rgb)/(img_r + img_g + img_b);
 
             // 计算theta角
             float numerator = (img_r - img_g + img_r - img_b ) / 2;
             float denominator = sqrt( 
                 pow(double (img_r - img_g), 2 ) +double( (img_r - img_b)*(img_g - img_b)) );
 
             // 计算Hue分量
             if(denominator != 0)
             {
                 float theta = acos( numerator/denominator) * 180/3.14;
 
                 if(img_b <= img_g)
                 {
                     fHue = theta ;
                 }
                 else
                 {
                     fHue = 360 - theta;
                 }
             }
             else
             {
                 fHue = 0;
             }
 
 
 
             // 赋值
             cvmSet( HSI_H, i, j, fHue );
             cvmSet( HSI_S, i, j, fSaturation);
             cvmSet( HSI_I, i, j, fIntensity );
         }
     }
 }
 
 // 将HSI颜色空间的三个分量组合起来,便于显示
IplImage*HSI_RGB_TRAN:: catHSImage(CvMat* HSI_H, CvMat* HSI_S, CvMat* HSI_I)
 {
     IplImage* HSI_Image = cvCreateImage( cvGetSize( HSI_H ), IPL_DEPTH_8U, 3 );
 
     for(int i = 0; i < HSI_Image->height; i++)
     {
         for(int j = 0; j < HSI_Image->width; j++)
         {
             double d = cvmGet( HSI_H, i, j );
             int b = (int)(d * 255/360);
             d = cvmGet( HSI_S, i, j );
             int g = (int)( d * 255 );
             d = cvmGet( HSI_I, i, j );
             int r = (int)( d * 255 );
 
             cvSet2D( HSI_Image, i, j, cvScalar( r, g, b ) );
         }
     }
 
     return HSI_Image;
 }
 
 
///////调用
 
CvMat* HSI_H=NULL,*HSI_S=NULL,*HSI_I=NULL;
    HSI_H = cvCreateMat( AOImage->width, AOImage->height, CV_32FC1 );
    HSI_S = cvCreateMat( AOImage->width, AOImage->height, CV_32FC1 );
    HSI_I = cvCreateMat(AOImage->width, AOImage->height, CV_32FC1 );
 
        hsi_rgb.RGB2HSImage(AOImage,HSI_H,HSI_S,HSI_I);