ROIImage.h

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00024 #ifndef _ROIIMAGE_H
00025 #define _ROIIMAGE_H
00026 
00027 #include <hugin_utils/utils.h>
00028 #include <vigra/imageinfo.hxx>
00029 
00030 #include "lut.h"
00031 
00032 namespace vigra_ext
00033 {
00034 
00035 
00044 template <class ImgIter, class ImgAcc>
00045 vigra::triple<ImgIter, ImgIter, ImgAcc>
00046 applyRect(vigra::Rect2D & r, vigra::triple<ImgIter, ImgIter, ImgAcc> img)
00047 {
00048 #ifdef DEBUG
00049     vigra::Diff2D t = img.second - (img.first + r.lowerRight());
00050     DEBUG_ASSERT(t.x >= 0);
00051     DEBUG_ASSERT(t.y >= 0);
00052 #endif
00053     return vigra::triple<ImgIter, ImgIter, ImgAcc>
00054            (img.first + r.upperLeft(),
00055             img.first + r.lowerRight(),
00056             img.third);
00057 }
00058 
00064 template <class ImgIter, class ImgAcc>
00065 vigra::pair<ImgIter, ImgAcc>
00066 applyRect(vigra::Rect2D & r, vigra::pair<ImgIter, ImgAcc> img)
00067 {
00068     return vigra::pair<ImgIter, ImgAcc>
00069            (img.first + r.upperLeft(),
00070             img.second);
00071 }
00072 
00073 
00074 
00084 template <class Image, class Mask>
00085 class ROIImage
00086 {
00087 
00088 // typedefs for own types
00089         
00090 
00091 public:
00092 // typedefs for the children types
00093     typedef typename Image::value_type      image_value_type;
00094     typedef typename Image::traverser       image_traverser;
00095     typedef typename Image::const_traverser image_const_traverser;
00096     typedef typename Image::Accessor        ImageAccessor;
00097     typedef typename Image::ConstAccessor   ImageConstAccessor;
00098 
00099     typedef typename Mask::value_type       mask_value_type;
00100     typedef typename Mask::traverser        mask_traverser;
00101     typedef typename Mask::const_traverser  mask_const_traverser;
00102     typedef typename Mask::Accessor         MaskAccessor;
00103     typedef typename Mask::ConstAccessor    MaskConstAccessor;
00104 
00107     ROIImage()
00108     {}
00109 
00112     virtual ~ROIImage()
00113     {}
00114 
00119     void resize(const vigra::Rect2D & rect)
00120     {
00121         m_region = rect;
00122         if (!m_region.isEmpty()) {
00123             m_image.resize(m_region.size());
00124             m_mask.resize(m_region.size());
00125         } else {
00126             m_image.resize(vigra::Size2D(1,1));
00127             m_mask.resize(vigra::Size2D(1,1));
00128         }
00129     }
00130 
00137     image_traverser
00138     upperLeft()
00139     {
00140         DEBUG_DEBUG(m_region);
00141         DEBUG_ASSERT(m_image.size().x > 0);
00142         DEBUG_ASSERT(m_image.size().y > 0);
00143         return m_image.upperLeft() - m_region.upperLeft();
00144     }
00145 
00146     image_const_traverser
00147     upperLeft() const
00148     {
00149         DEBUG_DEBUG(m_region);
00150         DEBUG_ASSERT(m_image.size().x > 0);
00151         DEBUG_ASSERT(m_image.size().y > 0);
00152         return m_image.upperLeft() - m_region.upperLeft();
00153     }
00154 
00155     image_traverser
00156     lowerRight()
00157     {
00158         DEBUG_DEBUG(m_region);
00159         DEBUG_ASSERT(m_image.size().x > 0);
00160         DEBUG_ASSERT(m_image.size().y > 0);
00161         return m_image.upperLeft() + m_region.size();
00162     }
00163 
00164     image_const_traverser
00165     lowerRight() const
00166     {
00167         DEBUG_DEBUG(m_region);
00168         DEBUG_ASSERT(m_image.size().x > 0);
00169         DEBUG_ASSERT(m_image.size().y > 0);
00170         return m_image.upperLeft() + m_region.size();
00171     }
00172 
00174     ImageAccessor accessor()
00175     {
00176         return m_image.accessor();
00177     }
00178 
00179     ImageConstAccessor accessor() const
00180     {
00181         const ROIImage<Image,Mask> & t = *this;
00182         return t.m_image.accessor();
00183     }
00184 
00191     mask_traverser
00192     maskUpperLeft()
00193     {
00194         DEBUG_DEBUG(m_region);
00195         DEBUG_ASSERT(m_mask.size().x > 0);
00196         DEBUG_ASSERT(m_mask.size().y > 0);
00197         return m_mask.upperLeft() - m_region.upperLeft();
00198     }
00199 
00200     mask_const_traverser
00201     maskUpperLeft() const
00202     {
00203         DEBUG_DEBUG(m_region);
00204         DEBUG_ASSERT(m_mask.size().x > 0);
00205         DEBUG_ASSERT(m_mask.size().y > 0);
00206         return m_mask.upperLeft() - m_region.upperLeft();
00207     }
00208 
00209     mask_traverser
00210     maskLowerRight()
00211     {
00212         DEBUG_DEBUG(m_region);
00213         DEBUG_ASSERT(m_mask.size().x > 0);
00214         DEBUG_ASSERT(m_mask.size().y > 0);
00215         return m_mask.upperLeft() + m_region.size();
00216     }
00217 
00218     mask_const_traverser
00219     maskLowerRight() const
00220     {
00221         DEBUG_DEBUG(m_region);
00222         DEBUG_ASSERT(m_mask.size().x > 0);
00223         DEBUG_ASSERT(m_mask.size().y > 0);
00224         return m_mask.upperLeft() + m_region.size();
00225     }
00226 
00228     MaskAccessor maskAccessor()
00229     {
00230         return m_mask.accessor();
00231     }
00232 
00233     MaskConstAccessor maskAccessor() const
00234     {
00235         return m_mask.accessor();
00236     }
00237 
00238     vigra::Rect2D & boundingBox()
00239     {
00240         return m_region;
00241     }
00242 
00243     image_value_type operator()(int x, int y)
00244     {
00245         return operator[](vigra::Diff2D(x,y));
00246     }
00247 
00248     image_value_type operator[](vigra::Diff2D const & pos)
00249         {
00250             if (m_region.contains(vigra::Point2D(pos))) {
00251                 return m_image[pos - m_region.upperLeft()];
00252             } else {
00253                 return vigra::NumericTraits<image_value_type>::zero();
00254             }
00255         }
00256 
00257 
00258     mask_value_type getMask(int x, int y)
00259     {
00260         return getMask(vigra::Diff2D(x,y));
00261     }
00262 
00263     mask_value_type getMask(const vigra::Diff2D & pos)
00264         {
00265             if (m_region.contains(vigra::Point2D(pos))) {
00266                 return m_mask[pos - m_region.upperLeft()];
00267             } else {
00268                 return vigra::NumericTraits<mask_value_type>::zero();
00269             }
00270         }
00271 
00272 
00273     Image       m_image;    
00274     Mask        m_mask;    
00275 
00276 protected:
00277     vigra::Rect2D      m_region;   
00278 };
00279 
00280 
00283 template<typename Image, typename Mask>
00284 inline vigra::triple<typename ROIImage<Image, Mask>::image_const_traverser,
00285                      typename ROIImage<Image, Mask>::image_const_traverser,
00286                      typename ROIImage<Image, Mask>::ImageConstAccessor>
00287 srcImageRange(const ROIImage<Image,Mask> & img)
00288 {
00289 return vigra::triple<typename ROIImage<Image,Mask>::image_const_traverser,
00290                    typename ROIImage<Image,Mask>::image_const_traverser,
00291                    typename ROIImage<Image,Mask>::ImageConstAccessor>(img.upperLeft(),
00292                                                              img.lowerRight(),
00293                                                              img.accessor());
00294 }
00295 
00296 
00297 template<typename Image, typename Mask>
00298 inline vigra::pair<typename ROIImage<Image, Mask>::image_const_traverser,
00299                    typename ROIImage<Image, Mask>::ImageConstAccessor>
00300 srcImage(const ROIImage<Image,Mask> & img)
00301 {
00302 return vigra::pair<typename ROIImage<Image,Mask>::image_const_traverser,
00303                    typename ROIImage<Image,Mask>::ImageConstAccessor>(img.upperLeft(),
00304                                                              img.accessor());
00305 }
00306 
00307 
00308 template <class Image, class Alpha>
00309 inline vigra::triple<typename ROIImage<Image,Alpha>::image_traverser,
00310                      typename ROIImage<Image,Alpha>::image_traverser,
00311                      typename ROIImage<Image,Alpha>::ImageAccessor>
00312 destImageRange(ROIImage<Image,Alpha> & img)
00313 {
00314     return vigra::triple<typename ROIImage<Image,Alpha>::image_traverser,
00315                 typename ROIImage<Image,Alpha>::image_traverser,
00316                 typename ROIImage<Image,Alpha>::ImageAccessor>(img.upperLeft(),
00317                                                           img.lowerRight(),     
00318                                                           img.accessor());
00319 }
00320 
00321 template <class Image, class Alpha>
00322 inline vigra::pair<typename ROIImage<Image,Alpha>::image_traverser,
00323                    typename ROIImage<Image,Alpha>::ImageAccessor>
00324 destImage(ROIImage<Image,Alpha> & img)
00325 {
00326     return vigra::pair<typename ROIImage<Image,Alpha>::image_traverser,
00327                 typename ROIImage<Image,Alpha>::ImageAccessor>(img.upperLeft(),
00328                                                           img.accessor());
00329 }
00330 
00331 template <class Image, class Alpha>
00332 inline vigra::triple<typename ROIImage<Image,Alpha>::mask_const_traverser,
00333                      typename ROIImage<Image,Alpha>::mask_const_traverser,
00334                      typename ROIImage<Image,Alpha>::MaskConstAccessor>
00335 srcMaskRange(const ROIImage<Image,Alpha> & img)
00336 {
00337     return vigra::triple<typename ROIImage<Image,Alpha>::mask_const_traverser,
00338                 typename ROIImage<Image,Alpha>::mask_const_traverser,
00339                 typename ROIImage<Image,Alpha>::MaskConstAccessor>(img.maskUpperLeft(),
00340                                                           img.maskLowerRight(), 
00341                                                           img.maskAccessor());
00342 }
00343 
00344 template <class Image, class Alpha>
00345 inline vigra::pair<typename ROIImage<Image,Alpha>::mask_const_traverser,
00346                    typename ROIImage<Image,Alpha>::MaskConstAccessor>
00347 srcMask(const ROIImage<Image,Alpha> & img)
00348 {
00349     return vigra::pair<typename ROIImage<Image,Alpha>::mask_const_traverser,
00350                 typename ROIImage<Image,Alpha>::MaskConstAccessor>(img.maskUpperLeft(),
00351                                                           img.maskAccessor());
00352 }
00353 
00354 template <class Image, class Alpha>
00355 inline vigra::triple<typename ROIImage<Image,Alpha>::mask_traverser,
00356                      typename ROIImage<Image,Alpha>::mask_traverser,
00357                      typename ROIImage<Image,Alpha>::MaskAccessor>
00358 destMaskRange(ROIImage<Image,Alpha> & img)
00359 {
00360     return vigra::triple<typename ROIImage<Image,Alpha>::mask_traverser,
00361                 typename ROIImage<Image,Alpha>::mask_traverser,
00362                 typename ROIImage<Image,Alpha>::MaskAccessor>(img.maskUpperLeft(),
00363                                                           img.maskLowerRight(), 
00364                                                           img.maskAccessor());
00365 }
00366 
00367 template <class Image, class Alpha>
00368 inline vigra::pair<typename ROIImage<Image,Alpha>::mask_traverser,
00369                    typename ROIImage<Image,Alpha>::MaskAccessor>
00370 destMask(ROIImage<Image,Alpha> & img)
00371 {
00372     return vigra::pair<typename ROIImage<Image,Alpha>::mask_traverser,
00373                 typename ROIImage<Image,Alpha>::MaskAccessor>(img.maskUpperLeft(),
00374                                                           img.maskAccessor());
00375 }
00376 
00377 #if 0
00378 template <class Image, class Mask, class Functor>
00379 void inspectROIImages(std::vector<ROIImage<Image,Mask> *> imgs, Functor & f)
00380 {
00381     int nImg = imgs.size();
00382     std::vector<typename Image::traverser> imgUL(nImg);
00383     std::vector<typename Mask::traverser> maskUL(nImg);
00384     std::vector<vigra::Rect2D> rois(nImg);
00385     for (unsigned i=0; i < nImg; i++) {
00386         imgs[i] = imgs->upperLeft();
00387         masks[i] = imgs->maskUpperLeft();
00388         rois[i] = imgs->boundingBox();
00389     }
00390 }
00391 #endif
00392 
00398 template <class ImgIter, class ImgAcc, class MaskIter, class MaskAcc, class Functor>
00399 void inspectImagesIf(std::vector<ImgIter> imgs,
00400                      std::vector<MaskIter> masks,
00401                      std::vector<vigra::Rect2D> rois,
00402                      Functor & f)
00403 {
00404 
00405     typedef typename ImgIter::value_type PixelType;
00406     typedef typename MaskIter::value_type MaskType;
00407 
00408     typedef typename ImgIter::row_iterator RowImgIter;
00409     typedef typename MaskIter::row_iterator RowMaskIter;
00410 
00411     int nImg = imgs.size();
00412 
00413     vigra_precondition(nImg > 1, "more than one image needed");
00414 
00415     // get maximum roi
00416     vigra::Rect2D maxRoi= rois[0];
00417     for (unsigned i=1; i < nImg; i++) {
00418         maxRoi |= rois[i];
00419     }
00420     // skip empty area on the top and right
00421     for (int k=0; k < nImg; k++) {
00422         imgs[k].first.x += maxRoi.left();
00423         imgs[k].first.y += maxRoi.top();
00424         masks[k].first.x += maxRoi.left();
00425         masks[k].first.y += maxRoi.top();
00426     }
00427 
00428     std::vector<RowImgIter> rowImgIter(nImg);
00429     std::vector<RowMaskIter> rowMaskIter(nImg);
00430 
00431     vigra::Point2D p;
00432     std::vector<PixelType> val(nImg);
00433     std::vector<MaskType> mval(nImg);
00434     for(p.y=maxRoi.top(); p.y < maxRoi.bottom(); ++p.y)
00435     {
00436         for (int k=0; k < nImg; k++) {
00437             rowImgIter[k] = imgs[k].first.rowIterator();
00438             rowMaskIter[k] = masks[k].first.rowIterator();
00439         }
00440 
00441         for (p.x=maxRoi.left(); p.x < maxRoi.right(); ++p.x) {
00442             for (int k=0; k < nImg; k++) {
00443                 if (rois[k].contains(p)) {
00444                     val[k] = *(rowImgIter[k]);
00445                     mval[k] = *(rowMaskIter[k]);
00446                 } else {
00447                     mval[k] = 0;
00448                 }
00449                 rowImgIter[k]++;
00450                 rowMaskIter[k]++;
00451             }
00452             f(val,mval);
00453         }
00454         for (int k=0; k < nImg; k++) {
00455             ++(imgs[k].first.y);
00456             ++(masks[k].first.y);
00457         }
00458     }
00459 }
00460 
00461 
00463 template<class ROIIMG, class DestIter, class DestAccessor,
00464          class MaskIter, class MaskAccessor, class FUNCTOR>
00465 void reduceROIImages(std::vector<ROIIMG *> images,
00466                      vigra::triple<DestIter, DestIter, DestAccessor> dest,
00467                      vigra::pair<MaskIter, MaskAccessor> destMask,
00468                      FUNCTOR & reduce)
00469 {
00470     typedef typename DestAccessor::value_type ImgType;
00471     typedef typename MaskAccessor::value_type MaskType;
00472 
00473     typedef typename
00474         vigra::NumericTraits<ImgType> Traits;
00475     typedef typename
00476         Traits::RealPromote RealImgType;
00477 
00478     typedef typename vigra_ext::LUTTraits<MaskType> MaskLUTTraits;
00479 
00480     unsigned int nImg = images.size();
00481 
00482     vigra::Diff2D size = dest.second - dest.first;
00483 
00484     // iterate over the whole image...
00485     // calculate something on the pixels in the overlapping images. 
00486     for (int y=0; y < size.y; y++) {
00487         for (int x=0; x < size.x; x++) {
00488             reduce.reset();
00489             MaskType maskRes=0;
00490             for (unsigned int i=0; i< nImg; i++) {
00491                 MaskType a;
00492                 a = images[i]->getMask(x,y);
00493                 if (a) {
00494                     maskRes = vigra_ext::LUTTraits<MaskType>::max();
00495                     reduce(images[i]->operator()(x,y), a);
00496                 }
00497             }
00498             dest.third.set(reduce(), dest.first, vigra::Diff2D(x,y));
00499             destMask.second.set(maskRes, destMask.first, vigra::Diff2D(x,y));
00500         }
00501     }
00502 }
00503 
00504 
00505 }
00506 
00507 #endif // _ROIIMAGE_H

Generated on 31 Oct 2014 for Hugintrunk by  doxygen 1.4.7