Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CalculateOverlap.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
2 
13 /* This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public
15  * License as published by the Free Software Foundation; either
16  * version 2 of the License, or (at your option) any later version.
17  *
18  * This software is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21  * General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public
24  * License along with this software. If not, see
25  * <http://www.gnu.org/licenses/>.
26  *
27  */
28 
29 #include "CalculateOverlap.h"
30 
31 namespace HuginBase {
32 
34 {
35  m_nrImg=pano->getNrOfImages();
36  if(m_nrImg>0)
37  {
38  m_overlap.resize(m_nrImg);
39  PanoramaOptions opts=pano->getOptions();
40  m_transform.resize(m_nrImg);
41  m_invTransform.resize(m_nrImg);
42  for(unsigned int i=0;i<m_nrImg;i++)
43  {
44  m_overlap[i].resize(m_nrImg,0);
46  m_transform[i]->createTransform(*pano,i,opts);
48  m_invTransform[i]->createInvTransform(*pano,i,opts);
49  };
50  // per default we are testing all images
51  for (unsigned int i = 0; i < m_nrImg; i++)
52  {
53  m_testImages.push_back(i);
54  }
55  };
56 };
57 
59 {
60  for(unsigned int i=0;i<m_nrImg;i++)
61  {
62  delete m_transform[i];
63  delete m_invTransform[i];
64  };
65 };
66 
67 void CalculateImageOverlap::calculate(unsigned int steps)
68 {
69  if(m_testImages.empty())
70  {
71  return;
72  };
73 #pragma omp parallel for schedule(dynamic)
74  for (int i = 0; i < m_testImages.size(); ++i)
75  {
76  unsigned int imgNr = m_testImages[i];
77  const SrcPanoImage& img = m_pano->getImage(imgNr);
78  vigra::Rect2D c=vigra::Rect2D(img.getSize());
79  if(img.getCropMode()!=SrcPanoImage::NO_CROP)
80  {
81  c&=img.getCropRect();
82  };
83  unsigned int frequency=std::min<unsigned int>(steps,std::min<unsigned int>(c.width(),c.height()));
84  if(frequency<2)
85  frequency=2;
86  std::vector<unsigned int> overlapCounter;
87  overlapCounter.resize(m_nrImg,0);
88  unsigned int pointCounter=0;
89  for (unsigned int x=0; x<frequency; x++)
90  {
91  for (unsigned int y=0; y<frequency; y++)
92  {
93  // scale (x, y) so it is always within the cropped region of the
94  // image.
95  double xc = double (x) / double (frequency) * double(c.width()) + c.left();
96  double yc = double (y) / double (frequency) * double(c.height()) + c.top();
97  vigra::Point2D p(xc,yc);
98  //check if inside crop, especially for circular crops
99  if(img.isInside(p,true))
100  {
101  pointCounter++;
102  //transform to panorama coordinates
103  double xi,yi;
104  if (m_invTransform[imgNr]->transformImgCoord(xi, yi, xc, yc))
105  {
106  //now, check if point is inside another image
107  for(unsigned int j=0;j<m_nrImg;j++)
108  {
109  if (imgNr == j)
110  continue;
111  double xj,yj;
112  //transform to image coordinates
113  if(m_transform[j]->transformImgCoord(xj,yj,xi,yi))
114  {
115  p.x=xj;
116  p.y=yj;
117  if(m_pano->getImage(j).isInside(p,true))
118  {
119  overlapCounter[j]++;
120  };
121  };
122  };
123  };
124  };
125  };
126  };
127  //now calculate overlap and save
128  m_overlap[imgNr][imgNr] = 1.0;
129  if(pointCounter>0)
130  {
131  for(unsigned int k=0;k<m_nrImg;k++)
132  {
133  if (imgNr == k)
134  {
135  continue;
136  };
137  m_overlap[imgNr][k] = (double)overlapCounter[k] / (double)pointCounter;
138  };
139  };
140  };
141 };
142 
143 double CalculateImageOverlap::getOverlap(unsigned int i, unsigned int j) const
144 {
145  if(i==j)
146  {
147  return 1.0;
148  }
149  else
150  {
151  return std::max<double>(m_overlap[i][j],m_overlap[j][i]);
152  };
153 };
154 
156 {
157  UIntSet overlapImgs;
158  for(unsigned int j=0;j<m_nrImg;j++)
159  {
160  if(i!=j)
161  {
162  if(getOverlap(i,j)>0)
163  {
164  overlapImgs.insert(j);
165  };
166  };
167  };
168  return overlapImgs;
169 };
170 
172 {
173  m_testImages.clear();
174  for (UIntSet::const_iterator it = img.begin(); it != img.end(); ++it)
175  {
176  m_testImages.push_back(*it);
177  };
178 };
179 
180 } // namespace
double getOverlap(unsigned int i, unsigned int j) const
returns the overlap for 2 images with number i and j
std::vector< PTools::Transform * > m_invTransform
void calculate(unsigned int steps)
does the calculation, for each image steps*steps points are extracted and tested with all other image...
bool isInside(vigra::Point2D p, bool ignoreMasks=false) const
check if a coordinate is inside the source image
std::vector< PTools::Transform * > m_transform
std::set< unsigned int > UIntSet
Definition: PanoramaData.h:51
std::vector< unsigned int > m_testImages
UIntSet getOverlapForImage(unsigned int i) const
returns a set of images which overlap with given image number
std::vector< std::vector< double > > m_overlap
virtual const PanoramaOptions & getOptions() const =0
returns the options for this panorama
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
definitions of classes to calculate overlap between different images
Holds transformations for Image -&gt; Pano and the other way.
virtual ~CalculateImageOverlap()
destructor
virtual std::size_t getNrOfImages() const =0
number of images.
All variables of a source image.
Definition: SrcPanoImage.h:194
Panorama image options.
CalculateImageOverlap(const PanoramaData *pano)
constructor
void limitToImages(UIntSet img)
limits the calculation of the overlap to given image numbers