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
中的亮度因素分离,将色度分解为色调和饱和度,并用角向量表示色调,如下图所示。
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
相关文章推荐
- C++复杂在哪里?
- cmake命令 安装、用法简介
- IOS 程序实现多种语言的本地化
- cmake命令 安装、用法简介
- js判断是否为正整数的正则写法 JavaScript正整数正则
- play framework中plugins和enhancers
- C# 将数据生成excel并储存
- spring的Annotation动态代理报错$Proxy11 cannot be cast to com.spring.service.BServiceImpl解决方案
- 环境变量是什么?
- 0x7743fcec 处未处理的异常: 0xC015000F: 正被停用的激活上下文不是最近激活的
- Loadrunner 中参数执行顺序
- ios中tabbar得title和navigationbar的title如何修改才能不会同时命名
- Hadoop-2.7.1集群环境搭建
- LVS + keepalived负载均衡DR实验
- iOS手写2048--基于Xcode7.1
- PopupWindow与AlertDialog的使用
- 域名汇总
- 写着玩的文章
- Linux下时间输出格式精确到微秒-gettimeofday
- sql时间转换字符串