@@ -1010,17 +1010,22 @@ double CV_ColorLabTest::get_success_error_level( int /*test_case_idx*/, int i, i
1010
1010
}
1011
1011
1012
1012
1013
- static const double _1_3 = 0.333333333333 ;
1014
- const static float _1_3f = static_cast <float >(_1_3);
1015
-
1016
-
1017
1013
void CV_ColorLabTest::convert_row_bgr2abc_32f_c3 (const float * src_row, float * dst_row, int n)
1018
1014
{
1019
1015
int depth = test_mat[INPUT][0 ].depth ();
1020
1016
float Lscale = depth == CV_8U ? 255 .f /100 .f : depth == CV_16U ? 65535 .f /100 .f : 1 .f ;
1021
1017
float ab_bias = depth == CV_8U ? 128 .f : depth == CV_16U ? 32768 .f : 0 .f ;
1022
1018
float M[9 ];
1023
1019
1020
+ // 7.787f = (29/3)^3/(29*4)
1021
+ static const float lowScale = 29 .f *29 .f /(27 .f *4 .f );
1022
+ // 0.008856f = (6/29)^3
1023
+ static const float lthresh = 6 .f *6 .f *6 .f /(29 .f *29 .f *29 .f );
1024
+ // 903.3 = (29/3)^3
1025
+ static const float yscale = 29 .f *29 .f *29 .f /27 .f ;
1026
+
1027
+ static const float f16of116 = 16 .f /116 .f ;
1028
+
1024
1029
for (int j = 0 ; j < 9 ; j++ )
1025
1030
M[j] = (float )RGB2XYZ[j];
1026
1031
@@ -1031,25 +1036,14 @@ void CV_ColorLabTest::convert_row_bgr2abc_32f_c3(const float* src_row, float* ds
1031
1036
float B = src_row[x];
1032
1037
1033
1038
float X = (R * M[0 ] + G * M[1 ] + B * M[2 ]) / Xn;
1034
- float Y = R * M[3 ] + G * M[4 ] + B * M[5 ];
1039
+ float Y = R * M[3 ] + G * M[4 ] + B * M[5 ];
1035
1040
float Z = (R * M[6 ] + G * M[7 ] + B * M[8 ]) / Zn;
1036
- float fX = X > 0 .008856f ? pow (X, _1_3f) :
1037
- (7 .787f * X + 16 .f / 116 .f );
1038
- float fZ = Z > 0 .008856f ? pow (Z, _1_3f):
1039
- (7 .787f * Z + 16 .f / 116 .f );
1040
1041
1041
- float L = 0 .0f , fY = 0 .0f ;
1042
- if (Y > 0 .008856f )
1043
- {
1044
- fY = pow (Y, _1_3f);
1045
- L = 116 .f * fY - 16 .f ;
1046
- }
1047
- else
1048
- {
1049
- fY = 7 .787f * Y + 16 .f / 116 .f ;
1050
- L = 903 .3f * Y;
1051
- }
1042
+ float fX = X > lthresh ? cubeRoot (X) : (lowScale * X + f16of116);
1043
+ float fY = Y > lthresh ? cubeRoot (Y) : (lowScale * Y + f16of116);
1044
+ float fZ = Z > lthresh ? cubeRoot (Z) : (lowScale * Z + f16of116);
1052
1045
1046
+ float L = Y > lthresh ? (116 .f *fY - 16 .f ) : (yscale*Y);
1053
1047
float a = 500 .f * (fX - fY );
1054
1048
float b = 200 .f * (fY - fZ );
1055
1049
@@ -1069,19 +1063,27 @@ void CV_ColorLabTest::convert_row_abc2bgr_32f_c3( const float* src_row, float* d
1069
1063
for (int j = 0 ; j < 9 ; j++ )
1070
1064
M[j] = (float )XYZ2RGB[j];
1071
1065
1072
- static const float lthresh = 903 .3f * 0 .008856f ;
1073
- static const float thresh = 7 .787f * 0 .008856f + 16 .0f / 116 .0f ;
1066
+ // 0.008856f * 903.3f = (6/29)^3*(29/3)^3 = 8
1067
+ static const float lThresh = 8 .f ;
1068
+ // 7.787f * 0.008856f + 16.0f / 116.0f = 6/29
1069
+ static const float fThresh = 6 .f /29 .f ;
1070
+ static const float lbias = 16 .f /116 .f ;
1071
+ // 7.787f = (29/3)^3/(29*4)
1072
+ static const float lowScale = 29 .f *29 .f /(27 .f *4 .f );
1073
+ // 903.3 = (29/3)^3
1074
+ static const float yscale = 29 .f *29 .f *29 .f /27 .f ;
1075
+
1074
1076
for (int x = 0 , end = n * 3 ; x < end; x += 3 )
1075
1077
{
1076
1078
float L = src_row[x] * Lscale;
1077
1079
float a = src_row[x + 1 ] - ab_bias;
1078
1080
float b = src_row[x + 2 ] - ab_bias;
1079
1081
1080
1082
float FY = 0 .0f , Y = 0 .0f ;
1081
- if (L <= lthresh )
1083
+ if (L <= lThresh )
1082
1084
{
1083
- Y = L / 903 . 3f ;
1084
- FY = 7 . 787f * Y + 16 . 0f / 116 . 0f ;
1085
+ Y = L / yscale ;
1086
+ FY = lowScale * Y + lbias ;
1085
1087
}
1086
1088
else
1087
1089
{
@@ -1095,8 +1097,8 @@ void CV_ColorLabTest::convert_row_abc2bgr_32f_c3( const float* src_row, float* d
1095
1097
float FXZ[] = { FX, FZ };
1096
1098
for (int k = 0 ; k < 2 ; ++k)
1097
1099
{
1098
- if (FXZ[k] <= thresh )
1099
- FXZ[k] = (FXZ[k] - 16 . 0f / 116 . 0f ) / 7 . 787f ;
1100
+ if (FXZ[k] <= fThresh )
1101
+ FXZ[k] = (FXZ[k] - lbias ) / lowScale ;
1100
1102
else
1101
1103
FXZ[k] = FXZ[k] * FXZ[k] * FXZ[k];
1102
1104
}
@@ -1155,25 +1157,37 @@ void CV_ColorLuvTest::convert_row_bgr2abc_32f_c3( const float* src_row, float* d
1155
1157
{
1156
1158
int depth = test_mat[INPUT][0 ].depth ();
1157
1159
float Lscale = depth == CV_8U ? 255 .f /100 .f : depth == CV_16U ? 65535 .f /100 .f : 1 .f ;
1160
+ static const float uLow = -134 .f , uHigh = 220 .f , uRange = uHigh - uLow;
1161
+ static const float vLow = -140 .f , vHigh = 122 .f , vRange = vHigh - vLow;
1158
1162
int j;
1159
1163
1160
1164
float M[9 ];
1161
- float un = 4 .f *Xn/(Xn + 15 .f *1 .f + 3 *Zn);
1162
- float vn = 9 .f *1 .f /(Xn + 15 .f *1 .f + 3 *Zn);
1165
+ // Yn == 1
1166
+ float dd = Xn + 15 .f *1 .f + 3 .f *Zn;
1167
+ float un = 4 .f *13 .f *Xn/dd;
1168
+ float vn = 9 .f *13 .f /dd;
1169
+
1163
1170
float u_scale = 1 .f , u_bias = 0 .f ;
1164
1171
float v_scale = 1 .f , v_bias = 0 .f ;
1165
1172
1166
1173
for ( j = 0 ; j < 9 ; j++ )
1167
1174
M[j] = (float )RGB2XYZ[j];
1168
1175
1176
+ // 0.72033 = 255/(220+134), 96.525 = 134*255/(220+134)
1177
+ // 0.9732 = 255/(140+122), 136.259 = 140*255/(140+122)
1169
1178
if ( depth == CV_8U )
1170
1179
{
1171
- u_scale = 0 . 720338983f ;
1172
- u_bias = 96 . 5254237f ;
1173
- v_scale = 0 . 973282442f ;
1174
- v_bias = 136 . 2595419f ;
1180
+ u_scale = 255 . f /uRange ;
1181
+ u_bias = -uLow* 255 . f /uRange ;
1182
+ v_scale = 255 . f /vRange ;
1183
+ v_bias = -vLow* 255 . f /vRange ;
1175
1184
}
1176
1185
1186
+ // 0.008856f = (6/29)^3
1187
+ static const float lthresh = 6 .f *6 .f *6 .f /(29 .f *29 .f *29 .f );
1188
+ // 903.3 = (29/3)^3
1189
+ static const float yscale = 29 .f *29 .f *29 .f /27 .f ;
1190
+
1177
1191
for ( j = 0 ; j < n*3 ; j += 3 )
1178
1192
{
1179
1193
float r = src_row[j+2 ];
@@ -1189,14 +1203,14 @@ void CV_ColorLuvTest::convert_row_bgr2abc_32f_c3( const float* src_row, float* d
1189
1203
L = u = v = 0 ;
1190
1204
else
1191
1205
{
1192
- if ( Y > 0 . 008856f )
1193
- L = ( float )( 116 .* pow (( double )Y,_1_3 ) - 16 .) ;
1206
+ if ( Y > lthresh )
1207
+ L = 116 .f * cubeRoot (Y ) - 16 .f ;
1194
1208
else
1195
- L = 903 . 3f * Y;
1209
+ L = yscale * Y;
1196
1210
1197
- d = 1 .f /d;
1198
- u = 13 * L*(4 * X*d - un);
1199
- v = 13 * L*(9 *Y*d - vn);
1211
+ d = 4 . f * 13 .f /d;
1212
+ u = L*(X*d - un);
1213
+ v = L*(9 . f / 4 . f *Y*d - vn);
1200
1214
}
1201
1215
dst_row[j] = L*Lscale;
1202
1216
dst_row[j+1 ] = u*u_scale + u_bias;
@@ -1209,24 +1223,34 @@ void CV_ColorLuvTest::convert_row_abc2bgr_32f_c3( const float* src_row, float* d
1209
1223
{
1210
1224
int depth = test_mat[INPUT][0 ].depth ();
1211
1225
float Lscale = depth == CV_8U ? 100 .f /255 .f : depth == CV_16U ? 100 .f /65535 .f : 1 .f ;
1226
+ static const float uLow = -134 .f , uHigh = 220 .f , uRange = uHigh - uLow;
1227
+ static const float vLow = -140 .f , vHigh = 122 .f , vRange = vHigh - vLow;
1228
+
1212
1229
int j;
1213
1230
float M[9 ];
1214
- float un = 4 .f *Xn/(Xn + 15 .f *1 .f + 3 *Zn);
1215
- float vn = 9 .f *1 .f /(Xn + 15 .f *1 .f + 3 *Zn);
1231
+ // Yn == 1
1232
+ float dd = Xn + 15 .f *1 .f + 3 .f *Zn;
1233
+ float un = 4 *13 .f *Xn/dd;
1234
+ float vn = 9 *13 .f *1 .f /dd;
1235
+
1216
1236
float u_scale = 1 .f , u_bias = 0 .f ;
1217
1237
float v_scale = 1 .f , v_bias = 0 .f ;
1218
1238
1219
1239
for ( j = 0 ; j < 9 ; j++ )
1220
1240
M[j] = (float )XYZ2RGB[j];
1221
1241
1242
+ // 0.72033 = 255/(220+134), 96.525 = 134*255/(220+134)
1243
+ // 0.9732 = 255/(140+122), 136.259 = 140*255/(140+122)
1222
1244
if ( depth == CV_8U )
1223
1245
{
1224
- u_scale = 1 . f / 0 . 720338983f ;
1225
- u_bias = 96 . 5254237f ;
1226
- v_scale = 1 . f / 0 . 973282442f ;
1227
- v_bias = 136 . 2595419f ;
1246
+ u_scale = uRange/ 255 . f ;
1247
+ u_bias = -uLow* 255 . f /uRange ;
1248
+ v_scale = vRange/ 255 . f ;
1249
+ v_bias = -vLow* 255 . f /vRange ;
1228
1250
}
1229
1251
1252
+ // (1 / 903.3) = (3/29)^3
1253
+ static const float yscale = 27 .f /(29 .f *29 .f *29 .f );
1230
1254
for ( j = 0 ; j < n*3 ; j += 3 )
1231
1255
{
1232
1256
float L = src_row[j]*Lscale;
@@ -1241,16 +1265,15 @@ void CV_ColorLuvTest::convert_row_abc2bgr_32f_c3( const float* src_row, float* d
1241
1265
}
1242
1266
else
1243
1267
{
1244
- Y = L * (1 .f /903 .3f );
1245
- if ( L == 0 )
1246
- L = 0 .001f ;
1268
+ Y = L * yscale;
1247
1269
}
1248
1270
1249
- u = u/(13 *L) + un;
1250
- v = v/(13 *L) + vn;
1251
-
1252
- X = -9 *Y*u/((u - 4 )*v - u*v);
1253
- Z = (9 *Y - 15 *v*Y - v*X)/(3 *v);
1271
+ float up = 3 .f *(u + L*un);
1272
+ float vp = 0 .25f /(v + L*vn);
1273
+ if (vp > 0 .25f ) vp = 0 .25f ;
1274
+ if (vp < -0 .25f ) vp = -0 .25f ;
1275
+ X = Y*3 .f *up*vp;
1276
+ Z = Y*(((12 .f *13 .f )*L - up)*vp - 5 .f );
1254
1277
1255
1278
float r = M[0 ]*X + M[1 ]*Y + M[2 ]*Z;
1256
1279
float g = M[3 ]*X + M[4 ]*Y + M[5 ]*Z;
0 commit comments