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 = (inputPixel.red * inputPixel.red
00174 + inputPixel.green * inputPixel.green
00175 + inputPixel.blue * inputPixel.blue) / 3.0;
00176 outputPixel =
00177 static_cast<Image<GRAY8>::PixelType>(std::sqrt(accumulator) + 0.5);
00178 }
00179
00180
00181 template<>
00182 inline
00183 void
00184 ColorspaceConverter<RGB8, RGB16>::
00185 operator()(const Image<RGB8>::PixelType& inputPixel,
00186 Image<RGB16>::PixelType& outputPixel)
00187 {
00188 outputPixel.red = static_cast<UnsignedInt16>(inputPixel.red);
00189 outputPixel.green = static_cast<UnsignedInt16>(inputPixel.green);
00190 outputPixel.blue = static_cast<UnsignedInt16>(inputPixel.blue);
00191 }
00192
00193
00194 template<>
00195 inline
00196 void
00197 ColorspaceConverter<RGB8, RGB_FLOAT32>::
00198 operator()(const Image<RGB8>::PixelType& inputPixel,
00199 Image<RGB_FLOAT32>::PixelType& outputPixel)
00200 {
00201 outputPixel.red = static_cast<Float32>(inputPixel.red);
00202 outputPixel.green = static_cast<Float32>(inputPixel.green);
00203 outputPixel.blue = static_cast<Float32>(inputPixel.blue);
00204 }
00205
00206
00207 template<>
00208 inline
00209 void
00210 ColorspaceConverter<RGB8, RGB_FLOAT64>::
00211 operator()(const Image<RGB8>::PixelType& inputPixel,
00212 Image<RGB_FLOAT64>::PixelType& outputPixel)
00213 {
00214 outputPixel.red = static_cast<Float64>(inputPixel.red);
00215 outputPixel.green = static_cast<Float64>(inputPixel.green);
00216 outputPixel.blue = static_cast<Float64>(inputPixel.blue);
00217 }
00218
00219
00220 template<>
00221 inline
00222 void
00223 ColorspaceConverter<RGB8, HSV_FLOAT64>::
00224 operator()(const Image<RGB8>::PixelType& inputPixel,
00225 Image<HSV_FLOAT64>::PixelType& outputPixel)
00226 {
00227
00228 Float64 maxVal = static_cast<Float64>(
00229 std::max(inputPixel.red, std::max(inputPixel.green, inputPixel.blue)));
00230 outputPixel.value = maxVal;
00231
00232
00233 if(maxVal == 0.0) {
00234 outputPixel.hue = Float64(0.0);
00235 outputPixel.saturation = Float64(0.0);
00236 return;
00237 }
00238
00239
00240 Float64 minVal = static_cast<Float64>(
00241 std::min(inputPixel.red, std::min(inputPixel.green, inputPixel.blue)));
00242 Float64 delta = maxVal - minVal;
00243 outputPixel.saturation = delta / maxVal;
00244
00245
00246 if(delta == 0.0) {
00247 outputPixel.hue = Float64(0.0);
00248 return;
00249 }
00250
00251
00252
00253 if(inputPixel.red == maxVal) {
00254 outputPixel.hue =
00255 Float64(1.0 / 6.0)
00256 + (static_cast<Float64>(inputPixel.green)
00257 - static_cast<Float64>(inputPixel.blue)) / (6.0 * delta);
00258 } else if(inputPixel.green == maxVal) {
00259 outputPixel.hue =
00260 Float64(0.5)
00261 + (static_cast<Float64>(inputPixel.blue)
00262 - static_cast<Float64>(inputPixel.red)) / (6.0 * delta);
00263 } else {
00264 outputPixel.hue =
00265 Float64(5.0 / 6.0)
00266 + (static_cast<Float64>(inputPixel.red)
00267 - static_cast<Float64>(inputPixel.green)) / (6.0 * delta);
00268 }
00269 }
00270
00271
00272 template<>
00273 inline
00274 void
00275 ColorspaceConverter<RGB8, BGRA8>::
00276 operator()(const Image<RGB8>::PixelType& inputPixel,
00277 Image<BGRA8>::PixelType& outputPixel)
00278 {
00279 outputPixel.red = inputPixel.red;
00280 outputPixel.green = inputPixel.green;
00281 outputPixel.blue = inputPixel.blue;
00282 outputPixel.alpha = UnsignedInt8(255);
00283 }
00284
00285
00286 template<>
00287 inline
00288 void
00289 ColorspaceConverter<RGB8, RGBA8>::
00290 operator()(const Image<RGB8>::PixelType& inputPixel,
00291 Image<RGBA8>::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<RGB16, RGB8>::
00304 operator()(const Image<RGB16>::PixelType& inputPixel,
00305 Image<RGB8>::PixelType& outputPixel)
00306 {
00307 outputPixel.red = static_cast<UnsignedInt8>(inputPixel.red);
00308 outputPixel.green = static_cast<UnsignedInt8>(inputPixel.green);
00309 outputPixel.blue = static_cast<UnsignedInt8>(inputPixel.blue);
00310 }
00311
00312
00313 template<>
00314 inline
00315 void
00316 ColorspaceConverter<RGB_FLOAT32, GRAY8>::
00317 operator()(const Image<RGB_FLOAT32>::PixelType& inputPixel,
00318 Image<GRAY8>::PixelType& outputPixel)
00319 {
00320 double accumulator = (inputPixel.red * inputPixel.red
00321 + inputPixel.green * inputPixel.green
00322 + inputPixel.blue * inputPixel.blue) / 3.0;
00323 outputPixel =
00324 static_cast<Image<GRAY8>::PixelType>(std::sqrt(accumulator) + 0.5);
00325 }
00326
00327
00328
00329 template<>
00330 inline
00331 void
00332 ColorspaceConverter<RGB_FLOAT64, HSV_FLOAT64>::
00333 operator()(const Image<RGB_FLOAT64>::PixelType& inputPixel,
00334 Image<HSV_FLOAT64>::PixelType& outputPixel)
00335 {
00336
00337 Float64 maxVal = static_cast<Float64>(
00338 std::max(inputPixel.red, std::max(inputPixel.green, inputPixel.blue)));
00339 outputPixel.value = maxVal;
00340
00341
00342 if(maxVal == 0.0) {
00343 outputPixel.hue = Float64(0.0);
00344 outputPixel.saturation = Float64(0.0);
00345 return;
00346 }
00347
00348
00349 Float64 minVal = static_cast<Float64>(
00350 std::min(inputPixel.red, std::min(inputPixel.green, inputPixel.blue)));
00351 Float64 delta = maxVal - minVal;
00352 outputPixel.saturation = delta / maxVal;
00353
00354
00355 if(delta == 0.0) {
00356 outputPixel.hue = Float64(0.0);
00357 return;
00358 }
00359
00360
00361
00362 if(inputPixel.red == maxVal) {
00363 outputPixel.hue =
00364 Float64(1.0 / 6.0)
00365 + (static_cast<Float64>(inputPixel.green)
00366 - static_cast<Float64>(inputPixel.blue)) / (6.0 * delta);
00367 } else if(inputPixel.green == maxVal) {
00368 outputPixel.hue =
00369 Float64(0.5)
00370 + (static_cast<Float64>(inputPixel.blue)
00371 - static_cast<Float64>(inputPixel.red)) / (6.0 * delta);
00372 } else {
00373 outputPixel.hue =
00374 Float64(5.0 / 6.0)
00375 + (static_cast<Float64>(inputPixel.red)
00376 - static_cast<Float64>(inputPixel.green)) / (6.0 * delta);
00377 }
00378 }
00379
00380
00381 template<>
00382 inline
00383 void
00384 ColorspaceConverter<BGRA8, RGB8>::
00385 operator()(const Image<BGRA8>::PixelType& inputPixel,
00386 Image<RGB8>::PixelType& outputPixel)
00387 {
00388 outputPixel.red = inputPixel.red;
00389 outputPixel.green = inputPixel.green;
00390 outputPixel.blue = inputPixel.blue;
00391 }
00392
00393
00394 template<>
00395 inline
00396 void
00397 ColorspaceConverter<RGBA8, RGB8>::
00398 operator()(const Image<RGBA8>::PixelType& inputPixel,
00399 Image<RGB8>::PixelType& outputPixel)
00400 {
00401 outputPixel.red = inputPixel.red;
00402 outputPixel.green = inputPixel.green;
00403 outputPixel.blue = inputPixel.blue;
00404 }
00405
00406 }
00407
00408 }
00409
00410 #endif