📄 cvcolor.c
字号:
113, 115, 116, 118, 119, 120, 122, 123, 125, 126, 128, 129, 130, 132, 133, 135,
136, 137, 139, 140, 142, 143, 145, 146, 147, 149, 150, 152, 153, 154, 156, 157,
159, 160, 162, 163, 164, 166, 167, 169, 170, 171, 173, 174, 176, 177, 179, 180,
181, 183, 184, 186, 187, 188, 190, 191, 193, 194, 196, 197, 198, 200, 201, 203,
204, 205, 207, 208, 210, 211, 213, 214, 215, 217, 218, 220, 221, 222, 224, 225,
227, 228, 230, 231, 232, 234, 235, 237, 238, 239, 241, 242, 244, 245, 247, 248,
249, 251, 252, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,
};
static CvStatus CV_STDCALL
icvBGRx2HSV_8u_CnC3R( const uchar* src, int srcstep, uchar* dst, int dststep,
CvSize size, int src_cn, int blue_idx )
{
const int hsv_shift = 12;
static const int div_table[] = {
0, 1044480, 522240, 348160, 261120, 208896, 174080, 149211,
130560, 116053, 104448, 94953, 87040, 80345, 74606, 69632,
65280, 61440, 58027, 54973, 52224, 49737, 47476, 45412,
43520, 41779, 40172, 38684, 37303, 36017, 34816, 33693,
32640, 31651, 30720, 29842, 29013, 28229, 27486, 26782,
26112, 25475, 24869, 24290, 23738, 23211, 22706, 22223,
21760, 21316, 20890, 20480, 20086, 19707, 19342, 18991,
18651, 18324, 18008, 17703, 17408, 17123, 16846, 16579,
16320, 16069, 15825, 15589, 15360, 15137, 14921, 14711,
14507, 14308, 14115, 13926, 13743, 13565, 13391, 13221,
13056, 12895, 12738, 12584, 12434, 12288, 12145, 12006,
11869, 11736, 11605, 11478, 11353, 11231, 11111, 10995,
10880, 10768, 10658, 10550, 10445, 10341, 10240, 10141,
10043, 9947, 9854, 9761, 9671, 9582, 9495, 9410,
9326, 9243, 9162, 9082, 9004, 8927, 8852, 8777,
8704, 8632, 8561, 8492, 8423, 8356, 8290, 8224,
8160, 8097, 8034, 7973, 7913, 7853, 7795, 7737,
7680, 7624, 7569, 7514, 7461, 7408, 7355, 7304,
7253, 7203, 7154, 7105, 7057, 7010, 6963, 6917,
6872, 6827, 6782, 6739, 6695, 6653, 6611, 6569,
6528, 6487, 6447, 6408, 6369, 6330, 6292, 6254,
6217, 6180, 6144, 6108, 6073, 6037, 6003, 5968,
5935, 5901, 5868, 5835, 5803, 5771, 5739, 5708,
5677, 5646, 5615, 5585, 5556, 5526, 5497, 5468,
5440, 5412, 5384, 5356, 5329, 5302, 5275, 5249,
5222, 5196, 5171, 5145, 5120, 5095, 5070, 5046,
5022, 4998, 4974, 4950, 4927, 4904, 4881, 4858,
4836, 4813, 4791, 4769, 4748, 4726, 4705, 4684,
4663, 4642, 4622, 4601, 4581, 4561, 4541, 4522,
4502, 4483, 4464, 4445, 4426, 4407, 4389, 4370,
4352, 4334, 4316, 4298, 4281, 4263, 4246, 4229,
4212, 4195, 4178, 4161, 4145, 4128, 4112, 4096
};
int i;
if( icvRGB2HSV_8u_C3R_p )
{
CvStatus status = icvBGRx2ABC_IPP_8u_CnC3R( src, srcstep, dst, dststep, size,
src_cn, blue_idx, icvRGB2HSV_8u_C3R_p );
if( status >= 0 )
{
size.width *= 3;
for( ; size.height--; dst += dststep )
{
for( i = 0; i <= size.width - 12; i += 12 )
{
uchar t0 = icvHue255To180[dst[i]], t1 = icvHue255To180[dst[i+3]];
dst[i] = t0; dst[i+3] = t1;
t0 = icvHue255To180[dst[i+6]]; t1 = icvHue255To180[dst[i+9]];
dst[i+6] = t0; dst[i+9] = t1;
}
for( ; i < size.width; i += 3 )
dst[i] = icvHue255To180[dst[i]];
}
}
return status;
}
srcstep -= size.width*src_cn;
size.width *= 3;
for( ; size.height--; src += srcstep, dst += dststep )
{
for( i = 0; i < size.width; i += 3, src += src_cn )
{
int b = (src)[blue_idx], g = (src)[1], r = (src)[2^blue_idx];
int h, s, v = b;
int vmin = b, diff;
int vr, vg;
CV_CALC_MAX_8U( v, g );
CV_CALC_MAX_8U( v, r );
CV_CALC_MIN_8U( vmin, g );
CV_CALC_MIN_8U( vmin, r );
diff = v - vmin;
vr = v == r ? -1 : 0;
vg = v == g ? -1 : 0;
s = diff * div_table[v] >> hsv_shift;
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);
dst[i] = (uchar)h;
dst[i+1] = (uchar)s;
dst[i+2] = (uchar)v;
}
}
return CV_OK;
}
static CvStatus CV_STDCALL
icvBGRx2HSV_32f_CnC3R( const float* src, int srcstep,
float* dst, int dststep,
CvSize size, int src_cn, int blue_idx )
{
int i;
srcstep /= sizeof(src[0]);
dststep /= sizeof(dst[0]);
srcstep -= size.width*src_cn;
size.width *= 3;
for( ; size.height--; src += srcstep, dst += dststep )
{
for( i = 0; i < size.width; i += 3, src += src_cn )
{
float b = src[blue_idx], g = src[1], r = src[2^blue_idx];
float h, s, v;
float vmin, diff;
v = vmin = r;
if( v < g ) v = g;
if( v < b ) v = b;
if( vmin > g ) vmin = g;
if( vmin > b ) vmin = b;
diff = v - vmin;
s = diff/(float)(fabs(v) + FLT_EPSILON);
diff = (float)(60./(diff + FLT_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;
dst[i] = h;
dst[i+1] = s;
dst[i+2] = v;
}
}
return CV_OK;
}
static CvStatus CV_STDCALL
icvHSV2BGRx_32f_C3CnR( const float* src, int srcstep, float* dst,
int dststep, CvSize size, int dst_cn, int blue_idx )
{
int i;
srcstep /= sizeof(src[0]);
dststep /= sizeof(dst[0]);
dststep -= size.width*dst_cn;
size.width *= 3;
for( ; size.height--; src += srcstep, dst += dststep )
{
for( i = 0; i < size.width; i += 3, dst += dst_cn )
{
float h = src[i], s = src[i+1], v = src[i+2];
float b, g, r;
if( s == 0 )
b = g = r = v;
else
{
static const int sector_data[][3]=
{{1,3,0}, {1,0,2}, {3,0,1}, {0,2,1}, {0,1,3}, {2,1,0}};
float tab[4];
int sector;
h *= 0.016666666666666666f; // h /= 60;
if( h < 0 )
do h += 6; while( h < 0 );
else if( h >= 6 )
do h -= 6; while( h >= 6 );
sector = cvFloor(h);
h -= sector;
tab[0] = v;
tab[1] = v*(1.f - s);
tab[2] = v*(1.f - s*h);
tab[3] = v*(1.f - s*(1.f - h));
b = tab[sector_data[sector][0]];
g = tab[sector_data[sector][1]];
r = tab[sector_data[sector][2]];
}
dst[blue_idx] = b;
dst[1] = g;
dst[blue_idx^2] = r;
if( dst_cn == 4 )
dst[3] = 0;
}
}
return CV_OK;
}
static CvStatus CV_STDCALL
icvHSV2BGRx_8u_C3CnR( const uchar* src, int srcstep, uchar* dst, int dststep,
CvSize size, int dst_cn, int blue_idx )
{
static const float pre_coeffs[] = { 2.f, 0.f, 0.0039215686274509803f, 0.f, 1.f, 0.f };
if( icvHSV2RGB_8u_C3R_p )
{
int block_size = MIN(1 << 14, size.width);
uchar* buffer;
int i, di, k;
CvStatus status = CV_OK;
buffer = (uchar*)cvStackAlloc( block_size*3*sizeof(buffer[0]) );
dststep -= size.width*dst_cn;
for( ; size.height--; src += srcstep, dst += dststep )
{
for( i = 0; i < size.width; i += block_size )
{
const uchar* src1 = src + i*3;
di = MIN(block_size, size.width - i);
for( k = 0; k < di*3; k += 3 )
{
uchar h = icvHue180To255[src1[k]];
uchar s = src1[k+1];
uchar v = src1[k+2];
buffer[k] = h;
buffer[k+1] = s;
buffer[k+2] = v;
}
status = icvHSV2RGB_8u_C3R_p( buffer, di*3,
buffer, di*3, cvSize(di,1) );
if( status < 0 )
return status;
for( k = 0; k < di*3; k += 3, dst += dst_cn )
{
uchar r = buffer[k];
uchar g = buffer[k+1];
uchar b = buffer[k+2];
dst[blue_idx] = b;
dst[1] = g;
dst[blue_idx^2] = r;
if( dst_cn == 4 )
dst[3] = 0;
}
}
}
return CV_OK;
}
return icvABC2BGRx_8u_C3CnR( src, srcstep, dst, dststep, size, dst_cn, blue_idx,
(CvColorCvtFunc2)icvHSV2BGRx_32f_C3CnR, pre_coeffs, 0 );
}
/****************************************************************************************\
* RGB <-> HLS *
\****************************************************************************************/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -