Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Stitcher.h
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
26 #ifndef _NONA_STITCHER_H
27 #define _NONA_STITCHER_H
28 
29 // To avoid windows.h namespace pollution later on
30 #include <vigra/windows.h>
31 
32 #include <sstream>
33 #include <iomanip>
34 #include <vector>
35 #include <utility>
36 #include <cctype>
37 #include <algorithm>
38 
39 #include <vigra/stdimage.hxx>
40 #include <vigra/rgbvalue.hxx>
41 #include <vigra/tiff.hxx>
42 
43 #include <vigra/impex.hxx>
44 #include <vigra_ext/impexalpha.hxx>
45 #include <vigra/copyimage.hxx>
46 
48 #include <vigra_ext/tiffUtils.h>
50 
51 #include <panodata/PanoramaData.h>
53 #include <nona/RemappedPanoImage.h>
54 #include <nona/ImageRemapper.h>
55 #include <nona/StitcherOptions.h>
57 
58 // somehow these are still
59 #undef DIFFERENCE
60 #undef min
61 #undef max
62 #undef MIN
63 #undef MAX
64 
65 namespace HuginBase {
66 namespace Nona {
67 
69 template <typename ImageType, typename AlphaType>
70 class Stitcher
71 {
72 public:
75  : m_pano(pano), m_progress(progress)
76  {
77  }
78 
79  virtual ~Stitcher() {};
80 
85  virtual void stitch(const PanoramaOptions & opts,
86  const UIntSet & images, const std::string & file,
88  {
89  init(opts, images);
90  }
91 
92  void init(const PanoramaOptions & opts, const UIntSet & images)
93  {
94  m_images=images;
95  calcOutputROIS(opts, images);
96  };
97 
98 
100  {
101  UIntSet ret;
102  assert(m_rois.size() == m_images.size());
103  std::vector<vigra::Rect2D>::iterator itr = m_rois.begin();
104  for(UIntSet::iterator it = m_images.begin(); it != m_images.end(); ++it) {
105  if (! itr->isEmpty()) {
106  ret.insert(*it);
107  }
108  }
109  return ret;
110  }
111 
112 protected:
113  // calculate ROI's if not already known
114  virtual void calcOutputROIS(const PanoramaOptions & opts, const UIntSet & images)
115  {
117  }
118 
122  std::vector<vigra::Rect2D> m_rois;
123 };
124 
125 namespace detail
126 {
127  template<typename ImageType, typename AlphaType>
129  unsigned int imgNr, unsigned int nImg,
130  const PanoramaOptions & opts,
131  const std::string& basename,
132  const bool useBigTIFF,
133  AppBase::ProgressDisplay* progress)
134  {
135  ImageType * final_img = 0;
136  AlphaType * alpha_img = 0;
137  ImageType complete;
138  vigra::BImage alpha;
139 
140  if (remapped.boundingBox().isEmpty())
141  // do not save empty files...
142  // TODO: need to tell other parts (enblend etc.) about it too!
143  return;
144 
146  {
147  // export alpha channel as gray channel (original pixel weights)
148  std::ostringstream greyname;
149  greyname << basename << std::setfill('0') << std::setw(4) << imgNr << "_gray.pgm";
150  vigra::ImageExportInfo exinfo1(greyname.str().c_str());
151  if (!opts.tiff_saveROI)
152  {
153  alpha.resize(opts.getROI().size());
154  vigra::Rect2D newOutRect = remapped.boundingBox() & opts.getROI();
155  vigra::Rect2D newOutArea(newOutRect);
156  newOutRect.moveBy(-opts.getROI().upperLeft());
158  vigra_ext::srcMaskRange(remapped)),
159  vigra_ext::applyRect(newOutRect,
160  destImage(alpha)));
161  vigra::exportImage(srcImageRange(alpha), exinfo1);
162  }
163  else
164  {
165  exinfo1.setPosition(remapped.boundingBox().upperLeft());
166  exinfo1.setCanvasSize(vigra::Size2D(opts.getWidth(), opts.getHeight()));
167  vigra::exportImage(srcImageRange(remapped.m_mask), exinfo1);
168  }
169 
170  // calculate real alpha for saving with the image
171  progress->setMessage("Calculating mask");
172  remapped.calcAlpha();
173  }
174 
175  if (!opts.tiff_saveROI)
176  {
177  // FIXME: this is stupid. Should not require space for full image...
178  // but this would need a lower level interface in vigra impex
179  complete.resize(opts.getROI().size());
180  alpha.resize(opts.getROI().size());
181  vigra::Rect2D newOutRect = remapped.boundingBox() & opts.getROI();
182  vigra::Rect2D newOutArea(newOutRect);
183  newOutRect.moveBy(-opts.getROI().upperLeft());
185  vigra_ext::srcImageRange(remapped)),
186  vigra_ext::applyRect(newOutRect,
187  destImage(complete)));
188 
190  vigra_ext::srcMaskRange(remapped)),
191  vigra_ext::applyRect(newOutRect,
192  destImage(alpha)));
193  final_img = &complete;
194  alpha_img = &alpha;
195  }
196  else
197  {
198  final_img = &remapped.m_image;
199  alpha_img = &remapped.m_mask;
200  }
201 
202  std::string ext = opts.getOutputExtension();
203  std::ostringstream filename;
204  filename << basename << std::setfill('0') << std::setw(4) << imgNr << "." + ext;
205 
206  progress->setMessage("saving", hugin_utils::stripPath(filename.str()));
207 
208  vigra::ImageExportInfo exinfo(filename.str().c_str(), useBigTIFF ? "w8" : "w");
209  exinfo.setXResolution(150);
210  exinfo.setYResolution(150);
211  exinfo.setICCProfile(remapped.m_ICCProfile);
212  if (opts.tiff_saveROI)
213  {
214  exinfo.setPosition(remapped.boundingBox().upperLeft());
215  exinfo.setCanvasSize(vigra::Size2D(opts.getWidth(), opts.getHeight()));
216  }
217  else
218  {
219  exinfo.setPosition(opts.getROI().upperLeft());
220  exinfo.setCanvasSize(vigra::Size2D(opts.getWidth(), opts.getHeight()));
221  }
222  if (!opts.outputPixelType.empty())
223  {
224  exinfo.setPixelType(opts.outputPixelType.c_str());
225  }
226  bool supportsAlpha = true;
227  if (ext == "tif")
228  {
229  exinfo.setCompression(opts.tiffCompression.c_str());
230  }
231  else
232  {
233  if (ext == "jpg")
234  {
235  std::ostringstream quality;
236  quality << "JPEG QUALITY=" << opts.quality;
237  exinfo.setCompression(quality.str().c_str());
238  supportsAlpha = false;
239  };
240  }
241 
242  if (supportsAlpha)
243  {
244  vigra::exportImageAlpha(srcImageRange(*final_img), srcImage(*alpha_img), exinfo);
245  }
246  else
247  {
248  vigra::exportImage(srcImageRange(*final_img), exinfo);
249  };
250  };
251 } // namespace detail
252 
254 template <typename ImageType, typename AlphaType>
255 class MultiImageRemapper : public Stitcher<ImageType, AlphaType>
256 {
257 public:
258 
260 
262  AppBase::ProgressDisplay* progress)
263  : Stitcher<ImageType,AlphaType>(pano, progress)
264  {
265  }
266 
268  {
269  }
270 
271  virtual void stitch(const PanoramaOptions & opts, const UIntSet & images,
272  const std::string & basename,
274  const AdvancedOptions& advOptions)
275  {
276  Base::stitch(opts, images, basename, remapper);
283 
284  m_basename = basename;
285 
286  // setup the output.
287  prepareOutputFile(opts, advOptions);
288 
289  // remap each image and save
290  int i=0;
291  for (UIntSet::const_iterator it = images.begin();
292  it != images.end(); ++it)
293  {
294  // get a remapped image.
295  PanoramaOptions modOptions(opts);
296  if (GetAdvancedOption(advOptions, "ignoreExposure", false))
297  {
298  modOptions.outputExposureValue = Base::m_pano.getImage(*it).getExposureValue();
299  modOptions.outputRangeCompression = 0.0;
300  };
302  remapped = remapper.getRemapped(Base::m_pano, modOptions, *it,
304  try {
305  saveRemapped(*remapped, *it, Base::m_pano.getNrOfImages(), opts, advOptions);
306  } catch (vigra::PreconditionViolation & e) {
307  // this can be thrown, if an image
308  // is completely out of the pano
309  std::cerr << e.what();
310  }
311  // free remapped image
312  remapper.release(remapped);
313  i++;
314  }
315  finalizeOutputFile(opts);
317  }
318 
320  virtual void prepareOutputFile(const PanoramaOptions & opts, const AdvancedOptions& advOptions)
321  {
322  Base::m_progress->setMessage("Multiple images output");
323  }
324 
327  unsigned int imgNr, unsigned int nImg,
328  const PanoramaOptions & opts,
329  const AdvancedOptions& advOptions)
330  {
331  detail::saveRemapped(remapped, imgNr, nImg, opts, m_basename, GetAdvancedOption(advOptions, "useBigTIFF", false), Base::m_progress);
332 
333  if (opts.saveCoordImgs) {
334  vigra::UInt16Image xImg;
335  vigra::UInt16Image yImg;
336 
337  Base::m_progress->setMessage("creating coordinate images");
338 
339  remapped.calcSrcCoordImgs(xImg, yImg);
340  vigra::UInt16Image dist;
341  if (! opts.tiff_saveROI) {
342  dist.resize(opts.getWidth(), opts.getHeight());
345  destImage(dist)));
346  std::ostringstream filename2;
347  filename2 << m_basename << std::setfill('0') << std::setw(4) << imgNr << "_x.tif";
348 
349  vigra::ImageExportInfo exinfo(filename2.str().c_str());
350  exinfo.setXResolution(150);
351  exinfo.setYResolution(150);
352  exinfo.setCompression(opts.tiffCompression.c_str());
353  vigra::exportImage(srcImageRange(dist), exinfo);
354 
355 
358  destImage(dist)));
359  std::ostringstream filename3;
360  filename3 << m_basename << std::setfill('0') << std::setw(4) << imgNr << "_y.tif";
361 
362  vigra::ImageExportInfo exinfo2(filename3.str().c_str());
363  exinfo2.setXResolution(150);
364  exinfo2.setYResolution(150);
365  exinfo2.setCompression(opts.tiffCompression.c_str());
366  vigra::exportImage(srcImageRange(dist), exinfo2);
367  } else {
368  std::ostringstream filename2;
369  filename2 << m_basename << std::setfill('0') << std::setw(4) << imgNr << "_x.tif";
370  vigra::ImageExportInfo exinfo(filename2.str().c_str());
371  exinfo.setXResolution(150);
372  exinfo.setYResolution(150);
373  exinfo.setCompression(opts.tiffCompression.c_str());
374  vigra::exportImage(srcImageRange(xImg), exinfo);
375  std::ostringstream filename3;
376  filename3 << m_basename << std::setfill('0') << std::setw(4) << imgNr << "_y.tif";
377  vigra::ImageExportInfo exinfo2(filename3.str().c_str());
378  exinfo2.setXResolution(150);
379  exinfo2.setYResolution(150);
380  exinfo2.setCompression(opts.tiffCompression.c_str());
381  vigra::exportImage(srcImageRange(yImg), exinfo2);
382  }
383  }
384  }
385 
386  virtual void finalizeOutputFile(const PanoramaOptions & opts)
387  {
389  }
390 
391 protected:
392  std::string m_basename;
393 };
394 
395 
396 
398 template <typename ImageType, typename AlphaImageType>
399 class TiffMultiLayerRemapper : public MultiImageRemapper<ImageType, AlphaImageType>
400 {
401 public:
402 
405  AppBase::ProgressDisplay* progress)
406  : MultiImageRemapper<ImageType, AlphaImageType> (pano, progress), m_tiff(NULL)
407  {
408  }
409 
411  {
412  }
413 
414  virtual void prepareOutputFile(const PanoramaOptions & opts, const AdvancedOptions& advOptions)
415  {
416  const std::string filename (Base::m_basename + ".tif");
417  DEBUG_DEBUG("Layering image into a multi image tif file " << filename);
418  Base::m_progress->setMessage("Multiple layer output");
419  m_tiff = TIFFOpen(filename.c_str(), GetAdvancedOption(advOptions, "useBigTIFF", false) ? "w8" : "w");
420  DEBUG_ASSERT(m_tiff && "could not open tiff output file");
421  }
422 
425  unsigned int imgNr, unsigned int nImg,
426  const PanoramaOptions & opts,
427  const AdvancedOptions& advOptions)
428  {
429  if (remapped.boundingBox().isEmpty())
430  return;
431 
432  DEBUG_DEBUG("Saving TIFF ROI");
434  Base::m_pano.getImage(imgNr).getFilename(),
436  opts.tiffCompression,
437  imgNr+1, nImg, remapped.boundingBox().upperLeft(),
438  opts.getROI().size(),
439  remapped.m_ICCProfile);
441  vigra::maskImage(remapped.m_mask),
442  m_tiff);
443  TIFFFlush(m_tiff);
444  }
445 
447  virtual void finalizeOutputFile(const PanoramaOptions & opts)
448  {
449  TIFFClose(m_tiff);
452  }
453 
454 
455 protected:
456  vigra::TiffImage * m_tiff;
457 };
458 
459 template <typename ImageType, typename AlphaType>
460 class WeightedStitcher : public Stitcher<ImageType, AlphaType>
461 {
462 public:
463 
466  AppBase::ProgressDisplay* progress)
467  : Stitcher<ImageType, AlphaType>(pano, progress)
468  {
469  }
470 
471  virtual ~WeightedStitcher() {};
472 
473  void stitch(const PanoramaOptions & opts, const UIntSet & imgSet,
474  const std::string & filename,
475  ImageType& panoImage,
476  AlphaType& alpha,
478  const AdvancedOptions& advOptions)
479  {
480  const unsigned int nImg = imgSet.size();
481 
482  Base::m_progress->setMessage("Remapping and stitching");
483 
484  const bool wrap = (opts.getHFOV() == 360.0) && (opts.getWidth()==opts.getROI().width());
485  // remap each image and blend into main pano image
486  const bool hardSeam = GetAdvancedOption(advOptions, "hardSeam", true);
487  UIntVector images;
488  if(hardSeam)
489  {
490  std::copy(imgSet.begin(), imgSet.end(), std::back_inserter(images));
491  }
492  else
493  {
495  };
496  for (UIntVector::const_iterator it = images.begin(); it != images.end(); ++it)
497  {
498  // get a remapped image.
499  DEBUG_DEBUG("remapping image: " << *it);
500  PanoramaOptions modOptions(opts);
501  if (GetAdvancedOption(advOptions, "ignoreExposure", false))
502  {
503  modOptions.outputExposureValue = Base::m_pano.getImage(*it).getExposureValue();
504  modOptions.outputRangeCompression = 0.0;
505  };
507  remapped = remapper.getRemapped(Base::m_pano, modOptions, *it,
508  Base::m_rois[std::distance(imgSet.begin(), imgSet.find(*it))], Base::m_progress);
509  if(iccProfile.empty())
510  {
511  iccProfile=remapped->m_ICCProfile;
512  };
513  if (GetAdvancedOption(advOptions, "saveIntermediateImages", false))
514  {
516  modOptions.tiff_saveROI = true;
517  std::string finalFilename(GetAdvancedOption(advOptions, "basename", filename));
518  const std::string suffix(GetAdvancedOption(advOptions, "saveIntermediateImagesSuffix"));
519  if (!suffix.empty())
520  {
521  finalFilename.append(suffix);
522  };
523  detail::saveRemapped(*remapped, *it, nImg, modOptions, finalFilename, GetAdvancedOption(advOptions, "useBigTIFF", false), Base::m_progress);
524  }
525  Base::m_progress->setMessage("blending", hugin_utils::stripPath(Base::m_pano.getImage(*it).getFilename()));
526  // add image to pano and panoalpha, adjusts panoROI as well.
527  try {
528  vigra_ext::MergeImages<ImageType, AlphaType>(panoImage, alpha, remapped->m_image, remapped->m_mask, vigra::Diff2D(remapped->boundingBox().upperLeft()), wrap, hardSeam);
529  // update bounding box of the panorama
530  m_panoROI |= remapped->boundingBox();
531  } catch (vigra::PreconditionViolation & e) {
532  DEBUG_ERROR("exception during stitching" << e.what());
533  // this can be thrown, if an image
534  // is completely out of the pano
535  }
536  // free remapped image
537  remapper.release(remapped);
538  }
539  // check if our intermediate image covers whole canvas
540  // if not update m_panoROI
541  if (m_panoROI.width() < opts.getROI().width() || m_panoROI.height() < opts.getROI().height())
542  {
543  // update m_panoROI
544  m_panoROI = opts.getROI();
545  }
546  }
547 
548  void stitch(const PanoramaOptions & opts, const UIntSet & imgSet,
549  const std::string & filename,
551  const AdvancedOptions& advOptions)
552  {
553  Base::stitch(opts, imgSet, filename, remapper);
554 
555  std::string basename = filename;
556 
557  // create panorama canvas
558  ImageType pano(opts.getWidth(), opts.getHeight());
559  AlphaType panoMask(opts.getWidth(), opts.getHeight());
560 
561  stitch(opts, imgSet, filename, pano, panoMask, remapper, advOptions);
562 
563  std::string ext = opts.getOutputExtension();
564  std::string cext = hugin_utils::tolower(hugin_utils::getExtension(basename));
565  std::transform(cext.begin(),cext.end(), cext.begin(), (int(*)(int))std::tolower);
566  // remove extension only if it specifies the same file type, otherwise
567  // its probably part of the filename.
568  if (cext == ext) {
569  basename = hugin_utils::stripExtension(basename);
570  }
571  std::string outputfile(basename);
572  // append suffix if given
573  const std::string suffix = GetAdvancedOption(advOptions, "saveFinalImageSuffix", std::string());
574  if (!suffix.empty())
575  {
576  outputfile.append(suffix);
577  };
578  outputfile.append("." + ext);
579 
580  // save the remapped image
581  Base::m_progress->setMessage("saving result", hugin_utils::stripPath(outputfile));
582  DEBUG_DEBUG("Saving panorama: " << outputfile);
583  vigra::ImageExportInfo exinfo(outputfile.c_str(), GetAdvancedOption(advOptions, "useBigTIFF", false) ? "w8" : "w");
584  exinfo.setXResolution(150);
585  exinfo.setYResolution(150);
586  exinfo.setICCProfile(iccProfile);
587  if (!opts.outputPixelType.empty()) {
588  exinfo.setPixelType(opts.outputPixelType.c_str());
589  }
590 
591  // set compression quality for jpeg images.
592  if (opts.outputFormat == PanoramaOptions::JPEG) {
593  std::ostringstream quality;
594  quality << "JPEG QUALITY=" << opts.quality;
595  exinfo.setCompression(quality.str().c_str());
596  // scale down to UInt8 if necessary
598  // force 8 bit depth for jpeg output
599  exinfo.setPixelType("UINT8");
600  vigra::exportImage(srcImageRange(pano, m_panoROI), exinfo);
601  } else if (opts.outputFormat == PanoramaOptions::TIFF) {
602  exinfo.setCompression(opts.tiffCompression.c_str());
603  exinfo.setCanvasSize(pano.size());
604  exinfo.setPosition(m_panoROI.upperLeft());
606  srcImage(panoMask, m_panoROI.upperLeft()), exinfo);
607  } else if (opts.outputFormat == PanoramaOptions::HDR) {
608  exinfo.setPixelType("FLOAT");
609  vigra::exportImage(srcImageRange(pano), exinfo);
610  } else {
612  srcImage(panoMask, m_panoROI.upperLeft()), exinfo);
613  }
614  /*
615 #ifdef DEBUG
616  vigra::exportImage(srcImageRange(panoMask), vigra::ImageExportInfo("pano_alpha.tif"));
617 #endif
618  */
619  }
620 
621  vigra::Rect2D GetPanoROI() const
622  {
623  return m_panoROI;
624  }
625  vigra::ImageImportInfo::ICCProfile GetICCProfile() const
626  {
627  return iccProfile;
628  };
629 protected:
630  vigra::ImageImportInfo::ICCProfile iccProfile;
631  vigra::Rect2D m_panoROI;
632 };
633 
634 
636 template<class VALUETYPE>
638 {
639  typedef VALUETYPE argument_type;
640  typedef VALUETYPE result_type;
641  typedef typename vigra::NumericTraits<argument_type> Traits;
642  typedef typename Traits::RealPromote float_type;
643 
644 
646  {
647  reset();
648  }
649 
650  void reset()
651  {
652  sum = vigra::NumericTraits<float_type>::zero();
653  values.clear();
654  }
655 
656  template<class T, class M>
657  void operator() (T const &v, M const &a)
658  {
659  if (a) {
660  values.push_back(v);
661  sum = sum + v;
662  }
663  }
664 
667  {
668  typedef typename std::vector<float_type>::const_iterator Iter;
669  if (values.size() > 1) {
670  float_type mean = sum / values.size();
671  float_type error = vigra::NumericTraits<float_type>::zero();
672  for (Iter it= values.begin(); it != values.end(); ++it) {
673  error += vigra::abs(*it-mean);
674  }
675  return error;
676  } else {
677  return sum;
678  }
679  }
680  std::vector<float_type> values;
682 };
683 
688 template <typename ImageType, typename AlphaType>
689 class ReduceStitcher : public Stitcher<ImageType, AlphaType>
690 {
692 public:
694  AppBase::ProgressDisplay* progress)
695  : Stitcher<ImageType, AlphaType>(pano, progress)
696  {
697  }
698 
699  virtual ~ReduceStitcher()
700  {
701  }
702 
703  template <class FUNCTOR>
704  void stitch(const PanoramaOptions & opts, const UIntSet & imgSet,
705  const std::string & filename,
707  FUNCTOR & reduce,
708  const AdvancedOptions& advOptions)
709  {
710  Base::stitch(opts, imgSet, filename, remapper);
711 
712  std::string basename = filename;
713 
714  // create panorama canvas
715  ImageType pano(opts.getWidth(), opts.getHeight());
716  AlphaType panoMask(opts.getWidth(), opts.getHeight());
717 
718  stitch(opts, imgSet, vigra::destImageRange(pano), vigra::destImage(panoMask),
719  remapper, reduce);
720 
721  std::string ext = opts.getOutputExtension();
722  std::string cext = hugin_utils::tolower(hugin_utils::getExtension(basename));
723  // remove extension only if it specifies the same file type, otherwise
724  // its probably part of the filename.
725  if (cext == ext) {
726  basename = hugin_utils::stripExtension(basename);
727  }
728  std::string outputfile = basename + "." + ext;
729 
730 // Base::m_progress.setMessage("saving result: " + hugin_utils::stripPath(outputfile));
731  DEBUG_DEBUG("Saving panorama: " << outputfile);
732  vigra::ImageExportInfo exinfo(outputfile.c_str(), GetAdvancedOption(advOptions, "useBigTIFF", false) ? "w8" : "w");
733  if (!opts.outputPixelType.empty()) {
734  exinfo.setPixelType(opts.outputPixelType.c_str());
735  }
736  exinfo.setXResolution(150);
737  exinfo.setYResolution(150);
738  exinfo.setICCProfile(iccProfile);
739  // set compression quality for jpeg images.
740  if (opts.outputFormat == PanoramaOptions::JPEG) {
741  std::ostringstream quality;
742  quality << "JPEG QUALITY=" << opts.quality;
743  exinfo.setCompression(quality.str().c_str());
744  vigra::exportImage(srcImageRange(pano), exinfo);
745  } else if (opts.outputFormat == PanoramaOptions::TIFF) {
746  exinfo.setCompression(opts.tiffCompression.c_str());
748  srcImage(panoMask), exinfo);
749  } else if (opts.outputFormat == PanoramaOptions::HDR) {
750  vigra::exportImage(srcImageRange(pano), exinfo);
751  } else {
753  srcImage(panoMask), exinfo);
754  }
755  /*
756 #ifdef DEBUG
757  vigra::exportImage(srcImageRange(panoMask), vigra::ImageExportInfo("pano_alpha.tif"));
758 #endif
759  */
760  }
761 
762 
763  template<class ImgIter, class ImgAccessor,
764  class AlphaIter, class AlphaAccessor,
765  class FUNCTOR>
766  void stitch(const PanoramaOptions & opts, const UIntSet & imgSet,
767  vigra::triple<ImgIter, ImgIter, ImgAccessor> pano,
768  std::pair<AlphaIter, AlphaAccessor> alpha,
770  FUNCTOR & reduce)
771  {
772  typedef typename vigra::NumericTraits<typename ImageType::value_type> Traits;
773  typedef typename AlphaAccessor::value_type MaskType;
774 
775  Base::stitch(opts, imgSet, "dummy", remapper);
776 
777  // remap all images..
778  typedef std::vector<RemappedPanoImage<ImageType, AlphaType> *> RemappedVector;
779  unsigned int nImg = imgSet.size();
780 
781  Base::m_progress->setMessage("Stitching");
782  // empty ROI
783  // vigra::Rect2D panoROI;
784  // remap all images..
785  RemappedVector remapped(nImg);
786 
787  int i=0;
788  // remap each image and blend into main pano image
789  for (UIntSet::const_iterator it = imgSet.begin();
790  it != imgSet.end(); ++it)
791  {
792  // get a copy of the remapped image.
793  // not very good, keeps all images in memory,
794  // but should be enought for the preview.
795  remapped[i] = remapper.getRemapped(Base::m_pano, opts, *it,
797  if(iccProfile.empty())
798  {
799  iccProfile=remapped[i]->m_ICCProfile;
800  };
801  i++;
802  }
803  vigra::Diff2D size = pano.second - pano.first;
804  ImgIter output = pano.first;
805  // iterate over the whole image...
806  // calculate something on the pixels that belong together..
807  for (int y=0; y < size.y; y++) {
808  for (int x=0; x < size.x; x++) {
809  reduce.reset();
810  MaskType maskRes=0;
811  for (unsigned int i=0; i< nImg; i++) {
812  MaskType a = remapped[i]->getMask(x,y);
813  if (a) {
815  reduce(remapped[i]->operator()(x,y), a);
816  }
817  }
818  pano.third.set(Traits::fromRealPromote(reduce()), output, vigra::Diff2D(x,y));
819  alpha.second.set(maskRes, alpha.first, vigra::Diff2D(x,y));
820  }
821  }
822 
823  for (typename RemappedVector::iterator it=remapped.begin();
824  it != remapped.end(); ++it)
825  {
826  remapper.release(*it);
827  }
828  }
829 
830 public:
831  vigra::ImageImportInfo::ICCProfile iccProfile;
832 };
833 
836 template <typename ImageType, typename AlphaType>
837 class SimpleStitcher : public Stitcher<ImageType, AlphaType>
838 {
840 public:
842  AppBase::ProgressDisplay* progress)
843  : Stitcher<ImageType, AlphaType>(pano, progress)
844  {
845  }
846 
847  virtual ~SimpleStitcher()
848  {
849  }
850 
851  template<class ImgIter, class ImgAccessor,
852  class AlphaIter, class AlphaAccessor,
853  class BlendFunctor>
854  void stitch(const PanoramaOptions & opts, const UIntSet & imgSet,
855  vigra::triple<ImgIter, ImgIter, ImgAccessor> pano,
856  std::pair<AlphaIter, AlphaAccessor> alpha,
858  BlendFunctor & blend)
859  {
860  Base::m_images=imgSet;
861  Base::calcOutputROIS(opts, imgSet);
862 
863  Base::m_progress->setMessage("Remapping and stitching with watershed algorithm");
864  // empty ROI
865  vigra::Rect2D panoROI;
866 
867  unsigned i=0;
868  // remap each image and blend into main pano image
869  for (UIntSet::reverse_iterator it = imgSet.rbegin();
870  it != imgSet.rend(); ++it)
871  {
872  // get a remapped image.
874  remapped = remapper.getRemapped(Base::m_pano, opts, *it,
876  if (iccProfile.empty()) {
877  // try to extract icc profile.
878  iccProfile = remapped->m_ICCProfile;
879  }
880  Base::m_progress->setMessage("blending");
881  // add image to pano and panoalpha, adjusts panoROI as well.
882  try {
883  blend(*remapped, pano, alpha, panoROI);
884  // update bounding box of the panorama
885  panoROI = panoROI | remapped->boundingBox();
886  } catch (vigra::PreconditionViolation & e) {
887  // this can be thrown, if an image
888  // is completely out of the pano
889  std::cerr << e.what();
890  }
891  // free remapped image
892  remapper.release(remapped);
893  i++;
894  }
896  }
897 
898  template <class BlendFunctor>
899  void stitch(const PanoramaOptions & opts, const UIntSet & imgSet,
900  const std::string & filename,
902  BlendFunctor & blend)
903  {
904  std::string basename = filename;
905 
906  // create panorama canvas
907  ImageType pano(opts.getWidth(), opts.getHeight());
908  AlphaType panoMask(opts.getWidth(), opts.getHeight());
909 
910  stitch(opts, imgSet, vigra::destImageRange(pano), vigra::destImage(panoMask), remapper, blend);
911 
912  std::string ext = opts.getOutputExtension();
913  std::string cext = hugin_utils::tolower(hugin_utils::getExtension(basename));
914  // remove extension only if it specifies the same file type, otherwise
915  // its probably part of the filename.
916  if (cext == ext) {
917  basename = hugin_utils::stripExtension(basename);
918  }
919  std::string outputfile = basename + "." + ext;
920 
921  Base::m_progress.setMessage("saving result:", hugin_utils::stripPath(outputfile));
922  DEBUG_DEBUG("Saving panorama: " << outputfile);
923  vigra::ImageExportInfo exinfo(outputfile.c_str());
924  exinfo.setXResolution(150);
925  exinfo.setYResolution(150);
926  exinfo.setICCProfile(iccProfile);
927  // set compression quality for jpeg images.
928  if (opts.outputFormat == PanoramaOptions::JPEG) {
929  std::ostringstream quality;
930  quality << "JPEG QUALITY=" << opts.quality;
931  exinfo.setCompression(quality.str().c_str());
932  vigra::exportImage(srcImageRange(pano), exinfo);
933  } else if (opts.outputFormat == PanoramaOptions::TIFF) {
934  exinfo.setCompression("DEFLATE");
936  srcImage(panoMask), exinfo);
937  } else {
939  srcImage(panoMask), exinfo);
940  }
941  /*
942 #ifdef DEBUG
943  vigra::exportImage(srcImageRange(panoMask), vigra::ImageExportInfo("pano_alpha.tif"));
944 #endif
945  */
946  Base::m_progress.popTask();
947 
948  }
949 public:
950  vigra::ImageExportInfo::ICCProfile iccProfile;
951 };
952 
957 {
958 
959 public:
964  template <typename ImageType, typename AlphaType,
965  typename PanoIter, typename PanoAccessor,
966  typename AlphaIter, typename AlphaAccessor>
968  vigra::triple<PanoIter, PanoIter, PanoAccessor> pano,
969  std::pair<AlphaIter, AlphaAccessor> alpha,
970  const vigra::Rect2D & panoROI)
971  {
972  DEBUG_DEBUG("pano roi: " << panoROI << " img roi: " << img.boundingBox());
973 
974 // DEBUG_DEBUG("no overlap, copying upper area. imgroi " << img.roi());
975 // DEBUG_DEBUG("pano roi: " << panoROI.upperLeft() << " -> " << panoROI.lowerRight());
976  DEBUG_DEBUG("size of panorama: " << pano.second - pano.first);
977 
978  // check if bounding box of image is outside of panorama...
979  vigra::Rect2D fullPano(vigra::Size2D(pano.second-pano.first));
980  // blend only the intersection (which is inside the pano..)
981  vigra::Rect2D overlap = fullPano & img.boundingBox();
982 
985  vigra_ext::applyRect(overlap, std::make_pair(pano.first, pano.third)));
986  // copy mask
988  vigra_ext::applyRect(overlap, srcMask(img)),
989  vigra_ext::applyRect(overlap, alpha));
990  }
991 };
992 
993 template<typename ImageType, typename AlphaType>
994 static void stitchPanoIntern(const PanoramaData & pano,
995  const PanoramaOptions & opts,
996  AppBase::ProgressDisplay* progress,
997  const std::string & basename,
998  UIntSet imgs,
999  const AdvancedOptions& advOptions)
1000 {
1002  // determine stitching output
1003  switch (opts.outputFormat) {
1004  case PanoramaOptions::JPEG:
1005  case PanoramaOptions::PNG:
1006  case PanoramaOptions::TIFF:
1007  case PanoramaOptions::HDR:
1008  case PanoramaOptions::EXR:
1009  {
1012  ReduceStitcher<ImageType, AlphaType> stitcher(pano, progress);
1013  stitcher.stitch(opts, imgs, basename, m, hdrmerge, advOptions);
1014  } else {
1015  WeightedStitcher<ImageType, AlphaType> stitcher(pano, progress);
1016  m.setAdvancedOptions(advOptions);
1017  stitcher.stitch(opts, imgs, basename, m, advOptions);
1018  }
1019  break;
1020  }
1026  {
1027  MultiImageRemapper<ImageType, AlphaType> stitcher(pano, progress);
1028  m.setAdvancedOptions(advOptions);
1029  stitcher.stitch(opts, imgs, basename, m, advOptions);
1030  break;
1031  }
1033  {
1034  TiffMultiLayerRemapper<ImageType, AlphaType> stitcher(pano, progress);
1035  stitcher.stitch(opts, imgs, basename, m, advOptions);
1036  break;
1037  }
1040  DEBUG_ERROR("multi mask stitching not implemented!");
1041  break;
1042  default:
1043  DEBUG_ERROR("output format " << opts.getFormatName(opts.outputFormat) << "not supported");
1044  break;
1045  }
1046 }
1047 
1054 IMPEX void stitchPanorama(const PanoramaData & pano,
1055  const PanoramaOptions & opts,
1056  AppBase::ProgressDisplay* progress,
1057  const std::string & basename,
1058  const UIntSet & usedImgs,
1059  const AdvancedOptions& advOptions = AdvancedOptions());
1060 
1061 // the instantiations of the stitching functions have been divided into two .cpp
1062 // files, because g++ will use too much memory otherwise (> 1.5 GB)
1063 
1064 void stitchPanoGray_8_16(const PanoramaData & pano,
1065  const PanoramaOptions & opts,
1066  AppBase::ProgressDisplay* progress,
1067  const std::string & basename,
1068  const UIntSet & usedImgs,
1069  const char * pixelType,
1070  const AdvancedOptions& advOptions);
1071 
1072 void stitchPanoGray_32_float(const PanoramaData & pano,
1073  const PanoramaOptions & opts,
1074  AppBase::ProgressDisplay* progress,
1075  const std::string & basename,
1076  const UIntSet & usedImgs,
1077  const char * pixelType,
1078  const AdvancedOptions& advOptions);
1079 
1080 
1081 void stitchPanoRGB_8_16(const PanoramaData & pano,
1082  const PanoramaOptions & opts,
1083  AppBase::ProgressDisplay* progress,
1084  const std::string & basename,
1085  const UIntSet & usedImgs,
1086  const char * pixelType,
1087  const AdvancedOptions& advOptions);
1088 
1089 void stitchPanoRGB_32_float(const PanoramaData & pano,
1090  const PanoramaOptions & opts,
1091  AppBase::ProgressDisplay* progress,
1092  const std::string & basename,
1093  const UIntSet & usedImgs,
1094  const char * pixelType,
1095  const AdvancedOptions& advOptions);
1096 
1097 } // namespace
1098 } // namespace
1099 
1100 #endif // _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
virtual void stitch(const PanoramaOptions &opts, const UIntSet &images, const std::string &basename, SingleImageRemapper< ImageType, AlphaType > &remapper, const AdvancedOptions &advOptions)
Definition: Stitcher.h:271
static void stitchPanoIntern(const PanoramaData &pano, const PanoramaOptions &opts, AppBase::ProgressDisplay *progress, const std::string &basename, UIntSet imgs, const AdvancedOptions &advOptions)
Definition: Stitcher.h:994
virtual void release(RemappedPanoImage< ImageType, AlphaType > *d)=0
declaration of functions to handle stacks and layers
virtual void saveRemapped(RemappedPanoImage< ImageType, AlphaImageType > &remapped, unsigned int imgNr, unsigned int nImg, const PanoramaOptions &opts, const AdvancedOptions &advOptions)
save the remapped image in a partial tiff layer
Definition: Stitcher.h:424
bool GetAdvancedOption(const AdvancedOptions &opts, const std::string &name, const bool defaultValue)
check if given option is saved and return its boolean value, otherwise return defaultValue ...
void operator()(RemappedPanoImage< ImageType, AlphaType > &img, vigra::triple< PanoIter, PanoIter, PanoAccessor > pano, std::pair< AlphaIter, AlphaAccessor > alpha, const vigra::Rect2D &panoROI)
blend img into pano, using alpha mask and panoROI
Definition: Stitcher.h:967
vigra::ImageImportInfo::ICCProfile GetICCProfile() const
Definition: Stitcher.h:625
virtual RemappedPanoImage< ImageType, AlphaType > * getRemapped(const PanoramaData &pano, const PanoramaOptions &opts, unsigned int imgNr, vigra::Rect2D outputROI, AppBase::ProgressDisplay *progress)=0
create a remapped pano image.
void stitch(const PanoramaOptions &opts, const UIntSet &imgSet, const std::string &filename, ImageType &panoImage, AlphaType &alpha, SingleImageRemapper< ImageType, AlphaType > &remapper, const AdvancedOptions &advOptions)
Definition: Stitcher.h:473
implements a stitching algorithm
Definition: Stitcher.h:70
blend images, by simply stacking them, without soft blending or boundary calculation ...
Definition: Stitcher.h:956
void copyImageIf(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor src_acc, MaskImageIterator mask_upperleft, MaskAccessor mask_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc)
Definition: openmp_vigra.h:316
void stitch(const PanoramaOptions &opts, const UIntSet &imgSet, const std::string &filename, SingleImageRemapper< ImageType, AlphaType > &remapper, BlendFunctor &blend)
Definition: Stitcher.h:899
float_type operator()() const
return the result
Definition: Stitcher.h:666
Some functions to create tiff images with masks.
unsigned int getHeight() const
get panorama height
void stitchPanoRGB_8_16(const PanoramaData &pano, const PanoramaOptions &opts, AppBase::ProgressDisplay *progress, const std::string &basename, const UIntSet &usedImgs, const char *pixelType, const AdvancedOptions &advOptions)
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
create a panorama using the reduce operation on all overlapping pixels.
Definition: Stitcher.h:689
Stitcher< ImageType, AlphaType > Base
Definition: Stitcher.h:464
Contains functions to transform whole images.
remap a set of images, and store the individual remapped files.
Definition: Stitcher.h:255
#define DEBUG_ASSERT(cond)
Definition: utils.h:80
vigra::Rect2D GetPanoROI() const
Definition: Stitcher.h:621
Difference reduce functor.
Definition: Stitcher.h:637
void exportImageAlpha(ImageIterator image_upper_left, ImageIterator image_lower_right, ImageAccessor image_accessor, AlphaIterator alpha_upper_left, AlphaAccessor alpha_accessor, const ImageExportInfo &export_info)
Write the image and its alpha channel to a file.
vigra::pair< typename ROIImage< Image, Mask >::image_const_traverser, typename ROIImage< Image, Mask >::ImageConstAccessor > srcImage(const ROIImage< Image, Mask > &img)
Definition: ROIImage.h:300
void stitchPanoGray_8_16(const PanoramaData &pano, const PanoramaOptions &opts, AppBase::ProgressDisplay *progress, const std::string &basename, const UIntSet &usedImgs, const char *pixelType, const AdvancedOptions &advOptions)
void stitch(const PanoramaOptions &opts, const UIntSet &imgSet, vigra::triple< ImgIter, ImgIter, ImgAccessor > pano, std::pair< AlphaIter, AlphaAccessor > alpha, SingleImageRemapper< ImageType, AlphaType > &remapper, FUNCTOR &reduce)
Definition: Stitcher.h:766
void saveRemapped(RemappedPanoImage< ImageType, AlphaType > &remapped, unsigned int imgNr, unsigned int nImg, const PanoramaOptions &opts, const std::string &basename, const bool useBigTIFF, AppBase::ProgressDisplay *progress)
Definition: Stitcher.h:128
void init(const PanoramaOptions &opts, const UIntSet &images)
Definition: Stitcher.h:92
UIntVector getEstimatedBlendingOrder(const PanoramaData &pano, const UIntSet &images, const unsigned int referenceImage)
returns vector of image numbers for blending in approbiate order
std::set< unsigned int > UIntSet
Definition: PanoramaData.h:51
virtual void prepareOutputFile(const PanoramaOptions &opts, const AdvancedOptions &advOptions)
prepare the output file (setup file structures etc.)
Definition: Stitcher.h:414
SimpleStitcher(const PanoramaData &pano, AppBase::ProgressDisplay *progress)
Definition: Stitcher.h:841
static const std::string & getFormatName(FileFormat f)
return string name of output file format
const vigra::Rect2D & getROI() const
vigra::Rect2D & boundingBox()
Definition: ROIImage.h:238
void calcSrcCoordImgs(DistImgType &imgX, DistImgType &imgY)
calculate distance map.
void taskFinished()
call when a task has finished and the status message should be cleared
virtual void finalizeOutputFile(const PanoramaOptions &opts)
Definition: Stitcher.h:386
virtual UIntSet getUsedImages()
Definition: Stitcher.h:99
void stitch(const PanoramaOptions &opts, const UIntSet &imgSet, const std::string &filename, SingleImageRemapper< ImageType, AlphaType > &remapper, FUNCTOR &reduce, const AdvancedOptions &advOptions)
Definition: Stitcher.h:704
Stitcher(const PanoramaData &pano, AppBase::ProgressDisplay *progress)
create a stitcher for the given panorama
Definition: Stitcher.h:74
std::string getExtension(const std::string &basename2)
Get extension of a filename.
Definition: utils.cpp:99
std::vector< unsigned int > UIntVector
Definition: PanoramaData.h:54
AppBase::ProgressDisplay * m_progress
Definition: Stitcher.h:120
vigra::FRGBImage ImageType
virtual void calcOutputROIS(const PanoramaOptions &opts, const UIntSet &images)
Definition: Stitcher.h:114
Stitcher< ImageType, AlphaType > Base
Definition: Stitcher.h:691
Image m_image
remapped image
Definition: ROIImage.h:273
const PanoramaData & m_pano
Definition: Stitcher.h:119
vigra::ImageExportInfo::ICCProfile iccProfile
Definition: Stitcher.h:950
MultiImageRemapper(const PanoramaData &pano, AppBase::ProgressDisplay *progress)
Definition: Stitcher.h:261
Helper class for storing different options.
vigra::ImageImportInfo::ICCProfile m_ICCProfile
void createAlphaTiffImage(ImageIterator upperleft, ImageIterator lowerright, ImageAccessor a, AlphaIterator alphaUpperleft, AlphaAccessor alphaA, vigra::TiffImage *tiff)
Definition: tiffUtils.h:522
void setMessage(const std::string &message, const std::string &filename="")
sets the message to given string
std::string stripExtension(const std::string &basename2)
remove extension of a filename
Definition: utils.cpp:130
Model for a panorama.
Definition: PanoramaData.h:81
functor to create a remapped image
Definition: ImageRemapper.h:41
virtual const SrcPanoImage & getImage(std::size_t nr) const =0
get a panorama image, counting starts with 0
static std::vector< vigra::Rect2D > computeROIS(const PanoramaData &panorama, const PanoramaOptions &opts, const UIntSet &images)
virtual void saveRemapped(RemappedPanoImage< ImageType, AlphaType > &remapped, unsigned int imgNr, unsigned int nImg, const PanoramaOptions &opts, const AdvancedOptions &advOptions)
save a remapped image, or layer
Definition: Stitcher.h:326
virtual void finalizeOutputFile(const PanoramaOptions &opts)
close the tiff file
Definition: Stitcher.h:447
vigra::pair< typename ROIImage< Image, Alpha >::image_traverser, typename ROIImage< Image, Alpha >::ImageAccessor > destImage(ROIImage< Image, Alpha > &img)
Definition: ROIImage.h:324
void stitchPanorama(const PanoramaData &pano, const PanoramaOptions &opt, AppBase::ProgressDisplay *progress, const std::string &basename, const UIntSet &usedImgs, const AdvancedOptions &advOptions)
The main stitching function.
Definition: Stitcher.cpp:40
MultiImageRemapper< ImageType, AlphaImageType > Base
Definition: Stitcher.h:403
Contains functions to transform whole images.
#define DEBUG_ERROR(msg)
Definition: utils.h:76
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 createTiffDirectory(vigra::TiffImage *tiff, const std::string &pagename, const std::string &documentname, const std::string comp, uint16_t page, uint16_t nImg, vigra::Diff2D offset, vigra::Size2D fullSize, const vigra::ImageExportInfo::ICCProfile &icc)
write a new Tiff directory, for a new layer
Definition: tiffUtils.h:58
#define IMPEX
Definition: hugin_shared.h:39
void stitchPanoGray_32_float(const PanoramaData &pano, const PanoramaOptions &opts, AppBase::ProgressDisplay *progress, const std::string &basename, const UIntSet &usedImgs, const char *pixelType, const AdvancedOptions &advOptions)
const std::string & getOutputExtension() const
return the extension used by the current output format
ReduceStitcher(const PanoramaData &pano, AppBase::ProgressDisplay *progress)
Definition: Stitcher.h:693
unsigned int getWidth() const
TiffMultiLayerRemapper(const PanoramaData &pano, AppBase::ProgressDisplay *progress)
Definition: Stitcher.h:404
A stitcher without seaming, just copies the images over each other.
Definition: Stitcher.h:837
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
void setAdvancedOptions(const HuginBase::Nona::AdvancedOptions advancedOptions)
Definition: ImageRemapper.h:60
void stitchPanoRGB_32_float(const PanoramaData &pano, const PanoramaOptions &opts, AppBase::ProgressDisplay *progress, const std::string &basename, const UIntSet &usedImgs, const char *pixelType, const AdvancedOptions &advOptions)
vigra::ImageImportInfo::ICCProfile iccProfile
Definition: Stitcher.h:628
static T max(T x, T y)
Definition: svm.cpp:65
void stitch(const PanoramaOptions &opts, const UIntSet &imgSet, const std::string &filename, SingleImageRemapper< ImageType, AlphaType > &remapper, const AdvancedOptions &advOptions)
Definition: Stitcher.h:548
#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
virtual void prepareOutputFile(const PanoramaOptions &opts, const AdvancedOptions &advOptions)
prepare the output file (setup file structures etc.)
Definition: Stitcher.h:320
std::map< std::string, std::string > AdvancedOptions
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
virtual void stitch(const PanoramaOptions &opts, const UIntSet &images, const std::string &file, SingleImageRemapper< ImageType, AlphaType > &remapper)
Stitch some images into a panorama file.
Definition: Stitcher.h:85
void copyImage(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor src_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc)
Definition: openmp_vigra.h:305
void calcAlpha()
calculate only the alpha channel.
void stitch(const PanoramaOptions &opts, const UIntSet &imgSet, vigra::triple< ImgIter, ImgIter, ImgAccessor > pano, std::pair< AlphaIter, AlphaAccessor > alpha, SingleImageRemapper< ImageType, AlphaType > &remapper, BlendFunctor &blend)
Definition: Stitcher.h:854
vigra::NumericTraits< argument_type > Traits
Definition: Stitcher.h:641
vigra::ImageImportInfo::ICCProfile iccProfile
Definition: Stitcher.h:831
WeightedStitcher(const PanoramaData &pano, AppBase::ProgressDisplay *progress)
Definition: Stitcher.h:465
std::vector< vigra::Rect2D > m_rois
Definition: Stitcher.h:122
functor to create a remapped image, loads image from disk
Definition: ImageRemapper.h:75
void ConvertTo8Bit(ImageType &image)
converts to given image to fit into 0..255
Definition: utils.h:757
Panorama image options.
std::vector< float_type > values
Definition: Stitcher.h:680
Stitcher< ImageType, AlphaType > Base
Definition: Stitcher.h:839
Stitcher< ImageType, AlphaType > Base
Definition: Stitcher.h:259
std::string tolower(const std::string &s)
convert a string to lowercase
Definition: stl_utils.h:49
std::string stripPath(const std::string &filename)
remove the path of a filename (mainly useful for gui display of filenames)
Definition: utils.cpp:160