Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
verdandi.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
2 
11 /* This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public
13 * License as published by the Free Software Foundation; either
14 * version 2 of the License, or (at your option) any later version.
15 *
16 * This software is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19 * General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public
22 * License along with this software. If not, see
23 * <http://www.gnu.org/licenses/>.
24 *
25 */
26 
27 #include <stdio.h>
28 #include <iostream>
29 #include <getopt.h>
30 #include <vigra_ext/impexalpha.hxx>
32 #include <vigra_ext/utils.h>
33 #include <hugin_utils/utils.h>
34 #include <hugin_utils/stl_utils.h>
35 
37 template <class ImageType, class MaskType>
38 bool SaveImage(ImageType& image, MaskType& mask, vigra::ImageExportInfo& exportImageInfo, std::string filetype, std::string pixelType, const vigra::Rect2D& roi, const int inputNumberBands)
39 {
40  exportImageInfo.setPixelType(pixelType.c_str());
41  if (vigra::isBandNumberSupported(filetype, inputNumberBands))
42  {
43  try
44  {
45  vigra::exportImageAlpha(vigra::srcImageRange(image, roi), vigra::srcImage(mask, roi.upperLeft()), exportImageInfo);
46  }
47  catch (std::exception& e)
48  {
49  std::cerr << "ERROR: Could not save " << exportImageInfo.getFileName() << std::endl
50  << "Cause: " << e.what() << std::endl;
51  return false;
52  };
53  return true;
54  }
55  else
56  {
57  if (vigra::isBandNumberSupported(filetype, inputNumberBands - 1))
58  {
59  std::cout << "Warning: Filetype " << filetype << " does not support alpha channels." << std::endl
60  << "Saving image without alpha channel." << std::endl;
61  try
62  {
63  vigra::exportImage(vigra::srcImageRange(image, roi), exportImageInfo);
64  }
65  catch (std::exception& e)
66  {
67  std::cerr << "ERROR: Could not save " << exportImageInfo.getFileName() << std::endl
68  << "Cause: " << e.what() << std::endl;
69  return false;
70  };
71  return true;
72  }
73  else
74  {
75  std::cerr << "ERROR: Output filetype " << filetype << " does not support " << inputNumberBands << " channels." << std::endl
76  << "Can't save image." << std::endl;
77  };
78  };
79  return false;
80 };
81 
83 template <class ImageType, class MaskType>
84 bool SaveFinalImage(ImageType& image, MaskType& mask, const std::string& inputPixelType, const int inputNumBands, vigra::ImageExportInfo& output, const vigra::Rect2D& roi)
85 {
86  VIGRA_UNIQUE_PTR<vigra::Encoder> encoder(vigra::encoder(output));
87  if (vigra::isPixelTypeSupported(encoder->getFileType(), inputPixelType))
88  {
89  return SaveImage(image, mask, output, encoder->getFileType(), inputPixelType, roi, inputNumBands);
90  }
91  else
92  {
93  if (vigra::isPixelTypeSupported(encoder->getFileType(), "UINT16"))
94  {
95  // transform to UINT16
96  output.setForcedRangeMapping(0, vigra::NumericTraits<typename vigra::NumericTraits<typename ImageType::PixelType>::ValueType>::max(), 0, 65535);
97  return SaveImage(image, mask, output, encoder->getFileType(), "UINT16", roi, inputNumBands);
98  }
99  else
100  {
101  if (vigra::isPixelTypeSupported(encoder->getFileType(), "UINT8"))
102  {
103  // transform to UINT8
104  output.setForcedRangeMapping(0, vigra::NumericTraits<typename vigra::NumericTraits<typename ImageType::PixelType>::ValueType>::max(), 0, 255);
105  return SaveImage(image, mask, output, encoder->getFileType(), "UINT8", roi, inputNumBands);
106  }
107  else
108  {
109  std::cerr << "ERROR: Output file type " << encoder->getFileType() << " does not support" << std::endl
110  << "requested pixeltype " << inputPixelType << "." << std::endl
111  << "Save output in other file format." << std::endl;
112  };
113  };
114  };
115  return false;
116 };
117 
119 void SetCompression(vigra::ImageExportInfo& output, const std::string& compression)
120 {
121  const std::string ext(hugin_utils::toupper(hugin_utils::getExtension(output.getFileName())));
122  if (!compression.empty())
123  {
124  if (ext == "JPEG" || ext == "JPG")
125  {
126  output.setCompression(std::string("JPEG QUALITY=" + compression).c_str());
127  }
128  else
129  {
130  output.setCompression(compression.c_str());
131  };
132  };
133 };
134 
136 template <class ImageType>
137 bool LoadAndMergeImages(std::vector<vigra::ImageImportInfo> imageInfos, const std::string& filename, const std::string& compression, const bool wrap, const bool hardSeam, const bool useBigTiff)
138 {
139  if (imageInfos.empty())
140  {
141  return false;
142  };
143  vigra::Size2D imageSize(imageInfos[0].getCanvasSize());
144  if (imageSize.area() == 0)
145  {
146  // not all images contains the canvas size/full image size
147  // in this case take also the position into account to get full image size
148  imageSize = vigra::Size2D(imageInfos[0].width() + imageInfos[0].getPosition().x,
149  imageInfos[0].height() + imageInfos[0].getPosition().y);
150  };
151  ImageType image(imageSize);
152  vigra::BImage mask(imageSize);
153  vigra::importImageAlpha(imageInfos[0],
154  std::pair<typename ImageType::Iterator, typename ImageType::Accessor>(image.upperLeft() + imageInfos[0].getPosition(), image.accessor()),
155  std::pair<typename vigra::BImage::Iterator, typename vigra::BImage::Accessor>(mask.upperLeft() + imageInfos[0].getPosition(), mask.accessor()));
156  std::cout << "Loaded " << imageInfos[0].getFileName() << std::endl;
157  vigra::Rect2D roi(vigra::Point2D(imageInfos[0].getPosition()), imageInfos[0].size());
158 
159  for (size_t i = 1; i < imageInfos.size(); ++i)
160  {
161  ImageType image2(imageInfos[i].size());
162  vigra::BImage mask2(image2.size());
163  vigra::importImageAlpha(imageInfos[i], vigra::destImage(image2), vigra::destImage(mask2));
164  std::cout << "Loaded " << imageInfos[i].getFileName() << std::endl;
165  roi |= vigra::Rect2D(vigra::Point2D(imageInfos[i].getPosition()), imageInfos[i].size());
166 
167  vigra_ext::MergeImages(image, mask, image2, mask2, imageInfos[i].getPosition(), wrap, hardSeam);
168  };
169  // save output
170  {
171  vigra::ImageExportInfo exportImageInfo(filename.c_str(), useBigTiff ? "w8" : "w");
172  exportImageInfo.setXResolution(imageInfos[0].getXResolution());
173  exportImageInfo.setYResolution(imageInfos[0].getYResolution());
174  exportImageInfo.setPosition(roi.upperLeft());
175  exportImageInfo.setCanvasSize(mask.size());
176  exportImageInfo.setICCProfile(imageInfos[0].getICCProfile());
177  SetCompression(exportImageInfo, compression);
178  return SaveFinalImage(image, mask, imageInfos[0].getPixelType(), imageInfos[0].numBands(), exportImageInfo, roi);
179  };
180 };
181 
183 static void usage(const char* name)
184 {
185  std::cout << name << ": blend images using watershed algorithm" << std::endl
186  << name << " version " << hugin_utils::GetHuginVersion() << std::endl
187  << std::endl
188  << "Usage: " << name << " [options] images" << std::endl
189  << std::endl
190  << " --output=FILE Set the filename for the output file." << std::endl
191  << " --compression=value Compression of the output files" << std::endl
192  << " For jpeg output: 0-100" << std::endl
193  << " For tiff output: PACKBITS, DEFLATE, LZW" << std::endl
194  << " -w, --wrap Wraparound 360 deg border." << std::endl
195  << " --seam=hard|blend Select the blend mode for the seam" << std::endl
196  << " --bigtiff Write output in BigTIFF format" << std::endl
197  << " (only with TIFF output)" << std::endl
198  << " -h, --help Shows this help" << std::endl
199  << std::endl;
200 };
201 
205 template<class ImageType, class MaskType>
206 bool ResaveImageFill(const vigra::ImageImportInfo& importInfo, vigra::ImageExportInfo& exportInfo, bool fillEdges, bool doWrap)
207 {
208  ImageType image(importInfo.size());
209  MaskType mask(image.size());
210  int numBands = importInfo.numBands();
211  if (importInfo.numExtraBands() == 0)
212  {
213  vigra::importImage(importInfo, vigra::destImage(image));
214  // init mask
216  // no alpha channel, so we can't detect empty edges
217  fillEdges = false;
218  ++numBands;
219  }
220  else
221  {
222  if (importInfo.numExtraBands() == 1)
223  {
224  vigra::importImageAlpha(importInfo, vigra::destImage(image), vigra::destImage(mask));
225  }
226  else
227  {
228  std::cerr << "ERROR: Images with several alpha channels are not supported." << std::endl;
229  return false;
230  };
231  };
232  std::cout << "Loaded " << importInfo.getFileName() << std::endl;
233  if (fillEdges)
234  {
235  const typename MaskType::PixelType maskZero = vigra_ext::LUTTraits<typename MaskType::PixelType>::min();
236  const typename MaskType::PixelType maskMax = vigra_ext::LUTTraits<typename MaskType::PixelType>::max();
238  // invert mask
239  MaskType dummyMask(image.size());
240  vigra::omp::transformImage(vigra::srcImageRange(mask), vigra::destImage(dummyMask), vigra::functor::ifThenElse(vigra::functor::Arg1() > vigra::functor::Param(maskMax / 2), vigra::functor::Param(maskZero), vigra::functor::Param(maskMax)));
241  // create label
242  vigra::BImage label(image.size());
243  vigra::omp::transformImage(vigra::srcImageRange(mask), vigra::destImage(label), vigra::functor::ifThenElse(vigra::functor::Arg1() > vigra::functor::Param(maskMax / 2), vigra::functor::Param(1), vigra::functor::Param(5)));
244  // check that we have uncovered labels
245  vigra::FindMinMax<vigra::UInt8> labelMinmax;
246  vigra::inspectImage(vigra::srcImageRange(label), labelMinmax);
247  if (labelMinmax.max > 1)
248  {
249  std::cout << "Filling edges" << std::endl;
250  // fill edges
251  vigra_ext::PoissonBlend(image, dummyImage, dummyMask, label, vigra::Point2D(0, 0), doWrap);
252  // now we need to update the mask
253  vigra::initImage(vigra::destImageRange(mask), maskMax);
254  };
255  };
256  const vigra::Rect2D roi(vigra::Point2D(0, 0), image.size());
257  return SaveFinalImage(image, mask, importInfo.getPixelType(), numBands, exportInfo, roi);
258 };
259 
260 int main(int argc, char* argv[])
261 {
262  // parse arguments
263  const char* optstring = "o:hw";
264 
265  enum
266  {
267  OPT_COMPRESSION = 1000,
268  OPT_SEAMMODE,
269  OPT_BIGTIFF
270  };
271  static struct option longOptions[] =
272  {
273  { "output", required_argument, NULL, 'o' },
274  { "compression", required_argument, NULL, OPT_COMPRESSION},
275  { "seam", required_argument, NULL, OPT_SEAMMODE},
276  { "wrap", no_argument, NULL, 'w' },
277  { "bigtiff", no_argument, NULL, OPT_BIGTIFF},
278  { "help", no_argument, NULL, 'h' },
279  0
280  };
281 
282  int c;
283  std::string output;
284  std::string compression;
285  bool wraparound = false;
286  bool hardSeam = true;
287  bool useBigTIFF = false;
288  while ((c = getopt_long(argc, argv, optstring, longOptions, nullptr)) != -1)
289  {
290  switch (c)
291  {
292  case 'o':
293  output = optarg;
294  break;
295  case 'h':
296  usage(hugin_utils::stripPath(argv[0]).c_str());
297  return 0;
298  break;
299  case OPT_COMPRESSION:
300  compression = hugin_utils::toupper(optarg);
301  break;
302  case OPT_SEAMMODE:
303  {
304  std::string text(optarg);
305  text = hugin_utils::tolower(text);
306  if (text == "hard")
307  {
308  hardSeam = true;
309  }
310  else
311  {
312  if (text == "blend")
313  {
314  hardSeam = false;
315  }
316  else
317  {
318  std::cerr << hugin_utils::stripPath(argv[0]) << ": String \"" << text << "\" is not a recognized seam blend mode." << std::endl;
319  return 1;
320  };
321  };
322  };
323  break;
324  case 'w':
325  wraparound = true;
326  break;
327  case OPT_BIGTIFF:
328  useBigTIFF = true;
329  break;
330  case ':':
331  case '?':
332  // missing argument or invalid switch
333  return 1;
334  break;
335  default:
336  // this should not happen
337  abort();
338  }
339  };
340 
341  unsigned nFiles = argc - optind;
342  if (nFiles < 1)
343  {
344  std::cerr << hugin_utils::stripPath(argv[0]) << ": at least one image need to be specified" << std::endl;
345  return 1;
346  }
347 
348  // extract file names
349  std::vector<std::string> files;
350  for (size_t i = 0; i < nFiles; i++)
351  {
352  std::string currentFile(argv[optind + i]);
353  // check file existence
354  if (hugin_utils::FileExists(currentFile))
355  {
356  files.push_back(currentFile);
357  };
358  }
359 
360  if (files.empty())
361  {
362  std::cerr << "ERROR: " << hugin_utils::stripPath(argv[0]) << " needs at least one image." << std::endl;
363  return 1;
364  };
365 
366  if (output.empty())
367  {
368  output = "final.tif";
369  };
370  hugin_utils::EnforceExtension(output, "tif");
372  {
373  std::cerr << "ERROR: Extension \"" << hugin_utils::getExtension(output) << "\" is unknown." << std::endl;
374  return 1;
375  };
376 
377 
378  bool success = false;
379  if (files.size() == 1)
380  {
381  //special case, only one image given
382  vigra::ImageImportInfo imageInfo(files[0].c_str());
383  vigra::ImageExportInfo exportInfo(output.c_str(), useBigTIFF ? "w8" : "w");
384  exportInfo.setXResolution(imageInfo.getXResolution());
385  exportInfo.setYResolution(imageInfo.getYResolution());
386  exportInfo.setCanvasSize(imageInfo.getCanvasSize());
387  exportInfo.setPosition(imageInfo.getPosition());
388  exportInfo.setICCProfile(imageInfo.getICCProfile());
389  SetCompression(exportInfo, compression);
390  const std::string pixeltype = imageInfo.getPixelType();
391  if (imageInfo.isColor())
392  {
393  if (pixeltype == "UINT8")
394  {
395  success = ResaveImageFill<vigra::BRGBImage, vigra::BImage>(imageInfo, exportInfo, !hardSeam, wraparound);
396  }
397  else if (pixeltype == "INT16")
398  {
399  success = ResaveImageFill<vigra::Int16RGBImage, vigra::Int16Image>(imageInfo, exportInfo, !hardSeam, wraparound);
400  }
401  else if (pixeltype == "UINT16")
402  {
403  success = ResaveImageFill<vigra::UInt16RGBImage, vigra::UInt16Image>(imageInfo, exportInfo, !hardSeam, wraparound);
404  }
405  else if (pixeltype == "INT32")
406  {
407  success = ResaveImageFill<vigra::Int32RGBImage, vigra::UInt32Image>(imageInfo, exportInfo, !hardSeam, wraparound);
408  }
409  else if (pixeltype == "UINT32")
410  {
411  success = ResaveImageFill<vigra::UInt32RGBImage, vigra::UInt32Image>(imageInfo, exportInfo, !hardSeam, wraparound);
412  }
413  else if (pixeltype == "FLOAT")
414  {
415  success = ResaveImageFill<vigra::FRGBImage, vigra::FImage>(imageInfo, exportInfo, !hardSeam, wraparound);
416  }
417  else
418  {
419  std::cerr << " ERROR: unsupported pixel type: " << pixeltype << std::endl;
420  };
421  }
422  else
423  {
424  //grayscale images
425  if (pixeltype == "UINT8")
426  {
427  success = ResaveImageFill<vigra::BImage, vigra::BImage>(imageInfo, exportInfo, !hardSeam, wraparound);
428  }
429  else if (pixeltype == "INT16")
430  {
431  success = ResaveImageFill<vigra::Int16Image, vigra::Int16Image>(imageInfo, exportInfo, !hardSeam, wraparound);
432  }
433  else if (pixeltype == "UINT16")
434  {
435  success = ResaveImageFill<vigra::UInt16Image, vigra::UInt16Image>(imageInfo, exportInfo, !hardSeam, wraparound);
436  }
437  else if (pixeltype == "INT32")
438  {
439  success = ResaveImageFill<vigra::Int32Image, vigra::Int32Image>(imageInfo, exportInfo, !hardSeam, wraparound);
440  }
441  else if (pixeltype == "UINT32")
442  {
443  success = ResaveImageFill<vigra::UInt32Image, vigra::UInt32Image>(imageInfo, exportInfo, !hardSeam, wraparound);
444  }
445  else if (pixeltype == "FLOAT")
446  {
447  success = ResaveImageFill<vigra::FImage, vigra::FImage>(imageInfo, exportInfo, !hardSeam, wraparound);
448  }
449  else
450  {
451  std::cerr << " ERROR: unsupported pixel type: " << pixeltype << std::endl;
452  };
453  };
454  }
455  else
456  {
457  std::vector<vigra::ImageImportInfo> imageInfos;
458  for (size_t i = 0; i < files.size(); ++i)
459  {
460  vigra::ImageImportInfo imageInfo(files[i].c_str());
461  imageInfos.push_back(imageInfo);
462  };
463  const std::string pixeltype(imageInfos[0].getPixelType());
464  if (imageInfos[0].numExtraBands() != 1)
465  {
466  std::cerr << "ERROR: Image does not contain alpha channel." << std::endl;
467  return 1;
468  }
469  //check, that image information matches
470  for (size_t i = 1; i < files.size(); ++i)
471  {
472  if (imageInfos[0].isColor() != imageInfos[i].isColor())
473  {
474  std::cerr << "ERROR: You can't merge color and grayscale images." << std::endl;
475  return 1;
476  };
477  if (imageInfos[0].numBands() != imageInfos[i].numBands())
478  {
479  std::cerr << "ERROR: You can't merge image with different number of channels." << std::endl
480  << " Image \"" << imageInfos[0].getFileName() << "\" has " << imageInfos[0].numBands() << " channels," << std::endl
481  << " but image \"" << imageInfos[i].getFileName() << "\" has " << imageInfos[i].numBands() << " channels." << std::endl;
482  return 1;
483  };
484  if (strcmp(pixeltype.c_str(), imageInfos[i].getPixelType()) != 0)
485  {
486  std::cerr << "ERROR: You can't merge images with different pixel types." << std::endl
487  << " Image \"" << imageInfos[0].getFileName() << "\" has pixel type " << imageInfos[0].getPixelType() << "," << std::endl
488  << " but image \"" << imageInfos[i].getFileName() << "\" has pixel type " << imageInfos[i].getPixelType() << "." << std::endl;
489  return 1;
490  };
491  };
492 
493  if (imageInfos[0].isColor())
494  {
495  if (pixeltype == "UINT8")
496  {
497  success = LoadAndMergeImages<vigra::BRGBImage>(imageInfos, output, compression, wraparound, hardSeam, useBigTIFF);
498  }
499  else if (pixeltype == "INT16")
500  {
501  success = LoadAndMergeImages<vigra::Int16RGBImage>(imageInfos, output, compression, wraparound, hardSeam, useBigTIFF);
502  }
503  else if (pixeltype == "UINT16")
504  {
505  success = LoadAndMergeImages<vigra::UInt16RGBImage>(imageInfos, output, compression, wraparound, hardSeam, useBigTIFF);
506  }
507  else if (pixeltype == "INT32")
508  {
509  success = LoadAndMergeImages<vigra::Int32RGBImage>(imageInfos, output, compression, wraparound, hardSeam, useBigTIFF);
510  }
511  else if (pixeltype == "UINT32")
512  {
513  success = LoadAndMergeImages<vigra::UInt32RGBImage>(imageInfos, output, compression, wraparound, hardSeam, useBigTIFF);
514  }
515  else if (pixeltype == "FLOAT")
516  {
517  success = LoadAndMergeImages<vigra::FRGBImage>(imageInfos, output, compression, wraparound, hardSeam, useBigTIFF);
518  }
519  else if (pixeltype == "DOUBLE")
520  {
521  success = LoadAndMergeImages<vigra::DRGBImage>(imageInfos, output, compression, wraparound, hardSeam, useBigTIFF);
522  }
523  else
524  {
525  std::cerr << " ERROR: unsupported pixel type: " << pixeltype << std::endl;
526  };
527  }
528  else
529  {
530  //grayscale images
531  if (pixeltype == "UINT8")
532  {
533  success = LoadAndMergeImages<vigra::BImage>(imageInfos, output, compression, wraparound, hardSeam, useBigTIFF);
534  }
535  else if (pixeltype == "INT16")
536  {
537  success = LoadAndMergeImages<vigra::Int16Image>(imageInfos, output, compression, wraparound, hardSeam, useBigTIFF);
538  }
539  else if (pixeltype == "UINT16")
540  {
541  success = LoadAndMergeImages<vigra::UInt16Image>(imageInfos, output, compression, wraparound, hardSeam, useBigTIFF);
542  }
543  else if (pixeltype == "INT32")
544  {
545  success = LoadAndMergeImages<vigra::Int32Image>(imageInfos, output, compression, wraparound, hardSeam, useBigTIFF);
546  }
547  else if (pixeltype == "UINT32")
548  {
549  success = LoadAndMergeImages<vigra::UInt32Image>(imageInfos, output, compression, wraparound, hardSeam, useBigTIFF);
550  }
551  else if (pixeltype == "FLOAT")
552  {
553  success = LoadAndMergeImages<vigra::FImage>(imageInfos, output, compression, wraparound, hardSeam, useBigTIFF);
554  }
555  else if (pixeltype == "DOUBLE")
556  {
557  success = LoadAndMergeImages<vigra::DImage>(imageInfos, output, compression, wraparound, hardSeam, useBigTIFF);
558  }
559  else
560  {
561  std::cerr << " ERROR: unsupported pixel type: " << pixeltype << std::endl;
562  };
563  };
564  };
565 
566  if (success)
567  {
568  std::cout << "Written result to " << output << std::endl;
569  return 0;
570  };
571  return 1;
572 }
bool FileExists(const std::string &filename)
checks if file exists
Definition: utils.cpp:362
void EnforceExtension(std::string &filename, const std::string &defaultExtension)
check if filename contains extension, if not add default extension
Definition: utils.cpp:411
void MergeImages(ImageType &image1, MaskType &mask1, const ImageType &image2, const MaskType &mask2, const vigra::Diff2D offset, const bool wrap, const bool hardSeam)
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
std::string toupper(const std::string &s)
Definition: stl_utils.h:59
functions to manage ROI&#39;s
bool IsFileTypeSupported(const std::string &filename)
return true, if file type by extension is supported by vigra
Definition: utils.cpp:405
bool LoadAndMergeImages(std::vector< vigra::ImageImportInfo > imageInfos, const std::string &filename, const std::string &compression, const bool wrap, const bool hardSeam, const bool useBigTiff)
loads image one by one and merge with all previouly loaded images, saves the final results ...
Definition: verdandi.cpp:137
std::string getExtension(const std::string &basename2)
Get extension of a filename.
Definition: utils.cpp:99
vigra::FRGBImage ImageType
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 importImageAlpha(const ImageImportInfo &import_info, ImageIterator image_iterator, ImageAccessor image_accessor, AlphaIterator alpha_iterator, AlphaAccessor alpha_accessor)
Read the image specified by the given vigra::ImageImportInfo object including its alpha channel...
Definition: impexalpha.hxx:479
bool SaveImage(ImageType &image, MaskType &mask, vigra::ImageExportInfo &exportImageInfo, std::string filetype, std::string pixelType)
save image, when possible with alpha channel, take care of formats which does not support alpha chann...
Definition: stacker.cpp:59
static T max(T x, T y)
Definition: svm.cpp:65
static void usage()
Definition: Main.cpp:32
std::string GetHuginVersion()
return a string with version numbers
Definition: utils.cpp:920
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
void transformImage(SrcImageIterator src_upperleft, SrcImageIterator src_lowerright, SrcAccessor src_acc, DestImageIterator dest_upperleft, DestAccessor dest_acc, const Functor &func)
Definition: openmp_vigra.h:330
bool ResaveImageFill(const vigra::ImageImportInfo &importInfo, vigra::ImageExportInfo &exportInfo, bool fillEdges, bool doWrap)
resave a single image LoadAndMergeImage would require the full canvas size for loading, so using this specialized version which is using the cropped intermediates images
Definition: verdandi.cpp:206
static T min(T x, T y)
Definition: svm.cpp:62
bool SaveFinalImage(ImageType &image, MaskType &mask, const std::string &inputPixelType, vigra::ImageExportInfo &output)
save final image, take care of some supported pixel types and convert when necessary to smaller pixel...
Definition: stacker.cpp:107
std::string tolower(const std::string &s)
convert a string to lowercase
Definition: stl_utils.h:49
void PoissonBlend(ImageType &image1, const ImageType &image2, const MaskType &mask2, const vigra::BImage &labels, const vigra::Point2D &offsetPoint, const bool doWrap)
std::string stripPath(const std::string &filename)
remove the path of a filename (mainly useful for gui display of filenames)
Definition: utils.cpp:160
void SetCompression(vigra::ImageExportInfo &output, const std::string &compression)
set compression for jpeg or tiff
Definition: stacker.cpp:41
int main(int argc, char *argv[])
Definition: Main.cpp:167