00001
00015 #ifndef _DLRCOMPUTERVISION_COLORSPACECONVERTER_H_
00016 #define _DLRCOMPUTERVISION_COLORSPACECONVERTER_H_
00017
00018 #include <functional>
00019 #include <dlrComputerVision/imageFormat.h>
00020 #include <dlrComputerVision/image.h>
00021
00022 namespace dlr {
00023
00024 namespace computerVision {
00025
00026 template<ImageFormat FORMAT0, ImageFormat FORMAT1>
00027 class ColorspaceConverter
00028 : public std::unary_function<typename Image<FORMAT0>::PixelType,
00029 typename Image<FORMAT1>::PixelType>
00030 {
00031 public:
00032
00037 ColorspaceConverter()
00038 : std::unary_function<typename Image<FORMAT0>::PixelType,
00039 typename Image<FORMAT1>::PixelType>()
00040 {}
00041
00042
00049 virtual ~ColorspaceConverter()
00050 {}
00051
00052
00071 inline
00072 typename Image<FORMAT1>::PixelType
00073 operator()(const typename Image<FORMAT0>::PixelType& inputPixel) {
00074 typename Image<FORMAT1>::PixelType outputPixel;
00075 this->operator()(inputPixel, outputPixel);
00076 return outputPixel;
00077 }
00078
00079
00090 inline
00091 void
00092 operator()(const typename Image<FORMAT0>::PixelType& inputPixel,
00093 typename Image<FORMAT1>::PixelType& outputPixel) {
00094
00095
00096
00097
00098
00099 outputPixel =
00100 static_cast<typename Image<FORMAT1>::PixelType>(inputPixel);
00101 }
00102
00103 };
00104
00105 }
00106
00107 }
00108
00109
00110
00111
00112
00113 #include <cmath>
00114
00115 namespace dlr {
00116
00117 namespace computerVision {
00118
00119 namespace privateCode {
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131 inline void
00132 doColorspaceConversion(const Image<RGB_FLOAT64>::PixelType& inputPixel,
00133 Image<HSV_FLOAT64>::PixelType& outputPixel)
00134 {
00135
00136 Float64 maxVal = static_cast<Float64>(
00137 std::max(inputPixel.red,
00138 std::max(inputPixel.green, inputPixel.blue)));
00139 outputPixel.value = maxVal;
00140
00141
00142 if(maxVal == 0.0) {
00143 outputPixel.hue = Float64(0.0);
00144 outputPixel.saturation = Float64(0.0);
00145 return;
00146 }
00147
00148
00149 Float64 minVal = static_cast<Float64>(
00150 std::min(inputPixel.red,
00151 std::min(inputPixel.green, inputPixel.blue)));
00152 Float64 delta = maxVal - minVal;
00153 outputPixel.saturation = delta / maxVal;
00154
00155
00156 if(delta == 0.0) {
00157 outputPixel.hue = Float64(0.0);
00158 return;
00159 }
00160
00161
00162
00163 if(inputPixel.red == maxVal) {
00164 outputPixel.hue =
00165 Float64(1.0 / 6.0)
00166 + (static_cast<Float64>(inputPixel.green)
00167 - static_cast<Float64>(inputPixel.blue)) / (6.0 * delta);
00168 } else if(inputPixel.green == maxVal) {
00169 outputPixel.hue =
00170 Float64(0.5)
00171 + (static_cast<Float64>(inputPixel.blue)
00172 - static_cast<Float64>(inputPixel.red)) / (6.0 * delta);
00173 } else {
00174 outputPixel.hue =
00175 Float64(5.0 / 6.0)
00176 + (static_cast<Float64>(inputPixel.red)
00177 - static_cast<Float64>(inputPixel.green)) / (6.0 * delta);
00178 }
00179
00180 #if 1
00181
00182
00183
00184 outputPixel.hue -= 1.0 / 6.0;
00185 outputPixel.hue = ((outputPixel.hue < 0.0)
00186 ? (outputPixel.hue + 1.0) : outputPixel.hue);
00187 #endif
00188 }
00189
00190 }
00191
00192
00193 template<>
00194 inline
00195 void
00196 ColorspaceConverter<GRAY1, GRAY8>::
00197 operator()(const Image<GRAY1>::PixelType& inputPixel,
00198 Image<GRAY8>::PixelType& outputPixel)
00199 {
00200 if(inputPixel) {
00201 outputPixel = Image<GRAY8>::PixelType(255);
00202 } else {
00203 outputPixel = Image<GRAY8>::PixelType(0);
00204 }
00205 }
00206
00207
00208 template<>
00209 inline
00210 void
00211 ColorspaceConverter<GRAY1, RGB8>::
00212 operator()(const Image<GRAY1>::PixelType& inputPixel,
00213 Image<RGB8>::PixelType& outputPixel)
00214 {
00215 if(inputPixel) {
00216 outputPixel.red = ImageFormatTraits<RGB8>::ComponentType(255);
00217 outputPixel.green = ImageFormatTraits<RGB8>::ComponentType(255);
00218 outputPixel.blue = ImageFormatTraits<RGB8>::ComponentType(255);
00219 } else {
00220 outputPixel.red = ImageFormatTraits<RGB8>::ComponentType(0);
00221 outputPixel.green = ImageFormatTraits<RGB8>::ComponentType(0);
00222 outputPixel.blue = ImageFormatTraits<RGB8>::ComponentType(0);
00223 }
00224 }
00225
00226
00227 template<>
00228 inline
00229 void
00230 ColorspaceConverter<GRAY8, RGB8>::
00231 operator()(const Image<GRAY8>::PixelType& inputPixel,
00232 Image<RGB8>::PixelType& outputPixel)
00233 {
00234 outputPixel.red = inputPixel;
00235 outputPixel.green = inputPixel;
00236 outputPixel.blue = inputPixel;
00237 }
00238
00239
00240 template<>
00241 inline
00242 void
00243 ColorspaceConverter<RGB8, GRAY8>::
00244 operator()(const Image<RGB8>::PixelType& inputPixel,
00245 Image<GRAY8>::PixelType& outputPixel)
00246 {
00247 double accumulator = (0.3 * inputPixel.red
00248 + 0.59 * inputPixel.green
00249 + 0.11 * inputPixel.blue);
00250 outputPixel = static_cast<Image<GRAY8>::PixelType>(accumulator + 0.5);
00251 }
00252
00253
00254 template<>
00255 inline
00256 void
00257 ColorspaceConverter<RGB8, GRAY_FLOAT64>::
00258 operator()(const Image<RGB8>::PixelType& inputPixel,
00259 Image<GRAY_FLOAT64>::PixelType& outputPixel)
00260 {
00261 double accumulator = (0.3 * inputPixel.red
00262 + 0.59 * inputPixel.green
00263 + 0.11 * inputPixel.blue);
00264 outputPixel =
00265 static_cast<Image<GRAY_FLOAT64>::PixelType>(accumulator + 0.5);
00266 }
00267
00268
00269 template<>
00270 inline
00271 void
00272 ColorspaceConverter<RGB8, RGB16>::
00273 operator()(const Image<RGB8>::PixelType& inputPixel,
00274 Image<RGB16>::PixelType& outputPixel)
00275 {
00276 outputPixel.red = static_cast<UnsignedInt16>(inputPixel.red);
00277 outputPixel.green = static_cast<UnsignedInt16>(inputPixel.green);
00278 outputPixel.blue = static_cast<UnsignedInt16>(inputPixel.blue);
00279 }
00280
00281
00282 template<>
00283 inline
00284 void
00285 ColorspaceConverter<RGB8, RGB_FLOAT32>::
00286 operator()(const Image<RGB8>::PixelType& inputPixel,
00287 Image<RGB_FLOAT32>::PixelType& outputPixel)
00288 {
00289 outputPixel.red = static_cast<Float32>(inputPixel.red);
00290 outputPixel.green = static_cast<Float32>(inputPixel.green);
00291 outputPixel.blue = static_cast<Float32>(inputPixel.blue);
00292 }
00293
00294
00295 template<>
00296 inline
00297 void
00298 ColorspaceConverter<RGB8, RGB_FLOAT64>::
00299 operator()(const Image<RGB8>::PixelType& inputPixel,
00300 Image<RGB_FLOAT64>::PixelType& outputPixel)
00301 {
00302 outputPixel.red = static_cast<Float64>(inputPixel.red);
00303 outputPixel.green = static_cast<Float64>(inputPixel.green);
00304 outputPixel.blue = static_cast<Float64>(inputPixel.blue);
00305 }
00306
00307
00308 template<>
00309 inline
00310 void
00311 ColorspaceConverter<RGB_FLOAT32, RGB8>::
00312 operator()(const Image<RGB_FLOAT32>::PixelType& inputPixel,
00313 Image<RGB8>::PixelType& outputPixel)
00314 {
00315 outputPixel.red = static_cast<UnsignedInt8>(inputPixel.red + 0.5);
00316 outputPixel.green = static_cast<UnsignedInt8>(inputPixel.green + 0.5);
00317 outputPixel.blue = static_cast<UnsignedInt8>(inputPixel.blue + 0.5);
00318 }
00319
00320
00321 template<>
00322 inline
00323 void
00324 ColorspaceConverter<RGB8, HSV_FLOAT64>::
00325 operator()(const Image<RGB8>::PixelType& inputPixel,
00326 Image<HSV_FLOAT64>::PixelType& outputPixel)
00327 {
00328
00329
00330
00331
00332
00333 privateCode::doColorspaceConversion(
00334 Image<RGB_FLOAT64>::PixelType(inputPixel.red, inputPixel.green,
00335 inputPixel.blue),
00336 outputPixel);
00337
00338
00339 outputPixel.value /= 255.0;
00340 }
00341
00342
00343 template<>
00344 inline
00345 void
00346 ColorspaceConverter<RGB8, YIQ_FLOAT64>::
00347 operator()(const Image<RGB8>::PixelType& inputPixel,
00348 Image<YIQ_FLOAT64>::PixelType& outputPixel)
00349 {
00350 outputPixel.luma = ((0.299 / 255.0) * inputPixel.red
00351 + (0.587 / 255.0) * inputPixel.green
00352 + (0.114 / 255.0) * inputPixel.blue);
00353 outputPixel.inPhase = ((0.595716 / 255.0)* inputPixel.red
00354 - (0.274453 / 255.0) * inputPixel.green
00355 - (0.321263 / 255.0) * inputPixel.blue);
00356 outputPixel.quadrature = ((0.211456 / 255.0) * inputPixel.red
00357 - (0.522591 / 255.0) * inputPixel.green
00358 + (0.311135 / 255.0) * inputPixel.blue);
00359 }
00360
00361
00362 template<>
00363 inline
00364 void
00365 ColorspaceConverter<RGB8, BGRA8>::
00366 operator()(const Image<RGB8>::PixelType& inputPixel,
00367 Image<BGRA8>::PixelType& outputPixel)
00368 {
00369 outputPixel.red = inputPixel.red;
00370 outputPixel.green = inputPixel.green;
00371 outputPixel.blue = inputPixel.blue;
00372 outputPixel.alpha = UnsignedInt8(255);
00373 }
00374
00375
00376 template<>
00377 inline
00378 void
00379 ColorspaceConverter<RGB8, RGBA8>::
00380 operator()(const Image<RGB8>::PixelType& inputPixel,
00381 Image<RGBA8>::PixelType& outputPixel)
00382 {
00383 outputPixel.red = inputPixel.red;
00384 outputPixel.green = inputPixel.green;
00385 outputPixel.blue = inputPixel.blue;
00386 outputPixel.alpha = UnsignedInt8(255);
00387 }
00388
00389
00390 template<>
00391 inline
00392 void
00393 ColorspaceConverter<RGB16, RGB8>::
00394 operator()(const Image<RGB16>::PixelType& inputPixel,
00395 Image<RGB8>::PixelType& outputPixel)
00396 {
00397 outputPixel.red = static_cast<UnsignedInt8>(inputPixel.red);
00398 outputPixel.green = static_cast<UnsignedInt8>(inputPixel.green);
00399 outputPixel.blue = static_cast<UnsignedInt8>(inputPixel.blue);
00400 }
00401
00402
00403 template<>
00404 inline
00405 void
00406 ColorspaceConverter<RGB_FLOAT32, GRAY8>::
00407 operator()(const Image<RGB_FLOAT32>::PixelType& inputPixel,
00408 Image<GRAY8>::PixelType& outputPixel)
00409 {
00410 double accumulator = (inputPixel.red * inputPixel.red
00411 + inputPixel.green * inputPixel.green
00412 + inputPixel.blue * inputPixel.blue) / 3.0;
00413 outputPixel =
00414 static_cast<Image<GRAY8>::PixelType>(std::sqrt(accumulator) + 0.5);
00415 }
00416
00417
00418
00419 template<>
00420 inline
00421 void
00422 ColorspaceConverter<RGB_FLOAT64, HSV_FLOAT64>::
00423 operator()(const Image<RGB_FLOAT64>::PixelType& inputPixel,
00424 Image<HSV_FLOAT64>::PixelType& outputPixel)
00425 {
00426 privateCode::doColorspaceConversion(inputPixel, outputPixel);
00427 }
00428
00429
00430 template<>
00431 inline
00432 void
00433 ColorspaceConverter<RGB_FLOAT64, YIQ_FLOAT64>::
00434 operator()(const Image<RGB_FLOAT64>::PixelType& inputPixel,
00435 Image<YIQ_FLOAT64>::PixelType& outputPixel)
00436 {
00437 outputPixel.luma = (0.299 * inputPixel.red
00438 + 0.587 * inputPixel.green
00439 + 0.114 * inputPixel.blue);
00440 outputPixel.inPhase = (0.595716 * inputPixel.red
00441 - 0.274453 * inputPixel.green
00442 - 0.321263 * inputPixel.blue);
00443 outputPixel.quadrature = (0.211456 * inputPixel.red
00444 - 0.522591 * inputPixel.green
00445 + 0.311135 * inputPixel.blue);
00446 }
00447
00448
00449 template<>
00450 inline
00451 void
00452 ColorspaceConverter<BGRA8, RGB8>::
00453 operator()(const Image<BGRA8>::PixelType& inputPixel,
00454 Image<RGB8>::PixelType& outputPixel)
00455 {
00456 outputPixel.red = inputPixel.red;
00457 outputPixel.green = inputPixel.green;
00458 outputPixel.blue = inputPixel.blue;
00459 }
00460
00461
00462 template<>
00463 inline
00464 void
00465 ColorspaceConverter<RGBA8, RGB8>::
00466 operator()(const Image<RGBA8>::PixelType& inputPixel,
00467 Image<RGB8>::PixelType& outputPixel)
00468 {
00469 outputPixel.red = inputPixel.red;
00470 outputPixel.green = inputPixel.green;
00471 outputPixel.blue = inputPixel.blue;
00472 }
00473
00474 }
00475
00476 }
00477
00478 #endif