dlrComputerVision/utilities.h

Go to the documentation of this file.
00001 
00015 #ifndef _DLRCOMPUTERVISION_UTILITIES_H_
00016 #define _DLRCOMPUTERVISION_UTILITIES_H_
00017 
00018 #include <dlrComputerVision/colorspaceConverter.h>
00019 #include <dlrComputerVision/image.h>
00020 
00021 namespace dlr {
00022 
00023   namespace computerVision {
00024     
00071     template<ImageFormat FORMAT>
00072     bool
00073     associateColorComponents(
00074       Array2D<typename ImageFormatTraits<FORMAT>::ComponentType>& inputArray,
00075       Image<FORMAT>& outputImage);
00076 
00077 
00098     template<ImageFormat FORMAT>
00099     Image<FORMAT>
00100     associateColorComponents(
00101       Array2D<typename ImageFormatTraits<FORMAT>::ComponentType>& inputArray);
00102 
00103 
00125     template<ImageFormat OUTPUT_FORMAT, ImageFormat INPUT_FORMAT>
00126     Image<OUTPUT_FORMAT>
00127     convertColorspace(const Image<INPUT_FORMAT>& inputImage);
00128 
00129 
00176     template<ImageFormat FORMAT>
00177     bool
00178     dissociateColorComponents(
00179       Image<FORMAT>& inputImage,
00180       Array2D<typename ImageFormatTraits<FORMAT>::ComponentType>& outputArray);
00181 
00182 
00205     template<ImageFormat FORMAT>
00206     Array2D<typename ImageFormatTraits<FORMAT>::ComponentType>
00207     dissociateColorComponents(Image<FORMAT>& inputImage);
00208 
00209 
00237     template<ImageFormat Format>
00238     Image<Format>
00239     subsample(const Image<Format>& inputImage,
00240               size_t rowStep = 2,
00241               size_t columnStep = 2);
00242 
00243 
00244 #if 0
00245 
00262     template<ImageFormat InputFormat,
00263              ImageFormat OutputFormat,
00264              ImageFormat IntermediateFormat>
00265     Image<OutputFormat>
00266     supersample(const Image<InputFormat>& inputImage,
00267                 typename ImageFormatTraits<OutputFormat>::PixelType,
00268                 typename ImageFormatTraits<IntermediateFormat>::PixelType);
00269 #endif
00270   
00271     
00286     template <class Type, ImageFormat FORMAT>
00287     Array2D<Type>
00288     toArray(const Image<FORMAT>& inputImage);
00289 
00290   } // namespace computerVision    
00291 
00292 } // namespace dlr
00293 
00294 
00295 /* ============ Definitions of inline & template functions ============ */
00296 
00297 
00298 namespace dlr {
00299 
00300   namespace computerVision {
00301 
00303     namespace privateCode {
00304 
00305       // This function simplifies template specialization of
00306       // associateColorComponents, which makes things easier on the
00307       // compiler.
00308       template<ImageFormat Format, class ComponentType>
00309       inline bool
00310       associateColorComponents(
00311         Array2D<ComponentType>& inputArray,
00312         Image<Format>& outputImage)
00313       {
00314         // Some typedefs for notational convenience.
00315         typedef typename ImageFormatTraits<Format>::PixelType PixelType;
00316         typedef typename Image<Format>::iterator ImageIterator;
00317         typedef typename Array2D<ComponentType>::iterator ArrayIterator;
00318       
00319         // Argument checking.
00320         if(inputArray.columns()
00321            % ImageFormatTraits<Format>::getNumberOfComponents()
00322            != 0) {
00323           DLR_THROW(ValueException, "associateColorComponents()",
00324                     "Input image must have a number of columns which is "
00325                     "evenly divisible by the number of color components.");
00326         }
00327 
00328         // Calculate output image width.
00329         size_t numberOfOutputColumns = inputArray.columns()
00330           / ImageFormatTraits<Format>::getNumberOfComponents();
00331 
00332         bool returnValue;
00333         if(PixelType::isContiguous()) {
00334           // Build the output image.
00335           outputImage = Image<Format>(
00336             inputArray.rows(), numberOfOutputColumns,
00337             reinterpret_cast<PixelType*>(inputArray.data()));
00338           returnValue = true;
00339         } else {
00340           if(outputImage.rows() != inputArray.rows()
00341              || outputImage.columns() != numberOfOutputColumns) {
00342             outputImage = Image<Format>(
00343               inputArray.rows(), numberOfOutputColumns);
00344           }
00345           ArrayIterator arrayIterator = inputArray.begin();
00346           for(ImageIterator imageIterator = outputImage.begin();
00347               imageIterator != outputImage.end(); ++imageIterator) {
00348             imageIterator->copyFromIterator(arrayIterator);
00349             ++imageIterator;
00350           }
00351           returnValue = false;
00352         }
00353         return returnValue;
00354       }
00355 
00356   
00357       // Explicit specializations of
00358       // privateCode::associateColorComponents() are needed for those
00359       // image formats which use builtin types as pixels.
00360       template<>
00361       inline bool
00362       associateColorComponents(
00363         Array2D<bool>& inputArray,
00364         Image<GRAY1>& outputImage)
00365       {
00366         outputImage = inputArray;
00367         return true;
00368       }
00369 
00370 
00371       template<>
00372       inline bool
00373       associateColorComponents(Array2D<UnsignedInt8>& inputArray,
00374                                Image<GRAY8>& outputImage)
00375       {
00376         outputImage = inputArray;
00377         return true;
00378       }
00379 
00380     
00381       template<>
00382       inline bool
00383       associateColorComponents(Array2D<UnsignedInt16>& inputArray,
00384                                Image<GRAY16>& outputImage)
00385       {
00386         outputImage = inputArray;
00387         return true;
00388       }
00389 
00390     
00391       template<>
00392       inline bool
00393       associateColorComponents(Array2D<UnsignedInt32>& inputArray,
00394                                Image<GRAY32>& outputImage)
00395       {
00396         outputImage = inputArray;
00397         return true;
00398       }
00399 
00400     
00401       template<>
00402       inline bool
00403       associateColorComponents(Array2D<Int16>& inputArray,
00404                                Image<GRAY_SIGNED16>& outputImage)
00405       {
00406         outputImage = inputArray;
00407         return true;
00408       }
00409 
00410     
00411       template<>
00412       inline bool
00413       associateColorComponents(Array2D<Int32>& inputArray,
00414                                Image<GRAY_SIGNED32>& outputImage)
00415       {
00416         outputImage = inputArray;
00417         return true;
00418       }
00419 
00420     
00421       template<>
00422       inline bool
00423       associateColorComponents(Array2D<Float32>& inputArray,
00424                                Image<GRAY_FLOAT32>& outputImage)
00425       {
00426         outputImage = inputArray;
00427         return true;
00428       }
00429 
00430     
00431       template<>
00432       inline bool
00433       associateColorComponents(Array2D<Float64>& inputArray,
00434                                Image<GRAY_FLOAT64>& outputImage)
00435       {
00436         outputImage = inputArray;
00437         return true;
00438       }
00439 
00440       // This function returns by reference an array which either shares
00441       // or copies the data from the input image.
00442       template<ImageFormat Format, class ComponentType>
00443       inline bool
00444       dissociateColorComponents(
00445         Image<Format>& inputImage,
00446         Array2D<ComponentType>& outputArray)
00447       {
00448         // Some typedefs for notational convenience.
00449         typedef typename ImageFormatTraits<Format>::PixelType PixelType;
00450         typedef typename Image<Format>::iterator ImageIterator;
00451         typedef typename Array2D<ComponentType>::iterator ArrayIterator;
00452 
00453         // Calculate output array width.
00454         size_t numberOfOutputColumns = inputImage.columns()
00455           * ImageFormatTraits<Format>::getNumberOfComponents();
00456     
00457         // Now build the output array.
00458         bool returnValue;
00459         if(PixelType::isContiguous()) {
00460           outputArray = Array2D<ComponentType>(
00461             inputImage.rows(), numberOfOutputColumns,
00462             reinterpret_cast<ComponentType*>(inputImage.data()));
00463           returnValue = true;
00464         } else {
00465           if(outputArray.rows() != inputImage.rows()
00466              || outputArray.columns() != numberOfOutputColumns) {
00467             outputArray = Array2D<ComponentType>(
00468               inputImage.rows(), numberOfOutputColumns);
00469           }
00470           ArrayIterator arrayIterator = outputArray.begin();
00471           for(ImageIterator imageIterator = inputImage.begin();
00472               imageIterator != inputImage.end(); ++imageIterator) {
00473             imageIterator->copyToIterator(arrayIterator);
00474             ++imageIterator;
00475           }
00476           returnValue = false;
00477         }
00478         return returnValue;
00479       }
00480   
00481   
00482       // Explicit specializations of dissociateColorComponents() are needed
00483       // for those image formats which use builtin types as pixels.
00484       template<>
00485       inline bool
00486       dissociateColorComponents(Image<GRAY1>& inputImage,
00487                                 Array2D<bool>& outputArray)
00488       {
00489         outputArray = inputImage;
00490         return true;
00491       }
00492 
00493     
00494       template<>
00495       inline bool
00496       dissociateColorComponents(Image<GRAY8>& inputImage,
00497                                 Array2D<UnsignedInt8>& outputArray)
00498       {
00499         outputArray = inputImage;
00500         return true;
00501       }
00502 
00503     
00504       template<>
00505       inline bool
00506       dissociateColorComponents(Image<GRAY16>& inputImage,
00507                                 Array2D<UnsignedInt16>& outputArray)
00508       {
00509         outputArray = inputImage;
00510         return true;
00511       }
00512 
00513     
00514       template<>
00515       inline bool
00516       dissociateColorComponents(Image<GRAY32>& inputImage,
00517                                 Array2D<UnsignedInt32>& outputArray)
00518       {
00519         outputArray = inputImage;
00520         return true;
00521       }
00522 
00523     
00524       template<>
00525       inline bool
00526       dissociateColorComponents(Image<GRAY_SIGNED16>& inputImage,
00527                                 Array2D<Int16>& outputArray)
00528       {
00529         outputArray = inputImage;
00530         return true;
00531       }
00532 
00533     
00534       template<>
00535       inline bool
00536       dissociateColorComponents(Image<GRAY_SIGNED32>& inputImage,
00537                                 Array2D<Int32>& outputArray)
00538       {
00539         outputArray = inputImage;
00540         return true;
00541       }
00542 
00543     
00544       template<>
00545       inline bool
00546       dissociateColorComponents(Image<GRAY_FLOAT32>& inputImage,
00547                                 Array2D<Float32>& outputArray)
00548       {
00549         outputArray = inputImage;
00550         return true;
00551       }
00552 
00553     
00554       template<>
00555       inline bool
00556       dissociateColorComponents(Image<GRAY_FLOAT64>& inputImage,
00557                                 Array2D<Float64>& outputArray)
00558       {
00559         outputArray = inputImage;
00560         return true;
00561       }
00562 
00563     } // namespace privateCode
00565 
00566 
00567     // This function returns by reference an image which either shares
00568     // or copies the data from the input array.
00569     template<ImageFormat FORMAT>
00570     bool
00571     associateColorComponents(
00572       Array2D<typename ImageFormatTraits<FORMAT>::ComponentType>& inputArray,
00573       Image<FORMAT>& outputImage)
00574     {
00575       return privateCode::associateColorComponents(inputArray, outputImage);
00576     }
00577 
00578     
00579     // This deprecated function tries to return an Image which
00580     // references the same memory as the input array, but in which each
00581     // pixel is the aggregate of the appropriate number of elements from
00582     // the array.  If it is not possible to do so, then this function
00583     template<ImageFormat FORMAT>
00584     Image<FORMAT>
00585     associateColorComponents(
00586       Array2D<typename ImageFormatTraits<FORMAT>::ComponentType>& inputArray)
00587     {
00588       typedef typename ImageFormatTraits<FORMAT>::PixelType PixelType;
00589       if(!PixelType::isContiguous()) {
00590         DLR_THROW(dlr::LogicException, "associateColorComponents()",
00591                   "The deprecated single-argument version of "
00592                   "associateColorComponents() can only be use with "
00593                   "contiguous pixel types.");
00594       }
00595 
00596       Image<FORMAT> outputImage;
00597       associateColorComponents(inputArray, outputImage);
00598       return outputImage;
00599     }
00600 
00601 
00602     // This function takes an image in one colorspace and generates a
00603     // corresponding image in a second colorspace.
00604     template<ImageFormat OUTPUT_FORMAT, ImageFormat INPUT_FORMAT>
00605     Image<OUTPUT_FORMAT>
00606     convertColorspace(const Image<INPUT_FORMAT>& inputImage)
00607     {
00608       Image<OUTPUT_FORMAT> outputImage(
00609         inputImage.rows(), inputImage.columns());
00610       ColorspaceConverter<INPUT_FORMAT, OUTPUT_FORMAT> converter;
00611       std::transform(inputImage.begin(), inputImage.end(),
00612                      outputImage.begin(), converter);
00613       return outputImage;
00614     }
00615 
00616 
00617     // This function returns by reference an array which either shares
00618     // or copies the data from the input image.
00619     template<ImageFormat FORMAT>
00620     bool
00621     dissociateColorComponents(
00622       Image<FORMAT>& inputImage,
00623       Array2D<typename ImageFormatTraits<FORMAT>::ComponentType>& outputArray)
00624     {
00625       return privateCode::dissociateColorComponents(inputImage, outputArray);
00626     }
00627   
00628 
00629     // This deprecated function tries to return an Array2D which
00630     // references the same memory as the input image, but in which each
00631     // pixel has been "flattened" so that the returned array has a
00632     // separate element for each color component of each pixel.  If it
00633     template<ImageFormat FORMAT>
00634     Array2D<typename ImageFormatTraits<FORMAT>::ComponentType>
00635     dissociateColorComponents(Image<FORMAT>& inputImage)
00636     {
00637       typedef typename ImageFormatTraits<FORMAT>::PixelType PixelType;
00638       if(!PixelType::isContiguous()) {
00639         DLR_THROW(dlr::LogicException, "dissociateColorComponents()",
00640                   "The deprecated single-argument version of "
00641                   "dissociateColorComponents() can only be use with "
00642                   "contiguous pixel types.");
00643       }
00644       Array2D<typename ImageFormatTraits<FORMAT>::ComponentType> outputArray;
00645       dissociateColorComponents(inputImage, outputArray);
00646       return outputArray;
00647     }
00648 
00649   
00650     // This function subsamples its input to create a new, smaller
00651     // image.
00652     template<ImageFormat Format>
00653     Image<Format>
00654     subsample(const Image<Format>& inputImage,
00655               size_t rowStep,
00656               size_t columnStep)
00657     {
00658       Image<Format> outputImage(inputImage.rows() / rowStep,
00659                                 inputImage.columns() / columnStep);
00660       for(size_t outputRowIndex = 0; outputRowIndex < outputImage.rows();
00661           ++outputRowIndex) {
00662         Array1D<typename Image<Format>::PixelType> inputRow =
00663           inputImage.row(rowStep * outputRowIndex);
00664         Array1D<typename Image<Format>::PixelType> outputRow =
00665           outputImage.row(outputRowIndex);
00666         size_t inputColumnIndex = 0;
00667         for(size_t outputColumnIndex = 0;
00668             outputColumnIndex < outputImage.columns();
00669             ++outputColumnIndex) {
00670           outputRow[outputColumnIndex] = inputRow[inputColumnIndex];
00671           inputColumnIndex += columnStep;
00672         }
00673       }
00674       return outputImage;
00675     }
00676 
00677 
00678 #if 0
00679     // This function interpolates its input to create a new, larger
00680     // image.
00681     template<ImageFormat InputFormat,
00682              ImageFormat OutputFormat,
00683              ImageFormat IntermediateFormat>
00684     Image<OutputFormat>
00685     supersample(const Image<InputFormat>& inputImage,
00686                 typename ImageFormatTraits<OutputFormat>::PixelType,
00687                 typename ImageFormatTraits<IntermediateFormat>::PixelType)
00688     {
00689       Image<OutputFormat> outputImage(inputImage.rows() * 2,
00690                                       inputImage.columns() * 2);
00691       for(size_t inputRowIndex = 0; inputRowIndex < inputImage.rows();
00692           ++inputRowIndex) {
00693         Array1D<typename Image<InputFormat>::PixelType> inputRow0 =
00694           inputImage.row(inputRowIndex);
00695         Array1D<typename Image<InputFormat>::PixelType> inputRow1 =
00696           inputImage.row(inputRowIndex + 1);
00697         Array1D<typename Image<OutputFormat>::PixelType> outputRow0 =
00698           outputImage.row(2 * inputRowIndex);
00699         Array1D<typename Image<OutputFormat>::PixelType> outputRow1 =
00700           outputImage.row(2 * inputRowIndex + 1);
00701         size_t outputColumnIndex = 0;
00702         for(size_t inputColumnIndex = 0;
00703             inputColumnIndex < inputImage.columns();
00704             ++inputColumnIndex) {
00705           typename ImageFormatTraits<IntermediateFormat>::PixelType tempPixel;
00706         
00707           outputRow0[outputColumnIndex] = inputRow0[inputColumnIndex];
00708         
00709           tempPixel = inputRow0[inputColumnIndex];
00710           tempPixel += inputRow0[inputColumnIndex + 1];
00711           tempPixel /= 2;
00712           outputRow0[outputColumnIndex + 1] = tempPixel;
00713 
00714           tempPixel = inputRow0[inputColumnIndex];
00715           tempPixel += inputRow1[inputColumnIndex];
00716           tempPixel /= 2;
00717           outputRow1[outputColumnIndex] = tempPixel;
00718 
00719           tempPixel = inputRow0[inputColumnIndex];
00720           tempPixel += inputRow0[inputColumnIndex + 1];
00721           tempPixel += inputRow1[inputColumnIndex];
00722           tempPixel += inputRow1[inputColumnIndex + 1];
00723           tempPixel /= 4;
00724           outputRow1[outputColumnIndex + 1] = tempPixel;
00725 
00726           outputColumnIndex += 2;
00727         }
00728       }
00729       return outputImage;
00730     }
00731 #endif
00732   
00733 
00734     // This function creates a new array and copies into it the pixel
00735     // data from the input image.
00736     template <class Type, ImageFormat FORMAT>
00737     Array2D<Type>
00738     toArray(const Image<FORMAT>& inputImage)
00739     {
00740       // A typedef for notational convenience.
00741       typedef typename ImageFormatTraits<FORMAT>::ComponentType ComponentType;
00742 
00743       size_t numberOfOutputColumns = inputImage.columns()
00744         * ImageFormatTraits<FORMAT>::getNumberOfComponents();
00745 
00746       Array2D<ComponentType> tempArray;
00747       dissociateColorComponents(
00748         const_cast< Image<FORMAT>& >(inputImage), tempArray);
00749 
00750       Array2D<Type> returnValue(inputImage.rows(), numberOfOutputColumns);
00751       returnValue.copy(tempArray);
00752       return returnValue;
00753     }
00754   
00755   } // namespace computerVision    
00756   
00757 } // namespace dlr
00758 
00759 #endif /* #ifndef _DLRCOMPUTERVISION_UTILITIES_H_ */

Generated on Mon Jul 9 20:34:03 2007 for dlrLibs Utility Libraries by  doxygen 1.5.2