@@ -68,14 +68,6 @@ class CV_ColorCvtBaseTest : public cvtest::ArrayTest
68
68
// called from default implementation of convert_backward
69
69
virtual void convert_row_abc2bgr_32f_c3 ( const float * src_row, float * dst_row, int n );
70
70
71
- // called from default implementation of convert_backward
72
- // for cases of bit-exact functions
73
- virtual int convert_row_abc2bgr_8u_c3 ( const uchar* src_row, uchar* dst_row, int n, int cn );
74
-
75
- // called from default implementation of convert_forward
76
- // for cases of bit-exact functions
77
- virtual int convert_row_bgr2abc_8u_c3 (const uchar *src_row, uchar *dst_row, int n, int cn);
78
-
79
71
const char * fwd_code_str;
80
72
const char * inv_code_str;
81
73
@@ -237,23 +229,19 @@ void CV_ColorCvtBaseTest::convert_forward( const Mat& src, Mat& dst )
237
229
const uchar* src_row = src.ptr (i);
238
230
uchar* dst_row = dst.ptr (i);
239
231
240
- int processed = convert_row_bgr2abc_8u_c3 ( src_row, dst_row, cols, cn );
241
- if (processed != cols)
232
+ for ( j = 0 ; j < cols; j++ )
242
233
{
243
- for ( j = 0 ; j < cols; j++ )
244
- {
245
- src_buf[j*3 ] = src_row[j*cn + blue_idx]*c8u;
246
- src_buf[j*3 +1 ] = src_row[j*cn + 1 ]*c8u;
247
- src_buf[j*3 +2 ] = src_row[j*cn + (blue_idx^2 )]*c8u;
248
- }
234
+ src_buf[j*3 ] = src_row[j*cn + blue_idx]*c8u;
235
+ src_buf[j*3 +1 ] = src_row[j*cn + 1 ]*c8u;
236
+ src_buf[j*3 +2 ] = src_row[j*cn + (blue_idx^2 )]*c8u;
237
+ }
249
238
250
- convert_row_bgr2abc_32f_c3 ( src_buf, dst_buf, cols );
239
+ convert_row_bgr2abc_32f_c3 ( src_buf, dst_buf, cols );
251
240
252
- for ( j = 0 ; j < dst_cols_n; j++ )
253
- {
254
- int t = cvRound ( dst_buf[j] );
255
- dst_row[j] = saturate_cast<uchar>(t);
256
- }
241
+ for ( j = 0 ; j < dst_cols_n; j++ )
242
+ {
243
+ int t = cvRound ( dst_buf[j] );
244
+ dst_row[j] = saturate_cast<uchar>(t);
257
245
}
258
246
}
259
247
break ;
@@ -312,19 +300,6 @@ void CV_ColorCvtBaseTest::convert_row_abc2bgr_32f_c3( const float* /*src_row*/,
312
300
}
313
301
314
302
315
- int CV_ColorCvtBaseTest::convert_row_abc2bgr_8u_c3 (const uchar * /* src_row*/ ,
316
- uchar * /* dst_row*/ , int /* n*/ , int /* cn*/ )
317
- {
318
- return 0 ;
319
- }
320
-
321
-
322
- int CV_ColorCvtBaseTest::convert_row_bgr2abc_8u_c3 (const uchar* /* src_row*/ ,
323
- uchar* /* dst_row*/ , int /* n*/ , int /* cn*/ )
324
- {
325
- return 0 ;
326
- }
327
-
328
303
void CV_ColorCvtBaseTest::convert_backward ( const Mat& src, const Mat& dst, Mat& dst2 )
329
304
{
330
305
if ( custom_inv_transform )
@@ -349,26 +324,21 @@ void CV_ColorCvtBaseTest::convert_backward( const Mat& src, const Mat& dst, Mat&
349
324
const uchar* src_row = dst.ptr (i);
350
325
uchar* dst_row = dst2.ptr (i);
351
326
352
- int processed = convert_row_abc2bgr_8u_c3 (src_row, dst_row, dst_cols, cn);
353
-
354
- if (processed != dst_cols)
355
- {
356
- for ( j = 0 ; j < cols_n; j++ )
357
- src_buf[j] = src_row[j];
327
+ for ( j = 0 ; j < cols_n; j++ )
328
+ src_buf[j] = src_row[j];
358
329
359
- convert_row_abc2bgr_32f_c3 ( src_buf, dst_buf, dst_cols );
330
+ convert_row_abc2bgr_32f_c3 ( src_buf, dst_buf, dst_cols );
360
331
361
- for ( j = 0 ; j < dst_cols; j++ )
362
- {
363
- int b = cvRound ( dst_buf[j*3 ]*255 . );
364
- int g = cvRound ( dst_buf[j*3 +1 ]*255 . );
365
- int r = cvRound ( dst_buf[j*3 +2 ]*255 . );
366
- dst_row[j*cn + blue_idx] = saturate_cast<uchar>(b);
367
- dst_row[j*cn + 1 ] = saturate_cast<uchar>(g);
368
- dst_row[j*cn + (blue_idx^2 )] = saturate_cast<uchar>(r);
369
- if ( cn == 4 )
370
- dst_row[j*cn + 3 ] = 255 ;
371
- }
332
+ for ( j = 0 ; j < dst_cols; j++ )
333
+ {
334
+ int b = cvRound ( dst_buf[j*3 ]*255 . );
335
+ int g = cvRound ( dst_buf[j*3 +1 ]*255 . );
336
+ int r = cvRound ( dst_buf[j*3 +2 ]*255 . );
337
+ dst_row[j*cn + blue_idx] = saturate_cast<uchar>(b);
338
+ dst_row[j*cn + 1 ] = saturate_cast<uchar>(g);
339
+ dst_row[j*cn + (blue_idx^2 )] = saturate_cast<uchar>(r);
340
+ if ( cn == 4 )
341
+ dst_row[j*cn + 3 ] = 255 ;
372
342
}
373
343
}
374
344
break ;
@@ -1028,30 +998,7 @@ void CV_ColorXYZTest::convert_row_abc2bgr_32f_c3( const float* src_row, float* d
1028
998
1029
999
// // rgb <=> L*a*b*
1030
1000
1031
- // taken from color.cpp
1032
-
1033
- static ushort sRGBGammaTab_b [256 ], linearGammaTab_b[256 ];
1034
- enum { inv_gamma_shift = 12 , INV_GAMMA_TAB_SIZE = (1 << inv_gamma_shift) };
1035
- static ushort sRGBInvGammaTab_b [INV_GAMMA_TAB_SIZE], linearInvGammaTab_b[INV_GAMMA_TAB_SIZE];
1036
- #undef lab_shift
1037
- // #define lab_shift xyz_shift
1038
- #define lab_shift 12
1039
- #define gamma_shift 3
1040
- #define lab_shift2 (lab_shift + gamma_shift)
1041
- #define LAB_CBRT_TAB_SIZE_B (256 *3 /2 *(1 <<gamma_shift))
1042
- static ushort LabCbrtTab_b[LAB_CBRT_TAB_SIZE_B];
1043
-
1044
- enum
1045
- {
1046
- lab_base_shift = 14 ,
1047
- LAB_BASE = (1 << lab_base_shift),
1048
- };
1049
-
1050
- #define CV_DESCALE (x,n ) (((x) + (1 << ((n)-1 ))) >> (n))
1051
-
1052
- static ushort LabToYF_b[256 *2 ];
1053
- static const int minABvalue = -8145 ;
1054
- static int abToXZ_b[LAB_BASE*9 /4 ];
1001
+ // taken from color.cpp
1055
1002
1056
1003
// all constants should be presented through integers to keep bit-exactness
1057
1004
static const softdouble gammaThreshold = softdouble(809 )/softdouble(20000 ); // 0.04045
@@ -1088,90 +1035,6 @@ static inline float applyInvGamma(float x)
1088
1035
return x <= 0.0031308 ? x*12 .92f : (float )(1.055 *std::pow ((double )x, 1 ./2.4 ) - 0.055 );
1089
1036
}
1090
1037
1091
- static void initLabTabs ()
1092
- {
1093
- static bool initialized = false ;
1094
- if (!initialized)
1095
- {
1096
- static const softfloat lthresh = softfloat (216 ) / softfloat (24389 ); // 0.008856f = (6/29)^3
1097
- static const softfloat lscale = softfloat (841 ) / softfloat (108 ); // 7.787f = (29/3)^3/(29*4)
1098
- static const softfloat lbias = softfloat (16 ) / softfloat (116 );
1099
- static const softfloat f255 (255 );
1100
-
1101
- static const softfloat intScale (255 *(1 << gamma_shift));
1102
- for (int i = 0 ; i < 256 ; i++)
1103
- {
1104
- softfloat x = softfloat (i)/f255;
1105
- sRGBGammaTab_b [i] = (ushort)(cvRound (intScale*applyGamma (x)));
1106
- linearGammaTab_b[i] = (ushort)(i*(1 << gamma_shift));
1107
- }
1108
- static const softfloat invScale = softfloat::one ()/softfloat ((int )INV_GAMMA_TAB_SIZE);
1109
- for (int i = 0 ; i < INV_GAMMA_TAB_SIZE; i++)
1110
- {
1111
- softfloat x = invScale*softfloat (i);
1112
- sRGBInvGammaTab_b [i] = (ushort)(cvRound (f255*applyInvGamma (x)));
1113
- linearInvGammaTab_b[i] = (ushort)(cvTrunc (f255*x));
1114
- }
1115
-
1116
- static const softfloat cbTabScale (softfloat::one ()/(f255*(1 << gamma_shift)));
1117
- static const softfloat lshift2 (1 << lab_shift2);
1118
- for (int i = 0 ; i < LAB_CBRT_TAB_SIZE_B; i++)
1119
- {
1120
- softfloat x = cbTabScale*softfloat (i);
1121
- LabCbrtTab_b[i] = (ushort)(cvRound (lshift2 * (x < lthresh ? mulAdd (x, lscale, lbias) : cbrt (x))));
1122
- }
1123
-
1124
- // Lookup table for L to y and ify calculations
1125
- static const int BASE = (1 << 14 );
1126
- for (int i = 0 ; i < 256 ; i++)
1127
- {
1128
- int y, ify;
1129
- // 8 * 255.0 / 100.0 == 20.4
1130
- if ( i <= 20 )
1131
- {
1132
- // yy = li / 903.3f;
1133
- // y = L*100/903.3f; 903.3f = (29/3)^3, 255 = 17*3*5
1134
- y = cvRound (softfloat (i*BASE*20 *9 )/softfloat (17 *29 *29 *29 ));
1135
- // fy = 7.787f * yy + 16.0f / 116.0f; 7.787f = (29/3)^3/(29*4)
1136
- ify = cvRound (softfloat (BASE)*(softfloat (16 )/softfloat (116 ) + softfloat (i*5 )/softfloat (3 *17 *29 )));
1137
- }
1138
- else
1139
- {
1140
- // fy = (li + 16.0f) / 116.0f;
1141
- softfloat fy = (softfloat (i*100 *BASE)/softfloat (255 *116 ) +
1142
- softfloat (16 *BASE)/softfloat (116 ));
1143
- ify = cvRound (fy);
1144
- // yy = fy * fy * fy;
1145
- y = cvRound (fy*fy*fy/softfloat (BASE*BASE));
1146
- }
1147
-
1148
- LabToYF_b[i*2 ] = (ushort)y; // 2260 <= y <= BASE
1149
- LabToYF_b[i*2 +1 ] = (ushort)ify; // 0 <= ify <= BASE
1150
- }
1151
-
1152
- // Lookup table for a,b to x,z conversion
1153
- for (int i = minABvalue; i < LAB_BASE*9 /4 +minABvalue; i++)
1154
- {
1155
- int v;
1156
- // 6.f/29.f*BASE = 3389.730
1157
- if (i <= 3390 )
1158
- {
1159
- // fxz[k] = (fxz[k] - 16.0f / 116.0f) / 7.787f;
1160
- // 7.787f = (29/3)^3/(29*4)
1161
- v = i*108 /841 - BASE*16 /116 *108 /841 ;
1162
- }
1163
- else
1164
- {
1165
- // fxz[k] = fxz[k] * fxz[k] * fxz[k];
1166
- v = i*i/BASE*i/BASE;
1167
- }
1168
- abToXZ_b[i-minABvalue] = v; // -1335 <= v <= 88231
1169
- }
1170
-
1171
- initialized = true ;
1172
- }
1173
- }
1174
-
1175
1038
class CV_ColorLabTest : public CV_ColorCvtBaseTest
1176
1039
{
1177
1040
public:
@@ -1188,7 +1051,6 @@ class CV_ColorLabTest : public CV_ColorCvtBaseTest
1188
1051
1189
1052
CV_ColorLabTest::CV_ColorLabTest () : CV_ColorCvtBaseTest( true , true , false )
1190
1053
{
1191
- initLabTabs ();
1192
1054
INIT_FWD_INV_CODES ( BGR2Lab, Lab2BGR );
1193
1055
}
1194
1056
@@ -1218,52 +1080,12 @@ double CV_ColorLabTest::get_success_error_level( int /*test_case_idx*/, int i, i
1218
1080
{
1219
1081
int depth = test_mat[i][j].depth ();
1220
1082
// j == 0 is for forward code, j == 1 is for inverse code
1221
- return (depth == CV_8U) ? 0 :
1222
- // 16u is forbidden
1223
- // (depth == CV_16U) ? 32 :
1083
+ return (depth == CV_8U) ? (srgb ? 32 : 8 ) :
1084
+ // (depth == CV_16U) ? 32 : // 16u is disabled
1224
1085
srgb ? ((j == 0 ) ? 0.4 : 0.0055 ) : 1e-3 ;
1225
1086
}
1226
1087
1227
1088
1228
- int CV_ColorLabTest::convert_row_bgr2abc_8u_c3 (const uchar* src_row, uchar *dst_row, int n, int cn)
1229
- {
1230
- int coeffs[9 ];
1231
- softdouble whitept[3 ] = {Xn, softdouble::one (), Zn};
1232
-
1233
- static const softdouble lshift (1 << lab_shift);
1234
- for (int i = 0 ; i < 3 ; i++)
1235
- {
1236
- coeffs[i*3 + (blue_idx^2 )] = cvRound (lshift*RGB2XYZ[i*3 ]/whitept[i]);
1237
- coeffs[i*3 + 1 ] = cvRound (lshift*RGB2XYZ[i*3 +1 ]/whitept[i]);
1238
- coeffs[i*3 + (blue_idx )] = cvRound (lshift*RGB2XYZ[i*3 +2 ]/whitept[i]);
1239
- }
1240
-
1241
- const int Lscale = (116 *255 +50 )/100 ;
1242
- const int Lshift = -((16 *255 *(1 << lab_shift2) + 50 )/100 );
1243
- const ushort* tab = srgb ? sRGBGammaTab_b : linearGammaTab_b;
1244
- for (int x = 0 ; x < n; x++)
1245
- {
1246
- int R = src_row[x*cn + 0 ],
1247
- G = src_row[x*cn + 1 ],
1248
- B = src_row[x*cn + 2 ];
1249
- R = tab[R], G = tab[G], B = tab[B];
1250
- int fX = LabCbrtTab_b[CV_DESCALE (R*coeffs[0 ] + G*coeffs[1 ] + B*coeffs[2 ], lab_shift)];
1251
- int fY = LabCbrtTab_b[CV_DESCALE (R*coeffs[3 ] + G*coeffs[4 ] + B*coeffs[5 ], lab_shift)];
1252
- int fZ = LabCbrtTab_b[CV_DESCALE (R*coeffs[6 ] + G*coeffs[7 ] + B*coeffs[8 ], lab_shift)];
1253
-
1254
- int L = CV_DESCALE ( Lscale*fY + Lshift, lab_shift2 );
1255
- int a = CV_DESCALE ( 500 *(fX - fY ) + 128 *(1 << lab_shift2), lab_shift2 );
1256
- int b = CV_DESCALE ( 200 *(fY - fZ ) + 128 *(1 << lab_shift2), lab_shift2 );
1257
-
1258
- dst_row[x*3 ] = saturate_cast<uchar>(L);
1259
- dst_row[x*3 + 1 ] = saturate_cast<uchar>(a);
1260
- dst_row[x*3 + 2 ] = saturate_cast<uchar>(b);
1261
- }
1262
-
1263
- return n;
1264
- }
1265
-
1266
-
1267
1089
void CV_ColorLabTest::convert_row_bgr2abc_32f_c3 (const float * src_row, float * dst_row, int n)
1268
1090
{
1269
1091
int depth = test_mat[INPUT][0 ].depth ();
@@ -1318,70 +1140,6 @@ void CV_ColorLabTest::convert_row_bgr2abc_32f_c3(const float* src_row, float* ds
1318
1140
}
1319
1141
}
1320
1142
1321
- int CV_ColorLabTest::convert_row_abc2bgr_8u_c3 (const uchar* src_row, uchar *dst_row, int n, int cn)
1322
- {
1323
- static const int base_shift = 14 ;
1324
- static const int BASE = (1 << base_shift);
1325
- static const int shift = lab_shift+(base_shift-inv_gamma_shift);
1326
-
1327
- int coeffs[9 ];
1328
- softdouble whitept[3 ] = {Xn, softdouble::one (), Zn};
1329
-
1330
- static const softdouble lshift (1 << lab_shift);
1331
- for (int i = 0 ; i < 3 ; i++)
1332
- {
1333
- coeffs[i+(blue_idx )*3 ] = cvRound (lshift*XYZ2RGB[i ]*whitept[i]);
1334
- coeffs[i+ 1 *3 ] = cvRound (lshift*XYZ2RGB[i+3 ]*whitept[i]);
1335
- coeffs[i+(blue_idx^2 )*3 ] = cvRound (lshift*XYZ2RGB[i+6 ]*whitept[i]);
1336
- }
1337
- ushort* tab = srgb ? sRGBInvGammaTab_b : linearInvGammaTab_b;
1338
-
1339
- for (int x = 0 ; x < n; x++)
1340
- {
1341
- uchar LL = src_row[x*3 ];
1342
- uchar aa = src_row[x*3 + 1 ];
1343
- uchar bb = src_row[x*3 + 2 ];
1344
-
1345
- int ro, go, bo, xx, yy, zz, ify;
1346
-
1347
- yy = LabToYF_b[LL*2 ];
1348
- ify = LabToYF_b[LL*2 +1 ];
1349
-
1350
- int adiv, bdiv;
1351
- // adiv = aa*BASE/500 - 128*BASE/500, bdiv = bb*BASE/200 - 128*BASE/200;
1352
- // approximations with reasonable precision
1353
- adiv = ((5 *aa*53687 + (1 << 7 )) >> 13 ) - 128 *BASE/500 ;
1354
- bdiv = (( bb*41943 + (1 << 4 )) >> 9 ) - 128 *BASE/200 +1 ;
1355
-
1356
- int ifxz[] = {ify + adiv, ify - bdiv};
1357
-
1358
- for (int k = 0 ; k < 2 ; k++)
1359
- {
1360
- int & v = ifxz[k];
1361
- v = abToXZ_b[v-minABvalue];
1362
- }
1363
- xx = ifxz[0 ]; /* yy = yy */ ; zz = ifxz[1 ];
1364
-
1365
- ro = CV_DESCALE (coeffs[0 ]*xx + coeffs[1 ]*yy + coeffs[2 ]*zz, shift);
1366
- go = CV_DESCALE (coeffs[3 ]*xx + coeffs[4 ]*yy + coeffs[5 ]*zz, shift);
1367
- bo = CV_DESCALE (coeffs[6 ]*xx + coeffs[7 ]*yy + coeffs[8 ]*zz, shift);
1368
-
1369
- ro = max (0 , min ((int )INV_GAMMA_TAB_SIZE-1 , ro));
1370
- go = max (0 , min ((int )INV_GAMMA_TAB_SIZE-1 , go));
1371
- bo = max (0 , min ((int )INV_GAMMA_TAB_SIZE-1 , bo));
1372
-
1373
- ro = tab[ro];
1374
- go = tab[go];
1375
- bo = tab[bo];
1376
-
1377
- dst_row[x*cn ] = saturate_cast<uchar>(bo);
1378
- dst_row[x*cn + 1 ] = saturate_cast<uchar>(go);
1379
- dst_row[x*cn + 2 ] = saturate_cast<uchar>(ro);
1380
- if (cn == 4 ) dst_row[x*cn + 3 ] = 255 ;
1381
- }
1382
-
1383
- return n;
1384
- }
1385
1143
1386
1144
void CV_ColorLabTest::convert_row_abc2bgr_32f_c3 ( const float * src_row, float * dst_row, int n )
1387
1145
{
@@ -1472,7 +1230,6 @@ class CV_ColorLuvTest : public CV_ColorCvtBaseTest
1472
1230
1473
1231
CV_ColorLuvTest::CV_ColorLuvTest () : CV_ColorCvtBaseTest( true , true , false )
1474
1232
{
1475
- initLabTabs ();
1476
1233
INIT_FWD_INV_CODES ( BGR2Luv, Luv2BGR );
1477
1234
}
1478
1235
0 commit comments