ImageRemapper.h

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00027 #ifndef _NONA_IMAGEREMAPPER_H
00028 #define _NONA_IMAGEREMAPPER_H
00029 
00030 
00031 #include <panodata/PanoramaData.h>
00032 #include <nona/RemappedPanoImage.h>
00033 #include <vigra_ext/impexalpha.hxx>
00034 
00035 namespace HuginBase {
00036 namespace Nona {
00037 
00038         
00040     template <typename ImageType, typename AlphaType>
00041     class SingleImageRemapper
00042     {
00043         
00044         public:
00045             SingleImageRemapper() : m_advancedOptions()
00046             {};
00047 
00052             virtual RemappedPanoImage<ImageType,AlphaType>* getRemapped(const PanoramaData & pano,
00053                                                                         const PanoramaOptions & opts,
00054                                                                         unsigned int imgNr,
00055                                                                         vigra::Rect2D outputROI,
00056                                                                         AppBase::ProgressDisplay* progress) = 0;
00057             
00058             virtual ~SingleImageRemapper() {};
00059             
00060             void setAdvancedOptions(const HuginBase::Nona::AdvancedOptions advancedOptions)
00061             {
00062                 m_advancedOptions = advancedOptions;
00063             }
00064 
00066             virtual     void release(RemappedPanoImage<ImageType,AlphaType>* d) = 0;
00067         protected:
00068             HuginBase::Nona::AdvancedOptions m_advancedOptions;
00069         
00070     };
00071 
00072 
00074     template <typename ImageType, typename AlphaType>
00075     class FileRemapper : public SingleImageRemapper<ImageType, AlphaType>
00076     {
00077         
00078     public:
00079         FileRemapper() : SingleImageRemapper<ImageType, AlphaType>()
00080         {
00081             m_remapped = 0;
00082         }
00083 
00084         virtual ~FileRemapper() {};
00085 
00086     typedef std::vector<float> LUT;
00087 
00088 
00089     public:
00091         void loadImage(const PanoramaOptions & opts,
00092                      vigra::ImageImportInfo & info, ImageType & srcImg,
00093                      AlphaType & srcAlpha)
00094             {}
00095 
00097         virtual RemappedPanoImage<ImageType, AlphaType>*
00098         getRemapped(const PanoramaData & pano, const PanoramaOptions & opts,
00099                     unsigned int imgNr, vigra::Rect2D outputROI,
00100                     AppBase::ProgressDisplay* progress);
00101 
00103         virtual void release(RemappedPanoImage<ImageType,AlphaType>* d)
00104             { delete d; }
00105 
00106 
00107     protected:
00108         RemappedPanoImage<ImageType,AlphaType> * m_remapped;
00109 
00110     };
00111 
00112 
00113 
00115     template <class FFType, class SrcIter, class SrcAccessor, class DestIter, class DestAccessor>
00116     void applyFlatfield(vigra::triple<SrcIter, SrcIter, SrcAccessor> srcImg,
00117                         vigra::pair<DestIter, DestAccessor> destImg,
00118                         vigra::ImageImportInfo & ffInfo,
00119                         double gamma,
00120                         double gammaMaxVal,
00121                         bool division,
00122                         typename vigra::NumericTraits<typename SrcAccessor::value_type>::RealPromote a,
00123                         typename vigra::NumericTraits<typename SrcAccessor::value_type>::RealPromote b,
00124                         bool dither);
00125 
00126 
00127 
00128 }; // namespace
00129 }; // namespace
00130 
00131 
00132 
00133 
00134 //==============================================================================
00135 // templated implementations
00136 
00137 
00138 #include <vigra/functorexpression.hxx>
00139 #include <vigra_ext/VignettingCorrection.h>
00140 
00141 
00142 namespace HuginBase {
00143 namespace Nona {
00144     
00145     
00146 template <typename ImageType, typename AlphaType>
00147 RemappedPanoImage<ImageType, AlphaType>*
00148     FileRemapper<ImageType,AlphaType>::getRemapped(const PanoramaData & pano, const PanoramaOptions & opts,
00149                               unsigned int imgNr, vigra::Rect2D outputROI,
00150                               AppBase::ProgressDisplay* progress)
00151 {
00152     typedef typename ImageType::value_type PixelType;
00153     
00154     //typedef typename vigra::NumericTraits<PixelType>::RealPromote RPixelType;
00155     //        typedef typename vigra::BasicImage<RPixelType> RImportImageType;
00156     typedef typename vigra::BasicImage<float> FlatImgType;
00157     
00158     FlatImgType ffImg;
00159     AlphaType srcAlpha;
00160     
00161     // choose image type...
00162     const SrcPanoImage & img = pano.getImage(imgNr);
00163     
00164     vigra::Size2D destSize(opts.getWidth(), opts.getHeight());
00165     
00166     m_remapped = new RemappedPanoImage<ImageType, AlphaType>;
00167     
00168     // load image
00169     
00170     vigra::ImageImportInfo info(img.getFilename().c_str());
00171 
00172     int width = info.width();
00173     int height = info.height();
00174 
00175     if (opts.remapUsingGPU) {
00176         // Extend image width to multiple of 8 for fast GPU transfers.
00177         const int r = width % 8;
00178         if (r != 0) width += 8 - r;
00179     }
00180 
00181     ImageType srcImg(width, height);
00182     m_remapped->m_ICCProfile = info.getICCProfile();
00183     
00184     if (info.numExtraBands() > 0) {
00185         srcAlpha.resize(width, height);
00186     }
00187     //int nb = info.numBands() - info.numExtraBands();
00188     bool alpha = info.numExtraBands() > 0;
00189     std::string type = info.getPixelType();
00190     
00191     SrcPanoImage src = pano.getSrcImage(imgNr);
00192     
00193     // import the image
00194     progress->setMessage("loading", hugin_utils::stripPath(img.getFilename()));
00195     
00196     if (alpha) {
00197         vigra::importImageAlpha(info, vigra::destImage(srcImg),
00198                                 vigra::destImage(srcAlpha));
00199     } else {
00200         vigra::importImage(info, vigra::destImage(srcImg));
00201     }
00202     // check if the image needs to be scaled to 0 .. 1,
00203     // this only works for int -> float, since the image
00204     // has already been loaded into the output container
00205     double maxv = vigra_ext::getMaxValForPixelType(info.getPixelType());
00206     if (maxv != vigra_ext::LUTTraits<PixelType>::max()) {
00207         double scale = ((double)vigra_ext::LUTTraits<PixelType>::max()) /  maxv;
00208         //std::cout << "Scaling input image (pixel type: " << info.getPixelType() << " with: " << scale << std::endl;
00209         transformImage(vigra::srcImageRange(srcImg), destImage(srcImg),
00210                        vigra::functor::Arg1()*vigra::functor::Param(scale));
00211     }
00212     
00213     // load flatfield, if needed.
00214     if (img.getVigCorrMode() & SrcPanoImage::VIGCORR_FLATFIELD) {
00215         // load flatfield image.
00216         vigra::ImageImportInfo ffInfo(img.getFlatfieldFilename().c_str());
00217         progress->setMessage("flatfield vignetting correction", hugin_utils::stripPath(img.getFilename()));
00218         vigra_precondition(( ffInfo.numBands() == 1),
00219                            "flatfield vignetting correction: "
00220                            "Only single channel flatfield images are supported\n");
00221         ffImg.resize(ffInfo.width(), ffInfo.height());
00222         vigra::importImage(ffInfo, vigra::destImage(ffImg));
00223     }
00224     m_remapped->setAdvancedOptions(SingleImageRemapper<ImageType, AlphaType>::m_advancedOptions);
00225     // remap the image
00226     
00227     remapImage(srcImg, srcAlpha, ffImg,
00228                pano.getSrcImage(imgNr), opts,
00229                outputROI,
00230                *m_remapped,
00231                progress);
00232     return m_remapped;
00233 }
00234 
00235 
00237 template <class FFType, class SrcIter, class SrcAccessor, class DestIter, class DestAccessor>
00238 void applyFlatfield(vigra::triple<SrcIter, SrcIter, SrcAccessor> srcImg,
00239                     vigra::pair<DestIter, DestAccessor> destImg,
00240                     vigra::ImageImportInfo & ffInfo,
00241                     double gamma,
00242                     double gammaMaxVal,
00243                     bool division,
00244                     typename vigra::NumericTraits<typename SrcAccessor::value_type>::RealPromote a,
00245                     typename vigra::NumericTraits<typename SrcAccessor::value_type>::RealPromote b,
00246                     bool dither)
00247 {
00248     FFType ffImg(ffInfo.width(), ffInfo.height());
00249     vigra::importImage(ffInfo, vigra::destImage(ffImg));
00250     vigra_ext::flatfieldVigCorrection(srcImg, vigra::srcImage(ffImg), 
00251                                       destImg, gamma, gammaMaxVal, division, a, b, dither);
00252 }
00253 
00254 
00255 }; // namespace
00256 }; // namespace
00257 
00258 #endif // _H

Generated on 28 Jul 2016 for Hugintrunk by  doxygen 1.4.7