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 = (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       // "value" is the simplest to compute... it's just the max RGB value.
00228       Float64 maxVal = static_cast<Float64>(
00229         std::max(inputPixel.red, std::max(inputPixel.green, inputPixel.blue)));
00230       outputPixel.value = maxVal;
00231     
00232       // Handle first special case up-front.
00233       if(maxVal == 0.0) {
00234         outputPixel.hue = Float64(0.0);
00235         outputPixel.saturation = Float64(0.0);
00236         return;
00237       }
00238 
00239       // Now we can compute "saturation".
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       // Handle second special case up-front.
00246       if(delta == 0.0) {
00247         outputPixel.hue = Float64(0.0);
00248         return;
00249       }
00250 
00251       // Warning(xxx): our definition of hue goes from 0.0 to 1.0, not
00252       // 0.0 to 360.0, as is traditional.
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       // "value" is the simplest to compute... it's just the max RGB value.
00337       Float64 maxVal = static_cast<Float64>(
00338         std::max(inputPixel.red, std::max(inputPixel.green, inputPixel.blue)));
00339       outputPixel.value = maxVal;
00340     
00341       // Handle first special case up-front.
00342       if(maxVal == 0.0) {
00343         outputPixel.hue = Float64(0.0);
00344         outputPixel.saturation = Float64(0.0);
00345         return;
00346       }
00347 
00348       // Now we can compute "saturation".
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       // Handle second special case up-front.
00355       if(delta == 0.0) {
00356         outputPixel.hue = Float64(0.0);
00357         return;
00358       }
00359 
00360       // Warning(xxx): our definition of hue goes from 0.0 to 1.0, not
00361       // 0.0 to 360.0, as is traditional.
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   } // namespace computerVision
00407     
00408 } // namespace dlr
00409 
00410 #endif /* #ifndef _DLRCOMPUTERVISION_COLORSPACECONVERTER_H_ */

Generated on Wed Jun 25 14:34:09 2008 for dlrComputerVision Utility Library by  doxygen 1.5.5