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 template<>
00120 inline
00121 void
00122 ColorspaceConverter<GRAY1, GRAY8>::
00123 operator()(const Image<GRAY1>::PixelType& inputPixel,
00124 Image<GRAY8>::PixelType& outputPixel)
00125 {
00126 if(inputPixel) {
00127 outputPixel = Image<GRAY8>::PixelType(255);
00128 } else {
00129 outputPixel = Image<GRAY8>::PixelType(0);
00130 }
00131 }
00132
00133
00134 template<>
00135 inline
00136 void
00137 ColorspaceConverter<GRAY1, RGB8>::
00138 operator()(const Image<GRAY1>::PixelType& inputPixel,
00139 Image<RGB8>::PixelType& outputPixel)
00140 {
00141 if(inputPixel) {
00142 outputPixel.red = ImageFormatTraits<RGB8>::ComponentType(255);
00143 outputPixel.green = ImageFormatTraits<RGB8>::ComponentType(255);
00144 outputPixel.blue = ImageFormatTraits<RGB8>::ComponentType(255);
00145 } else {
00146 outputPixel.red = ImageFormatTraits<RGB8>::ComponentType(0);
00147 outputPixel.green = ImageFormatTraits<RGB8>::ComponentType(0);
00148 outputPixel.blue = ImageFormatTraits<RGB8>::ComponentType(0);
00149 }
00150 }
00151
00152
00153 template<>
00154 inline
00155 void
00156 ColorspaceConverter<GRAY8, RGB8>::
00157 operator()(const Image<GRAY8>::PixelType& inputPixel,
00158 Image<RGB8>::PixelType& outputPixel)
00159 {
00160 outputPixel.red = inputPixel;
00161 outputPixel.green = inputPixel;
00162 outputPixel.blue = inputPixel;
00163 }
00164
00165
00166 template<>
00167 inline
00168 void
00169 ColorspaceConverter<RGB8, GRAY8>::
00170 operator()(const Image<RGB8>::PixelType& inputPixel,
00171 Image<GRAY8>::PixelType& outputPixel)
00172 {
00173 double accumulator = (0.3 * inputPixel.red
00174 + 0.59 * inputPixel.green
00175 + 0.11 * inputPixel.blue);
00176 outputPixel = static_cast<Image<GRAY8>::PixelType>(accumulator + 0.5);
00177 }
00178
00179
00180 template<>
00181 inline
00182 void
00183 ColorspaceConverter<RGB8, GRAY_FLOAT64>::
00184 operator()(const Image<RGB8>::PixelType& inputPixel,
00185 Image<GRAY_FLOAT64>::PixelType& outputPixel)
00186 {
00187 double accumulator = (0.3 * inputPixel.red
00188 + 0.59 * inputPixel.green
00189 + 0.11 * inputPixel.blue);
00190 outputPixel =
00191 static_cast<Image<GRAY_FLOAT64>::PixelType>(accumulator + 0.5);
00192 }
00193
00194
00195 template<>
00196 inline
00197 void
00198 ColorspaceConverter<RGB8, RGB16>::
00199 operator()(const Image<RGB8>::PixelType& inputPixel,
00200 Image<RGB16>::PixelType& outputPixel)
00201 {
00202 outputPixel.red = static_cast<UnsignedInt16>(inputPixel.red);
00203 outputPixel.green = static_cast<UnsignedInt16>(inputPixel.green);
00204 outputPixel.blue = static_cast<UnsignedInt16>(inputPixel.blue);
00205 }
00206
00207
00208 template<>
00209 inline
00210 void
00211 ColorspaceConverter<RGB8, RGB_FLOAT32>::
00212 operator()(const Image<RGB8>::PixelType& inputPixel,
00213 Image<RGB_FLOAT32>::PixelType& outputPixel)
00214 {
00215 outputPixel.red = static_cast<Float32>(inputPixel.red);
00216 outputPixel.green = static_cast<Float32>(inputPixel.green);
00217 outputPixel.blue = static_cast<Float32>(inputPixel.blue);
00218 }
00219
00220
00221 template<>
00222 inline
00223 void
00224 ColorspaceConverter<RGB8, RGB_FLOAT64>::
00225 operator()(const Image<RGB8>::PixelType& inputPixel,
00226 Image<RGB_FLOAT64>::PixelType& outputPixel)
00227 {
00228 outputPixel.red = static_cast<Float64>(inputPixel.red);
00229 outputPixel.green = static_cast<Float64>(inputPixel.green);
00230 outputPixel.blue = static_cast<Float64>(inputPixel.blue);
00231 }
00232
00233
00234 template<>
00235 inline
00236 void
00237 ColorspaceConverter<RGB8, HSV_FLOAT64>::
00238 operator()(const Image<RGB8>::PixelType& inputPixel,
00239 Image<HSV_FLOAT64>::PixelType& outputPixel)
00240 {
00241
00242 Float64 maxVal = static_cast<Float64>(
00243 std::max(inputPixel.red, std::max(inputPixel.green, inputPixel.blue)));
00244 outputPixel.value = maxVal;
00245
00246
00247 if(maxVal == 0.0) {
00248 outputPixel.hue = Float64(0.0);
00249 outputPixel.saturation = Float64(0.0);
00250 return;
00251 }
00252
00253
00254 Float64 minVal = static_cast<Float64>(
00255 std::min(inputPixel.red, std::min(inputPixel.green, inputPixel.blue)));
00256 Float64 delta = maxVal - minVal;
00257 outputPixel.saturation = delta / maxVal;
00258
00259
00260 if(delta == 0.0) {
00261 outputPixel.hue = Float64(0.0);
00262 return;
00263 }
00264
00265
00266
00267 if(inputPixel.red == maxVal) {
00268 outputPixel.hue =
00269 Float64(1.0 / 6.0)
00270 + (static_cast<Float64>(inputPixel.green)
00271 - static_cast<Float64>(inputPixel.blue)) / (6.0 * delta);
00272 } else if(inputPixel.green == maxVal) {
00273 outputPixel.hue =
00274 Float64(0.5)
00275 + (static_cast<Float64>(inputPixel.blue)
00276 - static_cast<Float64>(inputPixel.red)) / (6.0 * delta);
00277 } else {
00278 outputPixel.hue =
00279 Float64(5.0 / 6.0)
00280 + (static_cast<Float64>(inputPixel.red)
00281 - static_cast<Float64>(inputPixel.green)) / (6.0 * delta);
00282 }
00283 }
00284
00285
00286 template<>
00287 inline
00288 void
00289 ColorspaceConverter<RGB8, BGRA8>::
00290 operator()(const Image<RGB8>::PixelType& inputPixel,
00291 Image<BGRA8>::PixelType& outputPixel)
00292 {
00293 outputPixel.red = inputPixel.red;
00294 outputPixel.green = inputPixel.green;
00295 outputPixel.blue = inputPixel.blue;
00296 outputPixel.alpha = UnsignedInt8(255);
00297 }
00298
00299
00300 template<>
00301 inline
00302 void
00303 ColorspaceConverter<RGB8, RGBA8>::
00304 operator()(const Image<RGB8>::PixelType& inputPixel,
00305 Image<RGBA8>::PixelType& outputPixel)
00306 {
00307 outputPixel.red = inputPixel.red;
00308 outputPixel.green = inputPixel.green;
00309 outputPixel.blue = inputPixel.blue;
00310 outputPixel.alpha = UnsignedInt8(255);
00311 }
00312
00313
00314 template<>
00315 inline
00316 void
00317 ColorspaceConverter<RGB16, RGB8>::
00318 operator()(const Image<RGB16>::PixelType& inputPixel,
00319 Image<RGB8>::PixelType& outputPixel)
00320 {
00321 outputPixel.red = static_cast<UnsignedInt8>(inputPixel.red);
00322 outputPixel.green = static_cast<UnsignedInt8>(inputPixel.green);
00323 outputPixel.blue = static_cast<UnsignedInt8>(inputPixel.blue);
00324 }
00325
00326
00327 template<>
00328 inline
00329 void
00330 ColorspaceConverter<RGB_FLOAT32, GRAY8>::
00331 operator()(const Image<RGB_FLOAT32>::PixelType& inputPixel,
00332 Image<GRAY8>::PixelType& outputPixel)
00333 {
00334 double accumulator = (inputPixel.red * inputPixel.red
00335 + inputPixel.green * inputPixel.green
00336 + inputPixel.blue * inputPixel.blue) / 3.0;
00337 outputPixel =
00338 static_cast<Image<GRAY8>::PixelType>(std::sqrt(accumulator) + 0.5);
00339 }
00340
00341
00342
00343 template<>
00344 inline
00345 void
00346 ColorspaceConverter<RGB_FLOAT64, HSV_FLOAT64>::
00347 operator()(const Image<RGB_FLOAT64>::PixelType& inputPixel,
00348 Image<HSV_FLOAT64>::PixelType& outputPixel)
00349 {
00350
00351 Float64 maxVal = static_cast<Float64>(
00352 std::max(inputPixel.red, std::max(inputPixel.green, inputPixel.blue)));
00353 outputPixel.value = maxVal;
00354
00355
00356 if(maxVal == 0.0) {
00357 outputPixel.hue = Float64(0.0);
00358 outputPixel.saturation = Float64(0.0);
00359 return;
00360 }
00361
00362
00363 Float64 minVal = static_cast<Float64>(
00364 std::min(inputPixel.red, std::min(inputPixel.green, inputPixel.blue)));
00365 Float64 delta = maxVal - minVal;
00366 outputPixel.saturation = delta / maxVal;
00367
00368
00369 if(delta == 0.0) {
00370 outputPixel.hue = Float64(0.0);
00371 return;
00372 }
00373
00374
00375
00376 if(inputPixel.red == maxVal) {
00377 outputPixel.hue =
00378 Float64(1.0 / 6.0)
00379 + (static_cast<Float64>(inputPixel.green)
00380 - static_cast<Float64>(inputPixel.blue)) / (6.0 * delta);
00381 } else if(inputPixel.green == maxVal) {
00382 outputPixel.hue =
00383 Float64(0.5)
00384 + (static_cast<Float64>(inputPixel.blue)
00385 - static_cast<Float64>(inputPixel.red)) / (6.0 * delta);
00386 } else {
00387 outputPixel.hue =
00388 Float64(5.0 / 6.0)
00389 + (static_cast<Float64>(inputPixel.red)
00390 - static_cast<Float64>(inputPixel.green)) / (6.0 * delta);
00391 }
00392 }
00393
00394
00395 template<>
00396 inline
00397 void
00398 ColorspaceConverter<BGRA8, RGB8>::
00399 operator()(const Image<BGRA8>::PixelType& inputPixel,
00400 Image<RGB8>::PixelType& outputPixel)
00401 {
00402 outputPixel.red = inputPixel.red;
00403 outputPixel.green = inputPixel.green;
00404 outputPixel.blue = inputPixel.blue;
00405 }
00406
00407
00408 template<>
00409 inline
00410 void
00411 ColorspaceConverter<RGBA8, RGB8>::
00412 operator()(const Image<RGBA8>::PixelType& inputPixel,
00413 Image<RGB8>::PixelType& outputPixel)
00414 {
00415 outputPixel.red = inputPixel.red;
00416 outputPixel.green = inputPixel.green;
00417 outputPixel.blue = inputPixel.blue;
00418 }
00419
00420 }
00421
00422 }
00423
00424 #endif