OpenCV之RGB与HSV颜色空间的转换

关于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 plain copy 在CODE上查看代码片 派生到我的代码片
  1. //====================================================================      
  2. // 作者   : quarryman      
  3. // 邮箱   : quarrying{at}qq.com      
  4. // 主页   : http://blog.csdn.net/quarryman      
  5. // 日期   : 2013年12月22日      
  6. // 描述   : RGB颜色空间与HSV颜色空间之间的转换     
  7. //====================================================================    
  8. #include <cv.h>  
  9. #include <highgui.h>  
  10. #define max(a,b)  (((a)>(b))?(a):(b))  
  11. #define min(a,b)  (((a)<(b))?(a):(b))  
  12.   
  13. IplImage* kcvRGB2HSV(IplImage* img)  
  14. {  
  15.     int w=img->width;  
  16.     int h=img->height;  
  17.     IplImage* dst=cvCreateImage(cvSize(w,h),8,3);  
  18.     for(int j=0;j<w;++j)  
  19.     {  
  20.         for(int i=0;i<h;++i)  
  21.         {  
  22.             int b=CV_IMAGE_ELEM(img,uchar,i,j*3+0);  
  23.             int g=CV_IMAGE_ELEM(img,uchar,i,j*3+1);  
  24.             int r=CV_IMAGE_ELEM(img,uchar,i,j*3+2);  
  25.             int maxval=max(b,max(g,r));  
  26.             int minval=min(b,min(g,r));  
  27.             int v=maxval;  
  28.             double diff=maxval-minval;  
  29.             int s=diff*255/(v+DBL_EPSILON);  
  30.               
  31.             double h=0;  
  32.             diff=60/(diff+DBL_EPSILON);  
  33.             if(v==r)  
  34.             {  
  35.                 h=(g-b)*diff;  
  36.             }  
  37.             else if(v==g)  
  38.             {  
  39.                 h=(b-r)*diff+120.f;  
  40.             }  
  41.             else  
  42.             {  
  43.                 h=(r-g)*diff+240.f;  
  44.             }  
  45.             if( h<0)  
  46.             {  
  47.                 h+=360.f;  
  48.             }  
  49.             CV_IMAGE_ELEM(dst,uchar,i,j*3+0)=h/2;  
  50.             CV_IMAGE_ELEM(dst,uchar,i,j*3+1)=s;  
  51.             CV_IMAGE_ELEM(dst,uchar,i,j*3+2)=v;  
  52.         }  
  53.     }  
  54.     return dst;  
  55. }  
  56.   
  57. IplImage* kcvHSV2RGB(IplImage* img)  
  58. {  
  59.     int w=img->width;  
  60.     int h=img->height;  
  61.     IplImage* dst=cvCreateImage(cvSize(w,h),8,3);  
  62.     for(int j=0;j<w;++j)  
  63.     {  
  64.         for(int i=0;i<h;++i)  
  65.         {  
  66.             int h=CV_IMAGE_ELEM(img,uchar,i,j*3+0);  
  67.             int s=CV_IMAGE_ELEM(img,uchar,i,j*3+1);  
  68.             int v=CV_IMAGE_ELEM(img,uchar,i,j*3+2);  
  69.             int c=(double)v*s/255;  
  70.             double hh=(double)h*2/60;  
  71.             double x=c*(1-abs(fmod(hh,2)-1));  
  72.             int r,g,b;  
  73.             if(0<=hh&&hh<1)  
  74.             {  
  75.                 r=c;g=x;b=0;  
  76.             }  
  77.             else if(1<=hh&hh<2)  
  78.             {  
  79.                 r=x;g=c;b=0;  
  80.             }  
  81.             else if(2<=hh&&hh<3)  
  82.             {  
  83.                 r=0;g=c;b=x;  
  84.             }  
  85.             else if(3<=hh&&hh<4)  
  86.             {  
  87.                 r=0;g=x;b=c;  
  88.             }  
  89.             else if(4<=hh&&hh<5)  
  90.             {  
  91.                 r=x;g=0;b=c;  
  92.             }  
  93.             else  
  94.             {  
  95.                 r=c;g=0;b=x;  
  96.             }  
  97.             int m=v-c;  
  98.             CV_IMAGE_ELEM(dst,uchar,i,j*3+0)=b+m;  
  99.             CV_IMAGE_ELEM(dst,uchar,i,j*3+1)=g+m;  
  100.             CV_IMAGE_ELEM(dst,uchar,i,j*3+2)=r+m;  
  101.         }  
  102.     }  
  103.     return dst;  
  104. }  
  105.   
  106. int main( int argc, char** argv )  
  107. {  
  108.     IplImage* img=cvLoadImage("lena.jpg",1);  
  109.     IplImage* hsv=kcvRGB2HSV(img);  
  110.     IplImage* hsv2=cvCreateImage(cvGetSize(img),8,3);  
  111.     cvCvtColor(img,hsv2,CV_BGR2HSV);  
  112.     // 注意不能是下面的语句  
  113.     // cvCvtColor(img,hsv2,CV_RGB2HSV);  
  114.     IplImage* dst=kcvHSV2RGB(hsv);  
  115.     IplImage* dst2=cvCreateImage(cvGetSize(img),8,3);  
  116.     cvCvtColor(hsv2,dst2,CV_HSV2BGR);  
  117.     // 注意不能是下面的语句  
  118.     // cvCvtColor(hsv2,dst2,CV_HSV2RGB);  
  119.   
  120.     cvNamedWindow("img");  
  121.     cvNamedWindow("hsv");  
  122.     cvNamedWindow("hsv2");  
  123.     cvNamedWindow("dst");  
  124.     cvNamedWindow("dst2");  
  125.     cvShowImage("img",img);  
  126.     cvShowImage("hsv",hsv);  
  127.     cvShowImage("hsv2",hsv2);  
  128.     cvShowImage("dst",dst);  
  129.     cvShowImage("dst2",dst2);  
  130.     cvWaitKey(0);  
  131.     cvDestroyAllWindows();  
  132.     cvReleaseImage(&img);  
  133.     cvReleaseImage(&hsv);  
  134.     cvReleaseImage(&hsv2);  
  135.     cvReleaseImage(&dst);  
  136.     cvReleaseImage(&dst2);  
  137.     return 0;  
  138. }  

