ios--OpenCV--RGB与HSV颜色空间的转换

原文摘自:http://blog.csdn.net/quarryman/article/details/17474861

HSV的介绍请参见维基百科:http://en.wikipedia.org/wiki/HSL_and_HSV,与其类似的颜色空间还有HSL(或称HLS)和HSI。本文有两则代码,代码一,自实现了RGB颜色空间与HSV颜色空间之间的转换,并与OpenCV中的cvCvtColor进行了比较;代码二,实现了一个HSV颜色盘。

代码一:

-(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 max1 = (g>r)?g:r;
            int maxval = (b>max1)?b:max1;
            int min1 = (g<r)?g:r;
            int minval = (b<min1)?b:min1;
            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;
}

代码二: 

[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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值