colorspaceConverter.h

Go to the documentation of this file.
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         // Default rule should work for many format combinations.  We'll
00095         // specialize for the rest below.  If you try to convert between
00096         // formats where this static_cast isn't appropriate, and for
00097         // which we haven't written a specialization, then you'll either
00098         // get a compile error or an unexpected conversion result.
00099         outputPixel =
00100           static_cast<typename Image<FORMAT1>::PixelType>(inputPixel);
00101       }
00102     
00103     };
00104 
00105   } // namespace computerVision
00106   
00107 } // namespace dlr
00108 
00109 
00110 /* ============ Definitions of inline & template functions ============ */
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       // "value" is the simplest to compute... it's just the max RGB value.
00242       Float64 maxVal = static_cast<Float64>(
00243         std::max(inputPixel.red, std::max(inputPixel.green, inputPixel.blue)));
00244       outputPixel.value = maxVal;
00245     
00246       // Handle first special case up-front.
00247       if(maxVal == 0.0) {
00248         outputPixel.hue = Float64(0.0);
00249         outputPixel.saturation = Float64(0.0);
00250         return;
00251       }
00252 
00253       // Now we can compute "saturation".
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       // Handle second special case up-front.
00260       if(delta == 0.0) {
00261         outputPixel.hue = Float64(0.0);
00262         return;
00263       }
00264 
00265       // Warning(xxx): our definition of hue goes from 0.0 to 1.0, not
00266       // 0.0 to 360.0, as is traditional.
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       // "value" is the simplest to compute... it's just the max RGB value.
00351       Float64 maxVal = static_cast<Float64>(
00352         std::max(inputPixel.red, std::max(inputPixel.green, inputPixel.blue)));
00353       outputPixel.value = maxVal;
00354     
00355       // Handle first special case up-front.
00356       if(maxVal == 0.0) {
00357         outputPixel.hue = Float64(0.0);
00358         outputPixel.saturation = Float64(0.0);
00359         return;
00360       }
00361 
00362       // Now we can compute "saturation".
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       // Handle second special case up-front.
00369       if(delta == 0.0) {
00370         outputPixel.hue = Float64(0.0);
00371         return;
00372       }
00373 
00374       // Warning(xxx): our definition of hue goes from 0.0 to 1.0, not
00375       // 0.0 to 360.0, as is traditional.
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   } // namespace computerVision
00421     
00422 } // namespace dlr
00423 
00424 #endif /* #ifndef _DLRCOMPUTERVISION_COLORSPACECONVERTER_H_ */

Generated on Tue Jan 6 23:24:56 2009 for dlrComputerVision Utility Library by  doxygen 1.5.6