// RbgtoHsi.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <stdio.h>
#include <math.h>
#include <cv.h>
#include <highgui.h>
#include <cxcore.h>
#include <cvaux.h>
int miny(int a, int b, int c);
int Rgb2Hsi(const IplImage* src, IplImage* dataH, IplImage* dataS, IplImage* dataI);
int main(int argc, char * argv[])
{
IplImage * Img = cvLoadImage("2.bmp", 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);
if( Rgb2Hsi(Img, HImg, SImg, IImg) == 0)
{
printf("Convert Error!\n");
exit(-1);
}
//高斯滤波先,以平滑图像
cvSmooth(SImg, SImg, CV_GAUSSIAN, 3, 0, 0, 0);
// cvThreshold(SImg, SImg, 100, 255, CV_THRESH_BINARY);
IplImage *pImgCanny = cvCreateImage(cvGetSize(SImg), IPL_DEPTH_8U, 1);
cvCanny(SImg, pImgCanny, 50, 150, 3);
cvNamedWindow("Img", 1);
cvNamedWindow("HImg", 1);
cvNamedWindow("SImg", 1);
cvNamedWindow("IImg", 1);
cvShowImage("Img", Img);
cvShowImage("HImg", HImg);
cvShowImage("SImg", SImg);
cvShowImage("IImg", IImg);
cvWaitKey(0);
return 0;
}
int miny(int a, int b, int c)
{
int m = a;
if(m > b)
m = b;
if( m > c)
m = c;
return m;
}
int Rgb2Hsi(const IplImage* src, IplImage* dataH, IplImage* dataS, IplImage* dataI)
{
//返回0:成功,1:失败
//输入为彩色图像src, 输出dataH,dataS,dataI,分别为HSI模型的H、S、I分量
int y,x,offsetSrc,offsetHsi;
int step,channels,step1;
int r,g,b,minRgb;
double cosThita,num,den,S,H;
uchar *dataImg;
uchar *dataS1;
uchar *dataI1;
uchar *dataH1;
channels = src->nChannels;
dataImg = (uchar *)src->imageData;
dataI1 = (uchar *)dataI->imageData;
dataH1=(uchar *)dataH->imageData;
dataS1=(uchar *)dataS->imageData;
if (channels!=3)
{
printf("The input image is not 3-channels!\n");
return 0;
}
step=src->widthStep;
step1=dataI->widthStep;
for (y=0; y<src->height; y++)
for (x=0; x<src->width; x++)
{
offsetSrc = y*step + x*channels;
offsetHsi=y*step1+x;
b = dataImg[offsetSrc];
g=dataImg[offsetSrc+1];
r=dataImg[offsetSrc+2];
dataI1[offsetHsi] = (int)((r+g+b)/3+0.5);
num=(2*r-g-b)/2;
den=sqrt((r-g)*(r-g)+(r-b)*(g-b));
if (den==0)
den=0.01;
cosThita=acos(num/den);
minRgb = miny(r, g, b);
den=r+g+b;
if (den==0)
den=0.01;
S=1-3*minRgb/den;
dataS1[offsetHsi]=(int) (S*255+0.5);//将S分量和H分量都扩充到[0,255]区间以便于显示
//一般H分量在[0,2pi]之间,S在[0,1]之间
if (b<=g)
H=cosThita/(2*3.14);
else
H=(2*3.14-cosThita)/(2*3.14);
dataH1[offsetHsi] = (int)(H*255+0.5);
if (S==0)
dataH1[offsetHsi]=0;
}
return 1;
}
效果:
hue [hjuː] n. 色调
saturability [sætʃərə'biliti] n. 饱和度
luminance ['lumɪnəns] n. 亮度
opencv rgbtohsi
int main(int argc, char *argv[])
{
IplImage *img = cvLoadImage("r2.jpg",1);
IplImage *r = cvCreateImage( cvGetSize(img), img->depth, 1);
IplImage *g = cvCreateImage( cvGetSize(img), img->depth, 1);
IplImage *b = cvCreateImage( cvGetSize(img), img->depth, 1);
CvMat *rmat = cvCreateMat( img->height, img->width, CV_32FC1);
CvMat *gmat = cvCreateMat( img->height, img->width, CV_32FC1);
CvMat *bmat = cvCreateMat( img->height, img->width, CV_32FC1);
CvMat *temp1 = cvCreateMat( img->height, img->width, CV_32FC1);
CvMat *temp2 = cvCreateMat( img->height, img->width, CV_32FC1);
CvMat *temp3 = cvCreateMat( img->height, img->width, CV_32FC1);
// cvNamedWindow("saturation", 1);
// cvNamedWindow("intensity", 1);
cvSplit( img, b, g, r, NULL);
cvConvert(b, bmat);
cvConvert(g, gmat);
cvConvert(r, rmat);
//计算饱和度S
cvMin( bmat, gmat, temp1);
cvMin( rmat, temp1, temp1);
cvAdd( bmat, gmat, temp2 );
cvAdd( temp2, rmat, temp2);
cvDiv( temp1, temp2, temp3, 765.0);
// cvDiv( temp1, temp2, temp3, 1);
cvAbsDiffS( temp3, temp3, cvScalarAll( 255.0 ));
cvConvert( temp3, r );
//计算亮度I
cvAddWeighted( bmat, 1.0/3.0, rmat, 1.0/3.0, 0.0, bmat );
cvAddWeighted( bmat, 1.0, gmat, 1.0/3.0, 0.0, bmat);
cvConvert( bmat, g );
// cvShowImage("saturation", r);
// cvShowImage( "intensity", g);
cvSaveImage("saturation.jpg",r);
cvSaveImage("intensity.jpg",g);
}