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