OPENCV学习笔记3-6_RGB->HSV

本文介绍了HSV颜色空间的基本概念,包括色调、饱和度和明度的定义,并提供了RGB到HSV颜色空间转换的公式及示例代码。HSV颜色空间因其面向用户的特点,在图像处理任务如目标检测中有广泛应用。

1.1 HSV 

    HSV(Hue, Saturation, Value)是根据颜色的直观特性由A. R. Smith在1978年创建的一种颜色空间, 也称六角锥体模型(Hexcone Model)。RGB颜色模型都是面向硬件的,而HSV颜色模型是面向用户的。

    色调H

    色调表示主色,使用的颜色名称(例如绿色、黄色和红色)就对应了不同的色调值,取值范围为0°~360°,从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°。它们的补色是:黄色为60°,青色为180°,品红为300°。

   饱和度S

    饱和度表示颜色接近光谱色的程度(颜色的鲜艳程度)。一种颜色,可以看成是某种光谱色与白色混合的结果。其中光谱色所占的比例愈大,颜色接近光谱色的程度就愈高,颜色的饱和度也就愈高。饱和度高,颜色则深而艳。光谱色的白光成分为0,饱和度达到最高。通常取值范围为0%~100%,值越大,颜色越饱和。

  明度V

    明度表示颜色明亮的程度,对于光源色,明度值与发光体的光亮度有关;对于物体色,此值和物体的透射比或反射比有关。通常取值范围为0%(黑)到100%(白)。

HSV色彩空间通常用一个圆锥体来表示,圆锥体内部每个点代表一种特定的颜色。角度位置表示颜色的色调,到中轴

线的距离表示饱和度,高度表示亮度。圆锥体的顶点表示黑色,它的色调和饱和度是没有意义的。

    

    通过把图像的通道分割到三个独立的图像中,可以直观地看到每一种HSV组件。因为处理的是8位图像,OpenCV会把通道值的范围重新调节为0~255(色调除外,色调的范围被调节为0~180)。

    在对特定物体做初步检测时,颜色信息非常有用。例如在辅助驾驶程序中检测路标,就要凭借标准路标的颜色快速地提取出可能是路标的信息。另一个例子是检测皮肤的颜色,检测到的皮肤区域可作为图像中有人存在的标志。在手势识别中经常使用这个方法,用肤色检测来确定手的位置。

 1.2 RGB to HSV conversion formula(转换公式)

    The R,G,B values are divided by 255 to change the range from 0..255 to 0..1:

    

1.3 Example Code

void Rgb2Hsv( float R, float G, float B, float & H, float & S, float &V )
{
/*
 * r,g,b values are from 0 to 1
 * h = [0,360], s = [0,1], v = [0,1]
 * if s == 0, then h = -1 (undefined)
 */
    float min, max, delta, tmp;
    tmp = min( R, G );
    min = min( tmp, B );
    tmp = max( R, G );
    max = max( tmp, B );
    V   = max;                  /* v */
    delta   = max - min;
    if ( max != 0 )
        S = delta / max;        /* s */
    else{
/* r = g = b = 0 // s = 0, v is undefined */
        S   = 0;
        H   = UNDEFINEDCOLOR;
        return;
    }
    if ( R == max )
        H = (G - B) / delta;            /* between yellow & magenta */
    else if ( G == max )
        H = 2 + (B - R) / delta;        /* between cyan & yellow */
    else
        H = 4 + (R - G) / delta;        /* between magenta & cyan */
    H *= 60;                                /* degrees */
    if ( H < 0 )
        H += 360;
}

     You can also try this code without floats (faster but less accurate):

typedef struct RgbColor
{
    unsigned char r;
    unsigned char g;
    unsigned char b;
} RgbColor;

typedef struct HsvColor
{
    unsigned char h;
    unsigned char s;
    unsigned char v;
} HsvColor;
HsvColor RgbToHsv(RgbColor rgb)
{
    HsvColor hsv;
    unsigned char rgbMin, rgbMax;

    rgbMin = rgb.r < rgb.g ? (rgb.r < rgb.b ? rgb.r : rgb.b) : (rgb.g < rgb.b ? rgb.g : rgb.b);
    rgbMax = rgb.r > rgb.g ? (rgb.r > rgb.b ? rgb.r : rgb.b) : (rgb.g > rgb.b ? rgb.g : rgb.b);

    hsv.v = rgbMax;
    if (hsv.v == 0)
    {
        hsv.h = 0;
        hsv.s = 0;
        return hsv;
    }

    hsv.s = 255 * long(rgbMax - rgbMin) / hsv.v;
    if (hsv.s == 0)
    {
        hsv.h = 0;
        return hsv;
    }

    if (rgbMax == rgb.r)
        hsv.h = 0 + 43 * (rgb.g - rgb.b) / (rgbMax - rgbMin);   //43 1;85 2; 6; 255 ;
    else if (rgbMax == rgb.g)
        hsv.h = 85 + 43 * (rgb.b - rgb.r) / (rgbMax - rgbMin);
    else
        hsv.h = 171 + 43 * (rgb.r - rgb.g) / (rgbMax - rgbMin);

    return hsv;
}

     or use opencv,

Mat img_hsv,img_rgb;
img_rgb = imread("pic.png",1);
cvtColor(img_rgb,img_hsv,CV_RGB2HSV);
namedWindow("win1", CV_WINDOW_AUTOSIZE);
imshow("win1", img_hsv);
// split the 3 channels into 3 images
//std::vector<cv::Mat> channels;
//cv::split(hsv, channels);
// channels[0] is the Hue
// channels[1] is the Saturation
// channels[2] is the Value

 

转载于:https://www.cnblogs.com/yunfung/p/7614259.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值