OpenCV之RGB与HSV颜色空间的转换
2014-10-18 20:10
330 查看
关于HSV颜色空间,还有一些参考性的博客,如http://blog.sina.com.cn/s/blog_6a22365901012nxl.html
HSV的介绍请参见维基百科:http://en.wikipedia.org/wiki/HSL_and_HSV,与其类似的颜色空间还有HSL(或称HLS)和HSI。本文有两则代码,代码一,自实现了RGB颜色空间与HSV颜色空间之间的转换,并与OpenCV中的cvCvtColor进行了比较;代码二,实现了一个HSV颜色盘。
代码一:
[cpp] view
plaincopy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
//====================================================================
// 作者 : quarryman
// 邮箱 : quarrying{at}qq.com
// 主页 : http://blog.csdn.net/quarryman
// 日期 : 2013年12月22日
// 描述 : RGB颜色空间与HSV颜色空间之间的转换
//====================================================================
#include <cv.h>
#include <highgui.h>
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
IplImage* kcvRGB2HSV(IplImage* img)
{
int w=img->width;
int h=img->height;
IplImage* dst=cvCreateImage(cvSize(w,h),8,3);
for(int j=0;j<w;++j)
{
for(int i=0;i<h;++i)
{
int b=CV_IMAGE_ELEM(img,uchar,i,j*3+0);
int g=CV_IMAGE_ELEM(img,uchar,i,j*3+1);
int r=CV_IMAGE_ELEM(img,uchar,i,j*3+2);
int maxval=max(b,max(g,r));
int minval=min(b,min(g,r));
int v=maxval;
double diff=maxval-minval;
int s=diff*255/(v+DBL_EPSILON);
double h=0;
diff=60/(diff+DBL_EPSILON);
if(v==r)
{
h=(g-b)*diff;
}
else if(v==g)
{
h=(b-r)*diff+120.f;
}
else
{
h=(r-g)*diff+240.f;
}
if( h<0)
{
h+=360.f;
}
CV_IMAGE_ELEM(dst,uchar,i,j*3+0)=h/2;
CV_IMAGE_ELEM(dst,uchar,i,j*3+1)=s;
CV_IMAGE_ELEM(dst,uchar,i,j*3+2)=v;
}
}
return dst;
}
IplImage* kcvHSV2RGB(IplImage* img)
{
int w=img->width;
int h=img->height;
IplImage* dst=cvCreateImage(cvSize(w,h),8,3);
for(int j=0;j<w;++j)
{
for(int i=0;i<h;++i)
{
int h=CV_IMAGE_ELEM(img,uchar,i,j*3+0);
int s=CV_IMAGE_ELEM(img,uchar,i,j*3+1);
int v=CV_IMAGE_ELEM(img,uchar,i,j*3+2);
int c=(double)v*s/255;
double hh=(double)h*2/60;
double x=c*(1-abs(fmod(hh,2)-1));
int r,g,b;
if(0<=hh&&hh<1)
{
r=c;g=x;b=0;
}
else if(1<=hh&hh<2)
{
r=x;g=c;b=0;
}
else if(2<=hh&&hh<3)
{
r=0;g=c;b=x;
}
else if(3<=hh&&hh<4)
{
r=0;g=x;b=c;
}
else if(4<=hh&&hh<5)
{
r=x;g=0;b=c;
}
else
{
r=c;g=0;b=x;
}
int m=v-c;
CV_IMAGE_ELEM(dst,uchar,i,j*3+0)=b+m;
CV_IMAGE_ELEM(dst,uchar,i,j*3+1)=g+m;
CV_IMAGE_ELEM(dst,uchar,i,j*3+2)=r+m;
}
}
return dst;
}
int main( int argc, char** argv )
{
IplImage* img=cvLoadImage("lena.jpg",1);
IplImage* hsv=kcvRGB2HSV(img);
IplImage* hsv2=cvCreateImage(cvGetSize(img),8,3);
cvCvtColor(img,hsv2,CV_BGR2HSV);
// 注意不能是下面的语句
// cvCvtColor(img,hsv2,CV_RGB2HSV);
IplImage* dst=kcvHSV2RGB(hsv);
IplImage* dst2=cvCreateImage(cvGetSize(img),8,3);
cvCvtColor(hsv2,dst2,CV_HSV2BGR);
// 注意不能是下面的语句
// cvCvtColor(hsv2,dst2,CV_HSV2RGB);
cvNamedWindow("img");
cvNamedWindow("hsv");
cvNamedWindow("hsv2");
cvNamedWindow("dst");
cvNamedWindow("dst2");
cvShowImage("img",img);
cvShowImage("hsv",hsv);
cvShowImage("hsv2",hsv2);
cvShowImage("dst",dst);
cvShowImage("dst2",dst2);
cvWaitKey(0);
cvDestroyAllWindows();
cvReleaseImage(&img);
cvReleaseImage(&hsv);
cvReleaseImage(&hsv2);
cvReleaseImage(&dst);
cvReleaseImage(&dst2);
return 0;
}
代码二:
[cpp] view
plaincopy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/9e12f1d3e499fc949c886e7c9e0484f9)
//====================================================================
// 作者 : quarryman
// 邮箱 : quarrying{at}qq.com
// 主页 : http://blog.csdn.net/quarryman
// 日期 : 2013年12月22日
// 描述 : HSV颜色盘
//====================================================================
#include <cv.h>
#include <highgui.h>
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
double module(CvPoint pt)
{
return sqrt((double)pt.x*pt.x+pt.y*pt.y);
}
double distance(CvPoint pt1,CvPoint pt2)
{
int dx=pt1.x-pt2.x;
int dy=pt1.y-pt2.y;
return sqrt((double)dx*dx+dy*dy);
}
double cross(CvPoint pt1,CvPoint pt2)
{
return pt1.x*pt2.x+pt1.y*pt2.y;
}
double angle(CvPoint pt1,CvPoint pt2)
{
return acos(cross(pt1,pt2)/(module(pt1)*module(pt2)+DBL_EPSILON));
}
// p和c其中一个是圆心
int inCircle(CvPoint p, CvPoint c, int r)
{
int dx=p.x-c.x;
int dy=p.y-c.y;
return dx*dx+dy*dy<=r*r?1:0;
}
IplImage* createPlate(int radius)
{
IplImage* img=cvCreateImage(cvSize(radius<<1,radius<<1),8,3);
cvSet(img,cvScalar(0,0,255));
int w=img->width;
int h=img->height;
int cx=w>>1;
int cy=h>>1;
CvPoint pt1=cvPoint(cx,0);
for(int j=0;j<w;++j)
{
for(int i=0;i<h;++i)
{
CvPoint pt2=cvPoint(j-cx,i-cy);
if(inCircle(cvPoint(0,0),pt2,radius))
{
int theta=angle(pt1,pt2)*180/3.1415926;
if(i>cx)
{
theta=-theta+360;
}
CV_IMAGE_ELEM(img,uchar,i,j*3+0)=theta/2;
CV_IMAGE_ELEM(img,uchar,i,j*3+1)=module(pt2)/cx*255;
CV_IMAGE_ELEM(img,uchar,i,j*3+2)=255;
}
}
}
IplImage* dst=cvCreateImage(cvGetSize(img),8,3);
cvCvtColor(img,dst,CV_HSV2BGR);
cvReleaseImage(&img);
return dst;
}
int main( int argc, char** argv )
{
IplImage* img=createPlate(300);
cvNamedWindow("img");
cvShowImage("img",img);
cvWaitKey(0);
cvDestroyAllWindows();
cvReleaseImage(&img);
return 0;
}
效果图如下:
HSV的介绍请参见维基百科:http://en.wikipedia.org/wiki/HSL_and_HSV,与其类似的颜色空间还有HSL(或称HLS)和HSI。本文有两则代码,代码一,自实现了RGB颜色空间与HSV颜色空间之间的转换,并与OpenCV中的cvCvtColor进行了比较;代码二,实现了一个HSV颜色盘。
代码一:
[cpp] view
plaincopy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
//====================================================================
// 作者 : quarryman
// 邮箱 : quarrying{at}qq.com
// 主页 : http://blog.csdn.net/quarryman
// 日期 : 2013年12月22日
// 描述 : RGB颜色空间与HSV颜色空间之间的转换
//====================================================================
#include <cv.h>
#include <highgui.h>
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
IplImage* kcvRGB2HSV(IplImage* img)
{
int w=img->width;
int h=img->height;
IplImage* dst=cvCreateImage(cvSize(w,h),8,3);
for(int j=0;j<w;++j)
{
for(int i=0;i<h;++i)
{
int b=CV_IMAGE_ELEM(img,uchar,i,j*3+0);
int g=CV_IMAGE_ELEM(img,uchar,i,j*3+1);
int r=CV_IMAGE_ELEM(img,uchar,i,j*3+2);
int maxval=max(b,max(g,r));
int minval=min(b,min(g,r));
int v=maxval;
double diff=maxval-minval;
int s=diff*255/(v+DBL_EPSILON);
double h=0;
diff=60/(diff+DBL_EPSILON);
if(v==r)
{
h=(g-b)*diff;
}
else if(v==g)
{
h=(b-r)*diff+120.f;
}
else
{
h=(r-g)*diff+240.f;
}
if( h<0)
{
h+=360.f;
}
CV_IMAGE_ELEM(dst,uchar,i,j*3+0)=h/2;
CV_IMAGE_ELEM(dst,uchar,i,j*3+1)=s;
CV_IMAGE_ELEM(dst,uchar,i,j*3+2)=v;
}
}
return dst;
}
IplImage* kcvHSV2RGB(IplImage* img)
{
int w=img->width;
int h=img->height;
IplImage* dst=cvCreateImage(cvSize(w,h),8,3);
for(int j=0;j<w;++j)
{
for(int i=0;i<h;++i)
{
int h=CV_IMAGE_ELEM(img,uchar,i,j*3+0);
int s=CV_IMAGE_ELEM(img,uchar,i,j*3+1);
int v=CV_IMAGE_ELEM(img,uchar,i,j*3+2);
int c=(double)v*s/255;
double hh=(double)h*2/60;
double x=c*(1-abs(fmod(hh,2)-1));
int r,g,b;
if(0<=hh&&hh<1)
{
r=c;g=x;b=0;
}
else if(1<=hh&hh<2)
{
r=x;g=c;b=0;
}
else if(2<=hh&&hh<3)
{
r=0;g=c;b=x;
}
else if(3<=hh&&hh<4)
{
r=0;g=x;b=c;
}
else if(4<=hh&&hh<5)
{
r=x;g=0;b=c;
}
else
{
r=c;g=0;b=x;
}
int m=v-c;
CV_IMAGE_ELEM(dst,uchar,i,j*3+0)=b+m;
CV_IMAGE_ELEM(dst,uchar,i,j*3+1)=g+m;
CV_IMAGE_ELEM(dst,uchar,i,j*3+2)=r+m;
}
}
return dst;
}
int main( int argc, char** argv )
{
IplImage* img=cvLoadImage("lena.jpg",1);
IplImage* hsv=kcvRGB2HSV(img);
IplImage* hsv2=cvCreateImage(cvGetSize(img),8,3);
cvCvtColor(img,hsv2,CV_BGR2HSV);
// 注意不能是下面的语句
// cvCvtColor(img,hsv2,CV_RGB2HSV);
IplImage* dst=kcvHSV2RGB(hsv);
IplImage* dst2=cvCreateImage(cvGetSize(img),8,3);
cvCvtColor(hsv2,dst2,CV_HSV2BGR);
// 注意不能是下面的语句
// cvCvtColor(hsv2,dst2,CV_HSV2RGB);
cvNamedWindow("img");
cvNamedWindow("hsv");
cvNamedWindow("hsv2");
cvNamedWindow("dst");
cvNamedWindow("dst2");
cvShowImage("img",img);
cvShowImage("hsv",hsv);
cvShowImage("hsv2",hsv2);
cvShowImage("dst",dst);
cvShowImage("dst2",dst2);
cvWaitKey(0);
cvDestroyAllWindows();
cvReleaseImage(&img);
cvReleaseImage(&hsv);
cvReleaseImage(&hsv2);
cvReleaseImage(&dst);
cvReleaseImage(&dst2);
return 0;
}
代码二:
[cpp] view
plaincopy
![](https://oscdn.geek-share.com/Uploads/Images/Content/201611/a7c8e286f463007e2a900848b93dd72c.png)
//====================================================================
// 作者 : quarryman
// 邮箱 : quarrying{at}qq.com
// 主页 : http://blog.csdn.net/quarryman
// 日期 : 2013年12月22日
// 描述 : HSV颜色盘
//====================================================================
#include <cv.h>
#include <highgui.h>
#define max(a,b) (((a)>(b))?(a):(b))
#define min(a,b) (((a)<(b))?(a):(b))
double module(CvPoint pt)
{
return sqrt((double)pt.x*pt.x+pt.y*pt.y);
}
double distance(CvPoint pt1,CvPoint pt2)
{
int dx=pt1.x-pt2.x;
int dy=pt1.y-pt2.y;
return sqrt((double)dx*dx+dy*dy);
}
double cross(CvPoint pt1,CvPoint pt2)
{
return pt1.x*pt2.x+pt1.y*pt2.y;
}
double angle(CvPoint pt1,CvPoint pt2)
{
return acos(cross(pt1,pt2)/(module(pt1)*module(pt2)+DBL_EPSILON));
}
// p和c其中一个是圆心
int inCircle(CvPoint p, CvPoint c, int r)
{
int dx=p.x-c.x;
int dy=p.y-c.y;
return dx*dx+dy*dy<=r*r?1:0;
}
IplImage* createPlate(int radius)
{
IplImage* img=cvCreateImage(cvSize(radius<<1,radius<<1),8,3);
cvSet(img,cvScalar(0,0,255));
int w=img->width;
int h=img->height;
int cx=w>>1;
int cy=h>>1;
CvPoint pt1=cvPoint(cx,0);
for(int j=0;j<w;++j)
{
for(int i=0;i<h;++i)
{
CvPoint pt2=cvPoint(j-cx,i-cy);
if(inCircle(cvPoint(0,0),pt2,radius))
{
int theta=angle(pt1,pt2)*180/3.1415926;
if(i>cx)
{
theta=-theta+360;
}
CV_IMAGE_ELEM(img,uchar,i,j*3+0)=theta/2;
CV_IMAGE_ELEM(img,uchar,i,j*3+1)=module(pt2)/cx*255;
CV_IMAGE_ELEM(img,uchar,i,j*3+2)=255;
}
}
}
IplImage* dst=cvCreateImage(cvGetSize(img),8,3);
cvCvtColor(img,dst,CV_HSV2BGR);
cvReleaseImage(&img);
return dst;
}
int main( int argc, char** argv )
{
IplImage* img=createPlate(300);
cvNamedWindow("img");
cvShowImage("img",img);
cvWaitKey(0);
cvDestroyAllWindows();
cvReleaseImage(&img);
return 0;
}
效果图如下:
相关文章推荐
- ios--OpenCV--RGB与HSV颜色空间的转换
- 使用Opencv将RGB颜色空间转换到HSV颜色空间/灰度图
- OpenCV实现RGB与YUV的转换
- opencv,图像处理,rgb转换为hsv空间
- 【OpenCV】 RGB和CIEXYZ颜色空间的转换及相关优化。
- Linux(V4L2驱动)下获得Opencv摄像头属性(图像输出格式和是否发生往RGB的转换)的方法
- YUV422P(UYVY)转换到RGB , 基于Opencv2.4.10
- 【OpenCV学习笔记】3.1 RGB图像转换为HSI图像
- OpenCV读取的图片从BGR转换为RGB
- OpenCV中RGB和HSV转换的问题
- 【OpenCV】颜色空间RGB与HSV(HSL)的转换
- OpenCV提供的转换函数实现YUV到RGB的转换
- RGB彩色图像与灰度图像转换 opencv实现 代码及分析
- 基于opencv的YUV图像转换为RGB图像
- HSV颜色空间理解及RGB图像转换到HSV空间的方法(数据集扩充)
- RGB到HSV颜色空间的转换
- 【OpenCV】颜色空间RGB与HSV(HSL)的转换
- YUV格式转换为RGB(基于opencv)
- OpenCV实现RGB颜色空间和HSI颜色空间的相互转换
- RGB到HSV颜色空间的转换