主要是一些算法基础函数,千里之行始于足下,记下这些基础函数迟早会有用武之地。
我们在做一些算法分析时候可以根据不同的目的转换不同的颜色空间,例如:分析目标颜色时候可以转换成RGB颜色空间,
分析亮度饱和度就要转换成HSV颜色空间等等。
#define RGB565_R(p) ((((p) & 0xF800) >> 11) << 3)
#define RGB565_G(p) ((((p) & 0x7E0 ) >> 5) << 2)
#define RGB565_B(p) ( ((p) & 0x1F ) << 3)
#define MAKE_RGB565(r,g,b) ((((r) >> 3) << 11) | (((g) >> 2) << 5) | ((b) >> 3))
#define RGBA_A(p) (((p) & 0xFF000000) >> 24)
#define RGBA_R(p) (((p) & 0x00FF0000) >> 16)
#define RGBA_G(p) (((p) & 0x0000FF00) >> 8)
#define RGBA_B(p) ((p) & 0x000000FF)
#define MAKE_RGBA(r,g,b,a) (((a) << 24) | ((r) << 16) | ((g) << 8) | (b))
inline byte RGB2GRAY(CvScalar &rgb)
{
float max = MAX(rgb.val[0],MAX(rgb.val[1],rgb.val[2]));
float min = MIN(rgb.val[0],MIN(rgb.val[1],rgb.val[2]));
float mid = MIN(rgb.val[0],MAX(rgb.val[1],rgb.val[2]));
float ret = max * 0.3 + mid * 0.59 + min * 0.11;
return (byte)ret;
}
inline CvScalar RGB2HSV(CvScalar &rgb)
{
double maxc = MAX(rgb.val[2],MAX(rgb.val[1],rgb.val[0]));
double minc = MIN(rgb.val[2],MIN(rgb.val[1],rgb.val[0]));
CvScalar hsv = CV_RGB(0,0,0);
if (maxc > 0)
{
hsv.val[2] = maxc;
hsv.val[1] = (maxc - minc)/maxc;
double delta = maxc - minc;
if ((maxc - rgb.val[2]) < FLOATPRECISION)
{
hsv.val[0] = (rgb.val[1] - rgb.val[0])*60/delta;
}else if ((maxc - rgb.val[1]) < FLOATPRECISION)
{
hsv.val[0] = (rgb.val[0] - rgb.val[2])*60/delta + 180;
}else
{
hsv.val[0] = (rgb.val[2] - rgb.val[1])*60/delta + 240;
}
if (hsv.val[0] < 0)
{
hsv.val[0] += 360;
}
}
return hsv;
};
inline CvScalar RGB2HSVP20(CvScalar &rgb)
{
double maxc = MAX(rgb.val[2],MAX(rgb.val[1],rgb.val[0]));
double minc = MIN(rgb.val[2],MIN(rgb.val[1],rgb.val[0]));
CvScalar hsv = CV_RGB(0,0,0);
if (maxc > 0)
{
hsv.val[2] = maxc;
hsv.val[1] = (maxc - minc)/maxc;
double delta = maxc - minc;
if ((maxc - rgb.val[2]) < FLOATPRECISION)
{
hsv.val[0] = (rgb.val[1] - rgb.val[0])*60/delta;
}else if ((maxc - rgb.val[1]) < FLOATPRECISION)
{
hsv.val[0] = (rgb.val[0] - rgb.val[2])*60/delta + 180;
}else
{
hsv.val[0] = (rgb.val[2] - rgb.val[1])*60/delta + 240;
}
if (hsv.val[0] < 0)
{
hsv.val[0] += 360;
}
if (hsv.val[0] > 320)
{
hsv.val[0] -= 320;
}else
{
hsv.val[0] += 40;
}
}
return hsv;
};
inline CvScalar RGB2Lab(CvScalar &rgb)
{
double X = 0.433910 * rgb.val[2]/255 + 0.376220 * rgb.val[1]/255 + 0.189860 * rgb.val[0]/255;
double Y = 0.212649 * rgb.val[2]/255 + 0.715169 * rgb.val[1]/255 + 0.072182 * rgb.val[0]/255;
double Z = 0.017756 * rgb.val[2]/255 + 0.109478 * rgb.val[1]/255 + 0.872915 * rgb.val[0]/255;
CvScalar Lab;
if (Y > 0.008856)
{
Lab.val[0] = 116*Y/3;
}
else
{
Lab.val[0] = 903.3*Y;
}
double fx = 0;
if (X > 0.008856)
{
fx = X/3;
}
else
{
fx = 7.787*X+16/116;
}
double fy = 0;
if (Y > 0.008856)
{
fy = Y/3;
}
else
{
fy = 7.787*Y+16/116;
}
double fz = 0;
if (Z > 0.008856)
{
fz = Z/3;
}
else
{
fz = 7.787*Z+16/116;
}
Lab.val[1] = 500*(fx - fy);
Lab.val[2] = 200*(fy - fz);
return Lab;
};
inline CvScalar RGB2YCrCb(CvScalar &rgb)
{
CvScalar YCrCb = cvScalar(0,0,0);
YCrCb.val[0] = 0.299*rgb.val[2] + 0.587*rgb.val[1] + 0.114*rgb.val[0];
YCrCb.val[1]=(rgb.val[2]-YCrCb.val[0])*0.713;
YCrCb.val[2]=(rgb.val[0]-YCrCb.val[0])*0.564;
return YCrCb;
};