00001
00002
00003
00004
00005
00006
00007 #ifndef __ColorModelConversions_h_
00008 #define __ColorModelConversions_h_
00009
00010 #include "Tools/Math/Common.h"
00011
00012
00013
00014
00015 class ColorModelConversions
00016 {
00017 public:
00018
00019
00020
00021
00022
00023
00024
00025
00026 static void fromYCbCrToRGB(unsigned char Y,
00027 unsigned char Cb,
00028 unsigned char Cr,
00029 unsigned char& R,
00030 unsigned char& G,
00031 unsigned char& B)
00032 {
00033 int r = (int)(Y + 1.4021 * (Cb - 128)),
00034 g = (int)(Y - 0.3456 * (Cr - 128) - 0.71448 * (Cb - 128)),
00035 b = (int)(Y + 1.7710 * (Cr - 128));
00036 if(r < 0) r = 0; else if(r > 255) r = 255;
00037 if(g < 0) g = 0; else if(g > 255) g = 255;
00038 if(b < 0) b = 0; else if(b > 255) b = 255;
00039 R = (unsigned char) r;
00040 G = (unsigned char) g;
00041 B = (unsigned char) b;
00042 }
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052 static void fromRGBToYCbCr(unsigned char R,
00053 unsigned char G,
00054 unsigned char B,
00055 unsigned char& Y,
00056 unsigned char& Cb,
00057 unsigned char& Cr)
00058 {
00059 int y = (int)( 0.2990 * R + 0.5870 * G + 0.1140 * B),
00060 cb = 127 + (int)(-0.1687 * R - 0.3313 * G + 0.5000 * B),
00061 cr = 127 + (int)( 0.5000 * R - 0.4187 * G - 0.0813 * B);
00062 if(y < 0) y = 0; else if(y > 255) y = 255;
00063 if(cb < 0) cb = 0; else if(cb > 255) cb = 255;
00064 if(cr < 0) cr = 0; else if(cr > 255) cr = 255;
00065 Y = (unsigned char) y;
00066 Cb = (unsigned char) cb;
00067 Cr = (unsigned char) cr;
00068 }
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 static void fromYCbCrToHSI(unsigned char Y,
00079 unsigned char Cb,
00080 unsigned char Cr,
00081 unsigned char& H,
00082 unsigned char& S,
00083 unsigned char& I)
00084 {
00085 const double sqrt3 = 1.732050808;
00086 unsigned char R,
00087 G,
00088 B;
00089 fromYCbCrToRGB(Y, Cb, Cr, R, G, B);
00090 I = R;
00091 if(G > I) I = G;
00092 if(B > I) I = B;
00093 if(I)
00094 {
00095 S = R;
00096 if(G < S) S = G;
00097 if(B < S) S = B;
00098 S = (unsigned char) (255 - 255 * S / I);
00099 if(S)
00100 {
00101 int h = int(atan2(sqrt3 * (G - B), 2 * R - G - B) / pi2 * 256);
00102 if(h > 255) h -= 256;
00103 else if(h < 0) h += 256;
00104 H = (unsigned char) h;
00105 }
00106 else
00107 H = 0;
00108 }
00109 else
00110 S = H = 0;
00111 }
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 static void fromHSIToYCbCr(unsigned char H,
00122 unsigned char S,
00123 unsigned char I,
00124 unsigned char& Y,
00125 unsigned char& Cb,
00126 unsigned char& Cr)
00127 {
00128 double h = 1.0 - H / 255.0,
00129 s = S / 255.0,
00130 r,
00131 g,
00132 b;
00133
00134 if(h < 1.0 / 3.0)
00135 {
00136 g = (1 - s) / 3;
00137 b = (1 + s * cos(pi2 * h) / cos(pi2 * (1.0 / 6.0 - h))) / 3.0;
00138 r = 1 - (g + b);
00139 }
00140 else if(h < 2.0 / 3.0)
00141 {
00142 h -= 1.0 / 3.0;
00143 b = (1 - s) / 3;
00144 r = (1 + s * cos(pi2 * h) / cos(pi2 * (1.0 / 6.0 - h))) / 3.0;
00145 g = 1 - (b + r);
00146 }
00147 else
00148 {
00149 h -= 2.0 / 3.0;
00150 r = (1 - s) / 3;
00151 g = (1 + s * cos(pi2 * h) / cos(pi2 * (1.0 / 6.0 - h))) / 3.0;
00152 b = 1 - (r + g);
00153 }
00154
00155 r *= I * 3;
00156 g *= I * 3;
00157 b *= I * 3;
00158 if(r > 255)
00159 r = 255;
00160 if(g > 255)
00161 g = 255;
00162 if(b > 255)
00163 b = 255;
00164
00165 fromRGBToYCbCr((unsigned char) r,
00166 (unsigned char) g,
00167 (unsigned char) b,
00168 Y, Cb, Cr);
00169 }
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179 static void fromYCbCrToTSL(unsigned char Y,
00180 unsigned char Cb,
00181 unsigned char Cr,
00182 unsigned char& T,
00183 unsigned char& S,
00184 unsigned char& L)
00185 {
00186 const double pi2_div = 0.15915494309189533576888376337251;
00187
00188 double cb = Cb - 128.0,
00189 cr = Cr - 128.0,
00190 tmp = 1.0 / (4.3403 * Y + 2.0 * cb + cr),
00191 tmp_r = (-0.6697 * cb + 1.6959 * cr) * tmp,
00192 tmp_g = (-1.168 * cb - 1.3626 * cr) * tmp,
00193 tmp_b = ( 1.8613 * cb - 0.331 * cr) * tmp;
00194 double t_out;
00195 if(tmp_g > 0.0)
00196 t_out = (atan2(tmp_r, tmp_g) * pi2_div + 0.25) * 255.0;
00197 else if(tmp_g < 0.0)
00198 t_out = (atan2(-tmp_r, -tmp_g) * pi2_div + 0.75) * 255.0;
00199 else
00200 t_out = 0.0;
00201 double s_out = sqrt(1.8 * (tmp_r * tmp_r + tmp_g * tmp_g + tmp_b * tmp_b)) * 255.0;
00202
00203 if(t_out < 0.0)
00204 t_out = 0.0;
00205 else if(t_out > 255.0)
00206 t_out = 255.0;
00207 if(s_out < 0.0)
00208 s_out = 0.0;
00209 else if(s_out > 255.0)
00210 s_out = 255.0;
00211
00212 T = (unsigned char) t_out;
00213 S = (unsigned char) s_out;
00214 L = Y;
00215 }
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225 static void fromTSLToYCbCr(unsigned char T,
00226 unsigned char S,
00227 unsigned char L,
00228 unsigned char& Y,
00229 unsigned char& Cb,
00230 unsigned char& Cr)
00231 {
00232 double rad = S * 0.555 / 255.0,
00233 phi = (T * 2 / 255.0 + 0.25) * pi,
00234 cr = 128 + rad * cos(phi) * 255.0,
00235 cb = 128 - rad * sin(phi) * 255.0;
00236 Y = L;
00237
00238 if(cb < 0)
00239 cb = 0;
00240 else if(cb > 255)
00241 cb = 255;
00242 if(cr < 0)
00243 cr = 0;
00244 else if(cr > 255)
00245 cr = 255;
00246 Cb = (unsigned char) cb;
00247 Cr = (unsigned char) cr;
00248 }
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 static void fromTSLToRGB(unsigned char t,
00259 unsigned char s,
00260 unsigned char l,
00261 unsigned char& r,
00262 unsigned char& g,
00263 unsigned char& b)
00264 {
00265 double y1, u1, v1, r1, g1, b1, rad, phi;
00266
00267
00268 rad = (((double) s) * 0.555) / 255.0;
00269 phi = (((double) t) * 2.0 * 3.14159) / 255.0;
00270 phi += 0.25 * 3.14159;
00271 y1 = (double) l;
00272 u1 = (rad * cos(phi)) * 255.0;
00273 v1 = -(rad * sin(phi)) * 255.0;
00274
00275
00276 if (u1 < -128.0)
00277 {
00278 u1 = -128.0;
00279 }
00280 else if (u1 > 127.0)
00281 {
00282 u1 = 127.0;
00283 }
00284 if (v1 < -128.0)
00285 {
00286 v1 = -128.0;
00287 }
00288 else if (v1 > 127.0)
00289 {
00290 v1 = 127.0;
00291 }
00292
00293
00294 r1 = y1 + 1.371 * v1;
00295 g1 = y1 - 0.336 * u1 - 0.698 * v1;
00296 b1 = y1 + 1.732 * u1;
00297
00298
00299 if (r1 < 0.0)
00300 {
00301 r1 = 0.0;
00302 }
00303 else if (r1 > 255.0)
00304 {
00305 r1 = 255.0;
00306 }
00307 if (g1 < 0.0)
00308 {
00309 g1 = 0.0;
00310 }
00311 else if (g1 > 255.0)
00312 {
00313 g1 = 255.0;
00314 }
00315 if (b1 < 0.0)
00316 {
00317 b1 = 0.0;
00318 }
00319 else if (b1 > 255.0)
00320 {
00321 b1 = 255.0;
00322 }
00323
00324
00325 r = (unsigned char) r1;
00326 g = (unsigned char) g1;
00327 b = (unsigned char) b1;
00328 }
00329 };
00330
00331 #endif //__ColorModelConversions_h_