代码二: 

[cpp]  view plain copy 在CODE上查看代码片 派生到我的代码片
  1. //====================================================================      
  2. // 作者   : quarryman      
  3. // 邮箱   : quarrying{at}qq.com      
  4. // 主页   : http://blog.csdn.net/quarryman      
  5. // 日期   : 2013年12月22日      
  6. // 描述   : HSV颜色盘     
  7. //====================================================================  
  8. #include <cv.h>  
  9. #include <highgui.h>  
  10. #define max(a,b)  (((a)>(b))?(a):(b))  
  11. #define min(a,b)  (((a)<(b))?(a):(b))  
  12.   
  13. double module(CvPoint pt)  
  14. {  
  15.     return sqrt((double)pt.x*pt.x+pt.y*pt.y);  
  16. }  
  17.   
  18. double distance(CvPoint pt1,CvPoint pt2)  
  19. {  
  20.     int dx=pt1.x-pt2.x;  
  21.     int dy=pt1.y-pt2.y;  
  22.     return sqrt((double)dx*dx+dy*dy);  
  23. }  
  24.   
  25. double cross(CvPoint pt1,CvPoint pt2)  
  26. {  
  27.     return pt1.x*pt2.x+pt1.y*pt2.y;  
  28. }  
  29.   
  30. double angle(CvPoint pt1,CvPoint pt2)  
  31. {  
  32.     return acos(cross(pt1,pt2)/(module(pt1)*module(pt2)+DBL_EPSILON));  
  33. }  
  34.   
  35. // p和c其中一个是圆心  
  36. int inCircle(CvPoint p, CvPoint c, int r)  
  37. {  
  38.     int dx=p.x-c.x;  
  39.     int dy=p.y-c.y;  
  40.     return dx*dx+dy*dy<=r*r?1:0;  
  41. }  
  42.   
  43. IplImage* createPlate(int radius)  
  44. {  
  45.     IplImage* img=cvCreateImage(cvSize(radius<<1,radius<<1),8,3);  
  46.     cvSet(img,cvScalar(0,0,255));  
  47.     int w=img->width;  
  48.     int h=img->height;  
  49.     int cx=w>>1;  
  50.     int cy=h>>1;  
  51.     CvPoint pt1=cvPoint(cx,0);  
  52.   
  53.     for(int j=0;j<w;++j)  
  54.     {  
  55.         for(int i=0;i<h;++i)  
  56.         {  
  57.             CvPoint pt2=cvPoint(j-cx,i-cy);  
  58.             if(inCircle(cvPoint(0,0),pt2,radius))  
  59.             {  
  60.                 int theta=angle(pt1,pt2)*180/3.1415926;  
  61.                 if(i>cx)  
  62.                 {  
  63.                     theta=-theta+360;  
  64.                 }  
  65.                 CV_IMAGE_ELEM(img,uchar,i,j*3+0)=theta/2;  
  66.                 CV_IMAGE_ELEM(img,uchar,i,j*3+1)=module(pt2)/cx*255;  
  67.                 CV_IMAGE_ELEM(img,uchar,i,j*3+2)=255;  
  68.             }  
  69.         }  
  70.     }  
  71.     IplImage* dst=cvCreateImage(cvGetSize(img),8,3);  
  72.     cvCvtColor(img,dst,CV_HSV2BGR);  
  73.     cvReleaseImage(&img);  
  74.     return dst;  
  75. }  
  76.   
  77. int main( int argc, char** argv )  
  78. {  
  79.     IplImage* img=createPlate(300);  
  80.     cvNamedWindow("img");  
  81.     cvShowImage("img",img);  
  82.     cvWaitKey(0);  
  83.     cvDestroyAllWindows();  
  84.     cvReleaseImage(&img);  
  85.     return 0;  
  86. }  

效果图如下:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值