00001
00002
00003
00004
00005
00006
00007
00008 #include "ColorTableTSL.h"
00009 #include "Tools/Math/Common.h"
00010 #include "Tools/Debugging/Debugging.h"
00011
00012
00013
00014
00015 ColorTableTSL::ColorTableTSL()
00016 : corrector()
00017 {
00018
00019 }
00020
00021
00022
00023
00024 ColorTableTSL::~ColorTableTSL()
00025 {
00026 }
00027
00028
00029
00030
00031 void ColorTableTSL::clear()
00032 {
00033 for (unsigned char y = 0; y < 32; y++)
00034 {
00035 for (unsigned char u = 0; u < 64; u++)
00036 {
00037 for (unsigned char v = 0; v < 64; v++)
00038 {
00039 colorClasses[y][u][v] = noColor;
00040 }
00041 }
00042 }
00043 for (int i = 0; i < numOfColors; i++)
00044 {
00045 tsl_threshold[i][0][0] = 0;
00046 tsl_threshold[i][1][0] = 0;
00047 tsl_threshold[i][0][1] = 0;
00048 tsl_threshold[i][1][1] = 0;
00049 tsl_threshold[i][0][2] = 0;
00050 tsl_threshold[i][1][2] = 0;
00051 tsl_order[i] = orange;
00052 }
00053 tsl_index = 0;
00054 }
00055
00056
00057
00058
00059 void ColorTableTSL::reset()
00060 {
00061 clear();
00062 addColorClass(green, 15, 85, 30, 150, 45, 170);
00063 addColorClass(skyblue, 230, 15, 45, 135, 75, 200);
00064 addColorClass(blue, 195, 20, 15, 100, 45, 120);
00065 addColorClass(orange, 120, 145, 45, 150, 120, 220);
00066 addColorClass(yellow, 90, 120, 45, 130, 150, 245);
00067 addColorClass(pink, 140, 180, 15, 65, 150, 245);
00068 addColorClass(red, 135, 165, 45, 255, 45, 155);
00069 addColorClass(gray, 0, 255, 0, 90, 0, 145);
00070 addColorClass(white, 0, 255, 0, 30, 145, 255);
00071 addColorClass(black, 0, 255, 0, 255, 0, 10);
00072 addColorClass(noColor, 0, 255, 0, 255, 0, 255);
00073 }
00074
00075
00076
00077
00078 void ColorTableTSL::addColorClass(
00079 colorClass colorClass,
00080 unsigned char t_min,
00081 unsigned char t_max,
00082 unsigned char s_min,
00083 unsigned char s_max,
00084 unsigned char l_min,
00085 unsigned char l_max
00086 )
00087 {
00088 tsl_order[tsl_index++] = colorClass;
00089 tsl_threshold[colorClass][0][0] = t_min;
00090 tsl_threshold[colorClass][1][0] = t_max;
00091 tsl_threshold[colorClass][0][1] = s_min;
00092 tsl_threshold[colorClass][1][1] = s_max;
00093 tsl_threshold[colorClass][0][2] = l_min;
00094 tsl_threshold[colorClass][1][2] = l_max;
00095 }
00096
00097
00098
00099
00100 void ColorTableTSL::calculateLUT()
00101 {
00102 unsigned char t,
00103 s,
00104 l;
00105
00106 for (register unsigned char y = 0; y < 32; y++)
00107 {
00108 for (register unsigned char u = 0; u < 64; u++)
00109 {
00110 for (register unsigned char v = 0; v < 64; v++)
00111 {
00112 convertYUVToTSL((y << 3) | (y >> 2), (u << 2) | (u >> 4), (v << 2) | (v >> 4), &t, &s, &l);
00113 colorClasses[y][u][v] = classifyTSL(t, s, l);
00114 }
00115 }
00116 }
00117 }
00118
00119
00120
00121
00122 colorClass ColorTableTSL::getColorClass(
00123 const unsigned char y,
00124 const unsigned char u,
00125 const unsigned char v
00126 ) const
00127 {
00128
00129
00130
00131
00132
00133
00134 return (colorClass) colorClasses[y >> 3][u >> 2][v >> 2];
00135 }
00136
00137
00138
00139
00140 void ColorTableTSL::convertYUVToTSL(
00141 unsigned char y,
00142 unsigned char u,
00143 unsigned char v,
00144 unsigned char *t,
00145 unsigned char *s,
00146 unsigned char *l
00147 ) const
00148 {
00149 double y_in,
00150 u_in,
00151 v_in,
00152 tmp,
00153 tmp_r,
00154 tmp_g,
00155 tmp_b,
00156 t_out,
00157 s_out;
00158 const double pi2_div = 0.15915494309189533576888376337251;
00159
00160 y_in = (double) y;
00161 u_in = (double) v;
00162 v_in = (double) u;
00163 u_in -= 128.0;
00164 v_in -= 128.0;
00165 tmp = 1.0 / (4.3403 * y_in + 2.0 * u_in + v_in);
00166 tmp_r = (-0.6697 * u_in + 1.6959 * v_in) * tmp;
00167 tmp_g = (-1.168 * u_in - 1.3626 * v_in) * tmp;
00168 tmp_b = ( 1.8613 * u_in - 0.331 * v_in) * tmp;
00169 if (tmp_g > 0.0)
00170 {
00171 t_out = (atan2(tmp_r, tmp_g) * pi2_div + 0.25) * 255.0;
00172 }
00173 else if (tmp_g < 0.0)
00174 {
00175 t_out = (atan2(-tmp_r, -tmp_g) * pi2_div + 0.75) * 255.0;
00176 }
00177 else
00178 {
00179 t_out = 0.0;
00180 }
00181 s_out = sqrt(1.8 * (tmp_r * tmp_r + tmp_g * tmp_g + tmp_b * tmp_b)) * 255.0;
00182
00183
00184 if (t_out < 0.0)
00185 {
00186 t_out = 0.0;
00187 }
00188 else if (t_out > 255.0)
00189 {
00190 t_out = 255.0;
00191 }
00192 if (s_out < 0.0)
00193 {
00194 s_out = 0.0;
00195 }
00196 else if (s_out > 255.0)
00197 {
00198 s_out = 255.0;
00199 }
00200
00201 *t = (unsigned char) t_out;
00202 *s = (unsigned char) s_out;
00203 *l = y;
00204 }
00205
00206
00207
00208
00209 colorClass ColorTableTSL::classifyTSL(
00210 unsigned char t,
00211 unsigned char s,
00212 unsigned char l
00213 ) const
00214 {
00215 colorClass cl;
00216
00217 for (register int i = 0; i < tsl_index; i++)
00218 {
00219 cl = tsl_order[i];
00220 if ((s >= tsl_threshold[cl][0][1]) && (s <= tsl_threshold[cl][1][1])
00221 && (l >= tsl_threshold[cl][0][2]) && (l <= tsl_threshold[cl][1][2]))
00222 {
00223 if (tsl_threshold[cl][0][0] < tsl_threshold[cl][1][0])
00224 {
00225 if ((t >= tsl_threshold[cl][0][0]) && (t <= tsl_threshold[cl][1][0]))
00226 {
00227 return cl;
00228 }
00229 }
00230 else
00231 {
00232 if ((t >= tsl_threshold[cl][0][0]) || (t <= tsl_threshold[cl][1][0]))
00233 {
00234 return cl;
00235 }
00236 }
00237 }
00238 }
00239 return noColor;
00240 }
00241
00242
00243
00244
00245
00246 void ColorTableTSL::generateColorClassImage(const Image& image,
00247 ColorClassImage& colorClassImage) const
00248 {
00249 unsigned char y,
00250 u,
00251 v;
00252
00253
00254
00255
00256 colorClassImage.width = image.cameraInfo.resolutionWidth;
00257 colorClassImage.height = image.cameraInfo.resolutionHeight;
00258
00259 for (register int j = 0; j < image.cameraInfo.resolutionHeight; j++)
00260 {
00261 for (register int i = 0; i < image.cameraInfo.resolutionWidth; i++)
00262 {
00263 y = image.image[j][0][i];
00264 u = image.image[j][1][i];
00265 v = image.image[j][2][i];
00266 corrector.getCorrectedPixel(i,j,y,u,v);
00267
00268
00269
00270
00271
00272 colorClassImage.image[j][i] = getColorClass(y,u,v);
00273
00274 }
00275 }
00276 }
00277
00278
00279 Out& operator << (Out& stream, const ColorTableTSL& colorTableTSL)
00280 {
00281 unsigned char tmp;
00282 register int i;
00283
00284 stream << (unsigned int) 0x004c5354;
00285 for (i = 0; i < numOfColors; i++)
00286 {
00287 tmp = colorTableTSL.tsl_order[i];
00288 stream << tmp;
00289 tmp = colorTableTSL.tsl_threshold[i][0][0];
00290 stream << tmp;
00291 tmp = colorTableTSL.tsl_threshold[i][1][0];
00292 stream << tmp;
00293 tmp = colorTableTSL.tsl_threshold[i][0][1];
00294 stream << tmp;
00295 tmp = colorTableTSL.tsl_threshold[i][1][1];
00296 stream << tmp;
00297 tmp = colorTableTSL.tsl_threshold[i][0][2];
00298 stream << tmp;
00299 tmp = colorTableTSL.tsl_threshold[i][1][2];
00300 stream << tmp;
00301 }
00302
00303 return stream;
00304 }
00305
00306 In& operator>>(In& stream,ColorTableTSL& colorTableTSL)
00307 {
00308 unsigned int tslMagic;
00309 unsigned char tmp;
00310 register int i;
00311
00312 stream >> tslMagic;
00313 if (tslMagic != (unsigned int) 0x004c5354)
00314 {
00315 colorTableTSL.reset();
00316 }
00317 else
00318 {
00319 for (i = 0; i < numOfColors; i++)
00320 {
00321 stream >> tmp;
00322 colorTableTSL.tsl_order[i] = (colorClass) tmp;
00323 stream >> tmp;
00324 colorTableTSL.tsl_threshold[i][0][0] = tmp;
00325 stream >> tmp;
00326 colorTableTSL.tsl_threshold[i][1][0] = tmp;
00327 stream >> tmp;
00328 colorTableTSL.tsl_threshold[i][0][1] = tmp;
00329 stream >> tmp;
00330 colorTableTSL.tsl_threshold[i][1][1] = tmp;
00331 stream >> tmp;
00332 colorTableTSL.tsl_threshold[i][0][2] = tmp;
00333 stream >> tmp;
00334 colorTableTSL.tsl_threshold[i][1][2] = tmp;
00335 }
00336 }
00337
00338 return stream;
00339 }
00340
00341 void ColorTableTSL::generateTSLDialogImage(const Image &image, ColorClassImage &colorClassImage){
00342 unsigned char y,
00343 u,
00344 v,
00345 t,
00346 s,
00347 l;
00348
00349 colorClassImage.width = image.cameraInfo.resolutionWidth;
00350 colorClassImage.height = image.cameraInfo.resolutionHeight;
00351
00352 for (register int j = 0; j < image.cameraInfo.resolutionHeight; j++)
00353 {
00354 for (register int i = 0; i < image.cameraInfo.resolutionWidth; i++)
00355 {
00356 y = image.image[j][0][i];
00357 u = image.image[j][1][i];
00358 v = image.image[j][2][i];
00359
00360
00361 convertYUVToTSL(y, u, v, &t, &s, &l);
00362 colorClassImage.image[j][i] = classifyTSL(t, s, l);
00363 }
00364 }
00365 }