Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ROIImage.h
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
24 #ifndef _ROIIMAGE_H
25 #define _ROIIMAGE_H
26 
27 #include <hugin_utils/utils.h>
28 #include <vigra/imageinfo.hxx>
29 
30 #include "lut.h"
31 
32 namespace vigra_ext
33 {
34 
35 
44 template <class ImgIter, class ImgAcc>
45 vigra::triple<ImgIter, ImgIter, ImgAcc>
46 applyRect(vigra::Rect2D & r, vigra::triple<ImgIter, ImgIter, ImgAcc> img)
47 {
48 #ifdef DEBUG
49  vigra::Diff2D t = img.second - (img.first + r.lowerRight());
50  DEBUG_ASSERT(t.x >= 0);
51  DEBUG_ASSERT(t.y >= 0);
52 #endif
53  return vigra::triple<ImgIter, ImgIter, ImgAcc>
54  (img.first + r.upperLeft(),
55  img.first + r.lowerRight(),
56  img.third);
57 }
58 
64 template <class ImgIter, class ImgAcc>
65 vigra::pair<ImgIter, ImgAcc>
66 applyRect(vigra::Rect2D & r, vigra::pair<ImgIter, ImgAcc> img)
67 {
68  return vigra::pair<ImgIter, ImgAcc>
69  (img.first + r.upperLeft(),
70  img.second);
71 }
72 
73 
74 
84 template <class Image, class Mask>
85 class ROIImage
86 {
87 
88 // typedefs for own types
89 
90 
91 public:
92 // typedefs for the children types
93  typedef typename Image::value_type image_value_type;
94  typedef typename Image::traverser image_traverser;
95  typedef typename Image::const_traverser image_const_traverser;
96  typedef typename Image::Accessor ImageAccessor;
97  typedef typename Image::ConstAccessor ImageConstAccessor;
98 
99  typedef typename Mask::value_type mask_value_type;
100  typedef typename Mask::traverser mask_traverser;
101  typedef typename Mask::const_traverser mask_const_traverser;
102  typedef typename Mask::Accessor MaskAccessor;
103  typedef typename Mask::ConstAccessor MaskConstAccessor;
104 
108  {}
109 
112  virtual ~ROIImage()
113  {}
114 
119  void resize(const vigra::Rect2D & rect)
120  {
121  m_region = rect;
122  if (!m_region.isEmpty()) {
123  m_image.resize(m_region.size());
124  m_mask.resize(m_region.size());
125  } else {
126  m_image.resize(vigra::Size2D(1,1));
127  m_mask.resize(vigra::Size2D(1,1));
128  }
129  }
130 
139  {
141  DEBUG_ASSERT(m_image.size().x > 0);
142  DEBUG_ASSERT(m_image.size().y > 0);
143  return m_image.upperLeft() - m_region.upperLeft();
144  }
145 
147  upperLeft() const
148  {
150  DEBUG_ASSERT(m_image.size().x > 0);
151  DEBUG_ASSERT(m_image.size().y > 0);
152  return m_image.upperLeft() - m_region.upperLeft();
153  }
154 
157  {
159  DEBUG_ASSERT(m_image.size().x > 0);
160  DEBUG_ASSERT(m_image.size().y > 0);
161  return m_image.upperLeft() + m_region.size();
162  }
163 
165  lowerRight() const
166  {
168  DEBUG_ASSERT(m_image.size().x > 0);
169  DEBUG_ASSERT(m_image.size().y > 0);
170  return m_image.upperLeft() + m_region.size();
171  }
172 
175  {
176  return m_image.accessor();
177  }
178 
180  {
181  const ROIImage<Image,Mask> & t = *this;
182  return t.m_image.accessor();
183  }
184 
193  {
195  DEBUG_ASSERT(m_mask.size().x > 0);
196  DEBUG_ASSERT(m_mask.size().y > 0);
197  return m_mask.upperLeft() - m_region.upperLeft();
198  }
199 
202  {
204  DEBUG_ASSERT(m_mask.size().x > 0);
205  DEBUG_ASSERT(m_mask.size().y > 0);
206  return m_mask.upperLeft() - m_region.upperLeft();
207  }
208 
211  {
213  DEBUG_ASSERT(m_mask.size().x > 0);
214  DEBUG_ASSERT(m_mask.size().y > 0);
215  return m_mask.upperLeft() + m_region.size();
216  }
217 
220  {
222  DEBUG_ASSERT(m_mask.size().x > 0);
223  DEBUG_ASSERT(m_mask.size().y > 0);
224  return m_mask.upperLeft() + m_region.size();
225  }
226 
229  {
230  return m_mask.accessor();
231  }
232 
234  {
235  return m_mask.accessor();
236  }
237 
238  vigra::Rect2D & boundingBox()
239  {
240  return m_region;
241  }
242 
244  {
245  return operator[](vigra::Diff2D(x,y));
246  }
247 
248  image_value_type operator[](vigra::Diff2D const & pos)
249  {
250  if (m_region.contains(vigra::Point2D(pos))) {
251  return m_image[pos - m_region.upperLeft()];
252  } else {
253  return vigra::NumericTraits<image_value_type>::zero();
254  }
255  }
256 
257 
258  mask_value_type getMask(int x, int y)
259  {
260  return getMask(vigra::Diff2D(x,y));
261  }
262 
263  mask_value_type getMask(const vigra::Diff2D & pos)
264  {
265  if (m_region.contains(vigra::Point2D(pos))) {
266  return m_mask[pos - m_region.upperLeft()];
267  } else {
268  return vigra::NumericTraits<mask_value_type>::zero();
269  }
270  }
271 
272 
273  Image m_image;
274  Mask m_mask;
275 
276 protected:
277  vigra::Rect2D m_region;
278 };
279 
280 
283 template<typename Image, typename Mask>
284 inline vigra::triple<typename ROIImage<Image, Mask>::image_const_traverser,
288 {
289 return vigra::triple<typename ROIImage<Image,Mask>::image_const_traverser,
292  img.lowerRight(),
293  img.accessor());
294 }
295 
296 
297 template<typename Image, typename Mask>
298 inline vigra::pair<typename ROIImage<Image, Mask>::image_const_traverser,
299  typename ROIImage<Image, Mask>::ImageConstAccessor>
301 {
302 return vigra::pair<typename ROIImage<Image,Mask>::image_const_traverser,
304  img.accessor());
305 }
306 
307 
308 template <class Image, class Alpha>
309 inline vigra::triple<typename ROIImage<Image,Alpha>::image_traverser,
310  typename ROIImage<Image,Alpha>::image_traverser,
311  typename ROIImage<Image,Alpha>::ImageAccessor>
313 {
314  return vigra::triple<typename ROIImage<Image,Alpha>::image_traverser,
317  img.lowerRight(),
318  img.accessor());
319 }
320 
321 template <class Image, class Alpha>
322 inline vigra::pair<typename ROIImage<Image,Alpha>::image_traverser,
323  typename ROIImage<Image,Alpha>::ImageAccessor>
325 {
326  return vigra::pair<typename ROIImage<Image,Alpha>::image_traverser,
328  img.accessor());
329 }
330 
331 template <class Image, class Alpha>
332 inline vigra::triple<typename ROIImage<Image,Alpha>::mask_const_traverser,
333  typename ROIImage<Image,Alpha>::mask_const_traverser,
334  typename ROIImage<Image,Alpha>::MaskConstAccessor>
336 {
337  return vigra::triple<typename ROIImage<Image,Alpha>::mask_const_traverser,
340  img.maskLowerRight(),
341  img.maskAccessor());
342 }
343 
344 template <class Image, class Alpha>
345 inline vigra::pair<typename ROIImage<Image,Alpha>::mask_const_traverser,
346  typename ROIImage<Image,Alpha>::MaskConstAccessor>
348 {
349  return vigra::pair<typename ROIImage<Image,Alpha>::mask_const_traverser,
351  img.maskAccessor());
352 }
353 
354 template <class Image, class Alpha>
355 inline vigra::triple<typename ROIImage<Image,Alpha>::mask_traverser,
356  typename ROIImage<Image,Alpha>::mask_traverser,
357  typename ROIImage<Image,Alpha>::MaskAccessor>
359 {
360  return vigra::triple<typename ROIImage<Image,Alpha>::mask_traverser,
363  img.maskLowerRight(),
364  img.maskAccessor());
365 }
366 
367 template <class Image, class Alpha>
368 inline vigra::pair<typename ROIImage<Image,Alpha>::mask_traverser,
369  typename ROIImage<Image,Alpha>::MaskAccessor>
371 {
372  return vigra::pair<typename ROIImage<Image,Alpha>::mask_traverser,
374  img.maskAccessor());
375 }
376 
377 #if 0
378 template <class Image, class Mask, class Functor>
379 void inspectROIImages(std::vector<ROIImage<Image,Mask> *> imgs, Functor & f)
380 {
381  int nImg = imgs.size();
382  std::vector<typename Image::traverser> imgUL(nImg);
383  std::vector<typename Mask::traverser> maskUL(nImg);
384  std::vector<vigra::Rect2D> rois(nImg);
385  for (unsigned i=0; i < nImg; i++) {
386  imgs[i] = imgs->upperLeft();
387  masks[i] = imgs->maskUpperLeft();
388  rois[i] = imgs->boundingBox();
389  }
390 }
391 #endif
392 
398 template <class ImgIter, class ImgAcc, class MaskIter, class MaskAcc, class Functor>
399 void inspectImagesIf(std::vector<ImgIter> imgs,
400  std::vector<MaskIter> masks,
401  std::vector<vigra::Rect2D> rois,
402  Functor & f)
403 {
404 
405  typedef typename ImgIter::value_type PixelType;
406  typedef typename MaskIter::value_type MaskType;
407 
408  typedef typename ImgIter::row_iterator RowImgIter;
409  typedef typename MaskIter::row_iterator RowMaskIter;
410 
411  int nImg = imgs.size();
412 
413  vigra_precondition(nImg > 1, "more than one image needed");
414 
415  // get maximum roi
416  vigra::Rect2D maxRoi= rois[0];
417  for (unsigned i=1; i < nImg; i++) {
418  maxRoi |= rois[i];
419  }
420  // skip empty area on the top and right
421  for (int k=0; k < nImg; k++) {
422  imgs[k].first.x += maxRoi.left();
423  imgs[k].first.y += maxRoi.top();
424  masks[k].first.x += maxRoi.left();
425  masks[k].first.y += maxRoi.top();
426  }
427 
428  std::vector<RowImgIter> rowImgIter(nImg);
429  std::vector<RowMaskIter> rowMaskIter(nImg);
430 
431  vigra::Point2D p;
432  std::vector<PixelType> val(nImg);
433  std::vector<MaskType> mval(nImg);
434  for(p.y=maxRoi.top(); p.y < maxRoi.bottom(); ++p.y)
435  {
436  for (int k=0; k < nImg; k++) {
437  rowImgIter[k] = imgs[k].first.rowIterator();
438  rowMaskIter[k] = masks[k].first.rowIterator();
439  }
440 
441  for (p.x=maxRoi.left(); p.x < maxRoi.right(); ++p.x) {
442  for (int k=0; k < nImg; k++) {
443  if (rois[k].contains(p)) {
444  val[k] = *(rowImgIter[k]);
445  mval[k] = *(rowMaskIter[k]);
446  } else {
447  mval[k] = 0;
448  }
449  rowImgIter[k]++;
450  rowMaskIter[k]++;
451  }
452  f(val,mval);
453  }
454  for (int k=0; k < nImg; k++) {
455  ++(imgs[k].first.y);
456  ++(masks[k].first.y);
457  }
458  }
459 }
460 
461 
463 template<class ROIIMG, class DestIter, class DestAccessor,
464  class MaskIter, class MaskAccessor, class FUNCTOR>
465 void reduceROIImages(std::vector<ROIIMG *> images,
466  vigra::triple<DestIter, DestIter, DestAccessor> dest,
467  vigra::pair<MaskIter, MaskAccessor> destMask,
468  FUNCTOR & reduce)
469 {
470  typedef typename MaskAccessor::value_type MaskType;
471 
472  unsigned int nImg = images.size();
473 
474  vigra::Diff2D size = dest.second - dest.first;
475 
476  // iterate over the whole image...
477  // calculate something on the pixels in the overlapping images.
478  for (int y=0; y < size.y; y++) {
479  for (int x=0; x < size.x; x++) {
480  reduce.reset();
481  MaskType maskRes=0;
482  for (unsigned int i=0; i< nImg; i++) {
483  MaskType a;
484  a = images[i]->getMask(x,y);
485  if (a) {
487  reduce(images[i]->operator()(x,y), a);
488  }
489  }
490  dest.third.set(reduce(), dest.first, vigra::Diff2D(x,y));
491  destMask.second.set(maskRes, destMask.first, vigra::Diff2D(x,y));
492  }
493  }
494 }
495 
496 
497 }
498 
499 #endif // _ROIIMAGE_H
Mask m_mask
corresponding alpha channel
Definition: ROIImage.h:274
vigra::triple< ImgIter, ImgIter, ImgAcc > applyRect(vigra::Rect2D &r, vigra::triple< ImgIter, ImgIter, ImgAcc > img)
apply a roi to an image area
Definition: ROIImage.h:46
Mask::const_traverser mask_const_traverser
Definition: ROIImage.h:101
mask_traverser maskUpperLeft()
returns an traverser to the upper left of the image, this is usually outside of the rectangle...
Definition: ROIImage.h:192
mask_const_traverser maskLowerRight() const
Definition: ROIImage.h:219
vigra::pair< typename ROIImage< Image, Alpha >::mask_traverser, typename ROIImage< Image, Alpha >::MaskAccessor > destMask(ROIImage< Image, Alpha > &img)
Definition: ROIImage.h:370
void reduce(bool wraparound, SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor sa, AlphaIterator alpha_upperleft, AlphaAccessor aa, DestImageIterator dest_upperleft, DestImageIterator dest_lowerright, DestAccessor da, DestAlphaIterator dest_alpha_upperleft, DestAlphaIterator dest_alpha_lowerright, DestAlphaAccessor daa)
The Burt &amp; Adelson Reduce operation.
Definition: pyramid2.h:178
Image::ConstAccessor ImageConstAccessor
Definition: ROIImage.h:97
#define DEBUG_ASSERT(cond)
Definition: utils.h:80
virtual ~ROIImage()
dtor.
Definition: ROIImage.h:112
vigra::pair< typename ROIImage< Image, Mask >::image_const_traverser, typename ROIImage< Image, Mask >::ImageConstAccessor > srcImage(const ROIImage< Image, Mask > &img)
Definition: ROIImage.h:300
Image::Accessor ImageAccessor
Definition: ROIImage.h:96
mask_value_type getMask(const vigra::Diff2D &pos)
Definition: ROIImage.h:263
image_traverser lowerRight()
Definition: ROIImage.h:156
Mask::value_type mask_value_type
Definition: ROIImage.h:99
vigra::triple< typename ROIImage< Image, Alpha >::mask_traverser, typename ROIImage< Image, Alpha >::mask_traverser, typename ROIImage< Image, Alpha >::MaskAccessor > destMaskRange(ROIImage< Image, Alpha > &img)
Definition: ROIImage.h:358
vigra::Rect2D & boundingBox()
Definition: ROIImage.h:238
Mask::traverser mask_traverser
Definition: ROIImage.h:100
image_value_type operator()(int x, int y)
Definition: ROIImage.h:243
image_const_traverser upperLeft() const
Definition: ROIImage.h:147
Image m_image
remapped image
Definition: ROIImage.h:273
void inspectImagesIf(std::vector< ImgIter > imgs, std::vector< MaskIter > masks, std::vector< vigra::Rect2D > rois, Functor &f)
function to inspect a variable number of images.
Definition: ROIImage.h:399
image_const_traverser lowerRight() const
Definition: ROIImage.h:165
Image::value_type image_value_type
Definition: ROIImage.h:93
bool contains(const wxArrayString &stringArray, const wxString &string, bool caseInSensitive=true)
check if given string is in wxArrayString, do comparison case insentive or case sensitive ...
MaskAccessor maskAccessor()
return the accessor of the alpha channel
Definition: ROIImage.h:228
vigra::pair< typename ROIImage< Image, Alpha >::image_traverser, typename ROIImage< Image, Alpha >::ImageAccessor > destImage(ROIImage< Image, Alpha > &img)
Definition: ROIImage.h:324
vigra::triple< typename ROIImage< Image, Mask >::image_const_traverser, typename ROIImage< Image, Mask >::image_const_traverser, typename ROIImage< Image, Mask >::ImageConstAccessor > srcImageRange(const ROIImage< Image, Mask > &img)
helper function for ROIImages
Definition: ROIImage.h:287
void reduceROIImages(std::vector< ROIIMG * > images, vigra::triple< DestIter, DestIter, DestAccessor > dest, vigra::pair< MaskIter, MaskAccessor > destMask, FUNCTOR &reduce)
algorithm to reduce a set of ROI images
Definition: ROIImage.h:465
mask_value_type getMask(int x, int y)
Definition: ROIImage.h:258
Mask::Accessor MaskAccessor
Definition: ROIImage.h:102
Mask::ConstAccessor MaskConstAccessor
Definition: ROIImage.h:103
vigra::triple< typename ROIImage< Image, Alpha >::mask_const_traverser, typename ROIImage< Image, Alpha >::mask_const_traverser, typename ROIImage< Image, Alpha >::MaskConstAccessor > srcMaskRange(const ROIImage< Image, Alpha > &img)
Definition: ROIImage.h:335
ImageAccessor accessor()
return the accessor of this image
Definition: ROIImage.h:174
static T max(T x, T y)
Definition: svm.cpp:65
#define DEBUG_DEBUG(msg)
Definition: utils.h:68
vigra::pair< typename ROIImage< Image, Alpha >::mask_const_traverser, typename ROIImage< Image, Alpha >::MaskConstAccessor > srcMask(const ROIImage< Image, Alpha > &img)
Definition: ROIImage.h:347
vigra::triple< typename ROIImage< Image, Alpha >::image_traverser, typename ROIImage< Image, Alpha >::image_traverser, typename ROIImage< Image, Alpha >::ImageAccessor > destImageRange(ROIImage< Image, Alpha > &img)
Definition: ROIImage.h:312
mask_traverser maskLowerRight()
Definition: ROIImage.h:210
image_traverser upperLeft()
returns an traverser to the upper left of the image, this is usually outside of the rectangle...
Definition: ROIImage.h:138
brief description.
Definition: ROIImage.h:85
ImageConstAccessor accessor() const
Definition: ROIImage.h:179
MaskConstAccessor maskAccessor() const
Definition: ROIImage.h:233
Image::const_traverser image_const_traverser
Definition: ROIImage.h:95
Image::traverser image_traverser
Definition: ROIImage.h:94
mask_const_traverser maskUpperLeft() const
Definition: ROIImage.h:201
vigra::Rect2D m_region
bounding rectangle of the image
Definition: ROIImage.h:277
void resize(const vigra::Rect2D &rect)
resize the image
Definition: ROIImage.h:119
image_value_type operator[](vigra::Diff2D const &pos)
Definition: ROIImage.h:248