Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
LayerStacks.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
8  /* This is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public
10  * License as published by the Free Software Foundation; either
11  * version 2 of the License, or (at your option) any later version.
12  *
13  * This software is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public
19  * License along with this software. If not, see
20  * <http://www.gnu.org/licenses/>.
21  *
22  */
23 
24 #include "LayerStacks.h"
25 
26 #include <panodata/PanoramaData.h>
31 
32 namespace HuginBase
33 {
34 
35 std::vector<UIntSet> getHDRStacks(const PanoramaData & pano, UIntSet allImgs, PanoramaOptions opts)
36 {
37  std::vector<UIntSet> result;
38 
39  // if no images are available, return empty result vector
40  if ( allImgs.empty() )
41  {
42  return result;
43  }
44 
45  // special case: for a negtive overlap use the assigned stacks and skip
46  // overlap calculation
47  if (opts.outputStacksMinOverlap < 0)
48  {
49  // first get all stacks
50  HuginBase::ConstStandardImageVariableGroups variable_groups(pano);
51  std::vector<UIntSet> allStacks = variable_groups.getStacks().getPartsSet();
52  std::vector<UIntSet> activeStacks;
53  for (const auto& singleStack : allStacks)
54  {
55  // now check that each stack contains only active images
56  UIntSet activeImgsInStack;
57  std::set_intersection(singleStack.begin(), singleStack.end(), allImgs.begin(), allImgs.end(), std::inserter(activeImgsInStack, activeImgsInStack.begin()));
58  if (!activeImgsInStack.empty())
59  {
60  activeStacks.push_back(activeImgsInStack);
61  };
62  }
63  return activeStacks;
64  };
65 
66  UIntSet stack;
67 
68  CalculateImageOverlap overlap(&pano);
69  overlap.calculate(10); // we are testing 10*10=100 points
70  do
71  {
72  const unsigned srcImg = *(allImgs.begin());
73  stack.insert(srcImg);
74  allImgs.erase(srcImg);
75 
76  // find all images that have a suitable overlap.
77  for (UIntSet::const_iterator it = allImgs.begin(); it != allImgs.end(); ++it)
78  {
79  const unsigned srcImg2 = *it;
80  if (overlap.getOverlap(srcImg, srcImg2) > opts.outputStacksMinOverlap)
81  {
82  stack.insert(srcImg2);
83  };
84  };
85  for (UIntSet::const_iterator it = stack.begin(); it != stack.end(); ++it)
86  {
87  allImgs.erase(*it);
88  };
89  result.push_back(stack);
90  stack.clear();
91  } while (!allImgs.empty());
92 
93  return result;
94 }
95 
96 std::vector<UIntSet> getExposureLayers(const PanoramaData & pano, UIntSet allImgs, PanoramaOptions opts)
97 {
98  return getExposureLayers(pano, allImgs, opts.outputLayersExposureDiff);
99 };
100 
101 std::vector<UIntSet> getExposureLayers(const PanoramaData & pano, UIntSet allImgs, const double maxEVDiff)
102 {
103  std::vector<UIntSet> result;
104 
105  // if no images are available, return empty result vector
106  if ( allImgs.empty() )
107  {
108  return result;
109  }
110 
111  UIntSet layer;
112 
113  do
114  {
115  const unsigned srcImg = *(allImgs.begin());
116  layer.insert(srcImg);
117  allImgs.erase(srcImg);
118 
119  // find all images that have a similar exposure values.
120  const double firstExposureValue = pano.getImage(srcImg).getExposureValue();
121  for (UIntSet::const_iterator it = allImgs.begin(); it != allImgs.end(); ++it)
122  {
123  const unsigned srcImg2 = *it;
124  if ( fabs(firstExposureValue - pano.getImage(srcImg2).getExposureValue()) < maxEVDiff )
125  {
126  layer.insert(srcImg2);
127  }
128  }
129  for (UIntSet::const_iterator it = layer.begin(); it != layer.end(); ++it)
130  {
131  allImgs.erase(*it);
132  };
133  result.push_back(layer);
134  layer.clear();
135  } while (!allImgs.empty());
136 
137  return result;
138 }
139 
140 UIntSet getImagesinROI (const PanoramaData& pano, const UIntSet activeImages)
141 {
142  return getImagesinROI(pano, activeImages, pano.getOptions().getROI());
143 }
144 
145 UIntSet getImagesinROI(const PanoramaData& pano, const UIntSet activeImages, vigra::Rect2D panoROI)
146 {
147  UIntSet images;
148  PanoramaOptions opts = pano.getOptions();
149  opts.setROI(panoROI);
150  for (UIntSet::const_iterator it = activeImages.begin(); it != activeImages.end(); ++it)
151  {
152  vigra::Rect2D roi = estimateOutputROI(pano, opts, *it);
153  if (!(roi.isEmpty()))
154  {
155  images.insert(*it);
156  }
157  }
158  return images;
159 }
160 
162 {
163  explicit SortVectorByExposure(const HuginBase::Panorama* pano) : m_pano(pano) {};
164  bool operator()(const size_t& img1, const size_t& img2)
165  {
166  return m_pano->getImage(img1).getExposureValue() < m_pano->getImage(img2).getExposureValue();
167  }
168 private:
170 };
171 
172 std::vector<HuginBase::UIntVector> getSortedStacks(const HuginBase::Panorama* pano)
173 {
174  std::vector<HuginBase::UIntVector> stacks;
175  if (pano->getNrOfImages() == 0)
176  {
177  return stacks;
178  };
179  HuginBase::ConstStandardImageVariableGroups variable_groups(*pano);
180  HuginBase::UIntSetVector imageGroups = variable_groups.getStacks().getPartsSet();
181  //get image with median exposure for search with cp generator
182  for (size_t imgGroup = 0; imgGroup < imageGroups.size(); ++imgGroup)
183  {
184  HuginBase::UIntVector stackImages(imageGroups[imgGroup].begin(), imageGroups[imgGroup].end());
185  std::sort(stackImages.begin(), stackImages.end(), SortVectorByExposure(pano));
186  stacks.push_back(stackImages);
187  };
188  return stacks;
189 };
190 
192 {
193 public:
194  virtual void Visit(const size_t vertex, const HuginBase::UIntSet& visitedNeighbors, const HuginBase::UIntSet& unvisitedNeighbors)
195  {
196  images.push_back(vertex);
197  };
198  UIntVector GetTranslatedImageNumbers(const UIntVector& translatedImgNumbers) const
199  {
200  UIntVector result(images.size(), 0);
201  for (size_t i = 0; i < images.size(); ++i)
202  {
203  result[i] = translatedImgNumbers[images[i]];
204  };
205  return result;
206  };
207 private:
209 };
210 
211 UIntVector getEstimatedBlendingOrder(const PanoramaData & pano, const UIntSet& images, const unsigned int referenceImage)
212 {
213  if (images.empty())
214  {
215  return UIntVector();
216  };
217  unsigned int refImage;
218  if (set_contains(images, referenceImage))
219  {
220  refImage = referenceImage;
221  }
222  else
223  {
224  refImage = *images.begin();
225  }
226  // store a vector for translating image numbers later
227  HuginBase::UIntVector subpanoImages;
228  std::copy(images.begin(), images.end(), std::back_inserter(subpanoImages));
229  // create subpano with all active images, don't forget to delete at end
230  HuginBase::PanoramaData* subPano = pano.getNewSubset(images);
231  // calculate overlap
232  CalculateImageOverlap overlap(subPano);
233  overlap.calculate(10); // we are testing 10*10=100 points
234  // now build ImageGraph and iterate all images
235  HuginGraph::ImageGraph graph(overlap);
236  GraphVisitor graphVisitor;
237  graph.VisitAllImages(refImage, true, &graphVisitor);
238  delete subPano;
239  // translate image numbers to original images
240  return graphVisitor.GetTranslatedImageNumbers(subpanoImages);
241 };
242 
243 }
const HuginBase::Panorama * m_pano
std::vector< UIntSet > getHDRStacks(const PanoramaData &pano, UIntSet allImgs, PanoramaOptions opts)
returns vector of set of output stacks
Definition: LayerStacks.cpp:35
declaration of functions to handle stacks and layers
std::vector< UIntSet > UIntSetVector
Definition: PanoramaData.h:56
std::vector< UIntSet > getExposureLayers(const PanoramaData &pano, UIntSet allImgs, PanoramaOptions opts)
returns vector of set of output exposure layers
Definition: LayerStacks.cpp:96
double getOverlap(unsigned int i, unsigned int j) const
returns the overlap for 2 images with number i and j
bool operator()(const size_t &img1, const size_t &img2)
ConstImageVariableGroup & getStacks()
Get the ImageVariableGroup representing the group of stack variables.
vigra::Rect2D estimateOutputROI(const PanoramaData &pano, const PanoramaOptions &opts, unsigned i, const double maxLength)
Somewhere to specify what variables belong to what.
UIntSet getImagesinROI(const PanoramaData &pano, const UIntSet activeImages)
returns set of images which are visible in output ROI
bool set_contains(const _Container &c, const typename _Container::key_type &key)
Definition: stl_utils.h:74
void calculate(unsigned int steps)
does the calculation, for each image steps*steps points are extracted and tested with all other image...
UIntVector getEstimatedBlendingOrder(const PanoramaData &pano, const UIntSet &images, const unsigned int referenceImage)
returns vector of image numbers for blending in approbiate order
virtual void Visit(const size_t vertex, const HuginBase::UIntSet &visitedNeighbors, const HuginBase::UIntSet &unvisitedNeighbors)
std::set< unsigned int > UIntSet
Definition: PanoramaData.h:51
const vigra::Rect2D & getROI() const
Model for a panorama.
Definition: Panorama.h:152
UIntSetVector getPartsSet() const
return a vector which contains a HuginBase::UIntSet for each group with the corresponding images numb...
std::size_t getNrOfImages() const
number of images.
Definition: Panorama.h:205
std::vector< unsigned int > UIntVector
Definition: PanoramaData.h:54
void VisitAllImages(const size_t startImg, bool forceAllComponents, BreadthFirstSearchVisitor *visitor)
visit all images via a breadth first search algorithm for each visited images, the functor visitor is...
Definition: ImageGraph.cpp:176
virtual const PanoramaOptions & getOptions() const =0
returns the options for this panorama
std::vector< HuginBase::UIntVector > getSortedStacks(const HuginBase::Panorama *pano)
returns vector of UIntVector with image numbers of each stack sorted by exposure
Make an ImageVariableGroup for lenses and other common concepts.
Model for a panorama.
Definition: PanoramaData.h:81
virtual const SrcPanoImage & getImage(std::size_t nr) const =0
get a panorama image, counting starts with 0
void setROI(const vigra::Rect2D &val)
definitions of classes to calculate overlap between different images
class for calculating overlap of images
const SrcPanoImage & getImage(std::size_t nr) const
get a panorama image, counting starts with 0
Definition: Panorama.h:211
UIntVector GetTranslatedImageNumbers(const UIntVector &translatedImgNumbers) const
Panorama image options.
SortVectorByExposure(const HuginBase::Panorama *pano)
abstract base functor for breadth first search in ImageGraph
Definition: ImageGraph.h:35
virtual PanoramaData * getNewSubset(const UIntSet &imgs) const =0
class to work with images graphs created from a HuginBase::Panorama class it creates a graph based on...
Definition: ImageGraph.h:44