切脉时为什么是动脉:关于opencv中的颜色模型转换之cvCvtColor

来源:百度文库 编辑:偶看新闻 时间:2024/04/27 20:02:31
    cvCvtColor(rgb_im,hsv_im,CV_BGR2HSV)针对8bit和32bit使用不同的计算公式,
  •     如果是8bit ,HSV的范围是:H(0-180)  S(0-255) V(0-255)
    计算公式为:                            1、 V=max(R,G,B)                            2、S=(V-min(R,G,B))*255/V if V!=0, 0 otherwise
                                    代码中使用的公式:s = diff * div_table[v] >> hsv_shift; (在这里为了避免除法运算,将 [255/v << hsv_shift] 存在了div_table中,计算后再右移回去)                            3、因为是8u类型,H不可能取值到360,故使用下面的公式将h计算到0-180范围内:                                   h = (vr & (g - b)) +(~vr & ((vg & (b - r + 2 * diff)) + ((~vg) & (r - g + 4 * diff))));
                                   h = ((h * div_table[diff] * 15 + (1 << (hsv_shift + 6))) >> (7 + hsv_shift))+ (h < 0 ? 30*6 : 0); 
  •     如果是32bit,需要在传入前将像素值归一化到0-1之间,此时HSV的范围是:H(0-360)  S(0-1) V(0-1)
    计算公式为:                      1、V=max(R,G,B)                      2、S = (V-min(R,G,B)) / (float)(fabs(v) + FLT_EPSILON); // #define FLT_EPSILON 1.192092896e-07F,这样避免了V==0情况的判断                      3、H                         vdiff=  (float)(60./((V-min(R,G,B)) + FLT_EPSILON));                         if V==R  h = (g - b)*vdiff;                         if V==G  h = (b - r)*vdiff + 120.f;                         if V==R  h = (r - g)*diff + 240.f;                         if( h < 0 ) h += 360.f; 
  • 而opencv的手册上写的转换公式如下:
    V=max(R,G,B)
    S=(V-min(R,G,B))*255/V if V!=0, 0 otherwise

    (G - B)*60/S, if V=R
    H= 180+(B - R)*60/S, if V=G
    240+(R - G)*60/S, if V=B

    if H<0 then H=H+360
图像精度转换cvConvertScale() 通常我们获取的图像深的为IPL_DEPTH_8U,而上述hsv_im已超出该范围。因此我们定义hsv_im的深度为IPL_DEPTH_32F,而源图像为IPL_DEPTH_8U,如果直接调用函数cvCvtColor会出项输入不匹配的错处,因此要将源图像转换到IPL_DEPTH_32F深度,并归一化像素值。这一步使用cvConvertScale(hsv_im,hsv_im_float,1/255),然后调用cvCvtColor(hsv_im_float,hsv_im,CV_BGR2HSV)即可得到正确的HSV值,但HSV值与matlab有一定误差,原因不明。