Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CleanCP.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
14  /* This is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU General Public
16  * License as published by the Free Software Foundation; either
17  * version 2 of the License, or (at your option) any later version.
18  *
19  * This software is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22  * Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU General Public
25  * License along with this software. If not, see
26  * <http://www.gnu.org/licenses/>.
27  *
28  */
29 
30 #include "CleanCP.h"
34 
35 namespace HuginBase {
36 
38 {
39  CPVector allCP=pano.getCtrlPoints();
40  unsigned int nrImg=pano.getNrOfImages();
41  PanoramaOptions opts=pano.getOptions();
42  //set projection to equrectangular for optimisation
44  pano.setOptions(opts);
45  UIntSet CPtoRemove;
46 
47  // do optimisation of all images pair
48  // after it remove cp with errors > median/mean + n*sigma
49  for (unsigned int image1=0; image1<nrImg-1; image1++)
50  {
51  const SrcPanoImage& img=pano.getImage(image1);
52  for (unsigned int image2=image1+1; image2<nrImg; image2++)
53  {
54  //do not check linked image pairs
55  if(img.YawisLinkedWith(pano.getImage(image2)))
56  continue;
57  UIntSet Images;
58  Images.clear();
59  Images.insert(image1);
60  Images.insert(image2);
61  Panorama clean=pano.getSubset(Images);
62  // pictures should contain at least 2 control points
63  if(clean.getNrOfCtrlPoints()>1)
64  {
65  // remove all horizontal and vertical control points
66  CPVector cpl = clean.getCtrlPoints();
67  CPVector newCP;
68  for (CPVector::const_iterator it = cpl.begin(); it != cpl.end(); ++it)
69  if (it->mode == ControlPoint::X_Y)
70  newCP.push_back(*it);
71  clean.setCtrlPoints(newCP);
72 
73  // we need at least 3 cp to optimize 3 variables: yaw, pitch and roll
74  if(clean.getNrOfCtrlPoints()>3)
75  {
76  //optimize position and hfov
77  OptimizeVector optvec;
78  std::set<std::string> imgopt;
79  //imgopt.insert("v");
80  optvec.push_back(imgopt);
81  imgopt.insert("r");
82  imgopt.insert("p");
83  imgopt.insert("y");
84  optvec.push_back(imgopt);
85  clean.setOptimizeVector(optvec);
86  PTools::optimize(clean);
87  cpl.clear();
88  cpl=clean.getCtrlPoints();
89  //calculate statistic and determine limit
90  double min,max,mean,var;
92  // if the standard deviation is bigger than the value, assume we have a lot of
93  // false cp, in this case take the mean value directly as limit
94  double limit = (sqrt(var) > mean) ? mean : (mean + n*sqrt(var));
95 
96  //identify cp with big error
97  unsigned int index=0;
98  unsigned int cpcounter=0;
99  for (CPVector::const_iterator it = allCP.begin(); it != allCP.end(); ++it)
100  {
101  if(it->mode == ControlPoint::X_Y)
102  if((it->image1Nr==image1 && it->image2Nr==image2) ||
103  (it->image1Nr==image2 && it->image2Nr==image1))
104  {
105  if (cpl[index].error>limit)
106  CPtoRemove.insert(cpcounter);
107  index++;
108  };
109  cpcounter++;
110  };
111  };
112  };
113  if (!progress.updateDisplayValue())
114  {
115  return CPtoRemove;
116  };
117  };
118  };
119 
120  return CPtoRemove;
121 };
122 
123 UIntSet getCPoutsideLimit(Panorama pano, double n, bool skipOptimisation, bool includeLineCp)
124 {
125  UIntSet CPtoRemove;
126  if(skipOptimisation)
127  {
128  //calculate current cp errors
130  }
131  else
132  {
133  //optimize pano, after optimization pano contains the cp errors of the optimized project
135  };
136  CPVector allCP=pano.getCtrlPoints();
137  if(!includeLineCp)
138  {
139  //remove all horizontal and vertical CP for calculation of mean and sigma
140  CPVector CPxy;
141  for (CPVector::const_iterator it = allCP.begin(); it != allCP.end(); ++it)
142  {
143  if(it->mode == ControlPoint::X_Y)
144  CPxy.push_back(*it);
145  };
146  pano.setCtrlPoints(CPxy);
147  };
148  //calculate mean and sigma
149  double min,max,mean,var;
151  if(!includeLineCp)
152  {
153  pano.setCtrlPoints(allCP);
154  };
155  // if the standard deviation is bigger than the value, assume we have a lot of
156  // false cp, in this case take the mean value directly as limit
157  double limit = (sqrt(var) > mean) ? mean : (mean + n*sqrt(var));
158 
159  //now determine all control points with error > limit
160  unsigned int index=0;
161  for (CPVector::const_iterator it = allCP.begin(); it != allCP.end(); ++it)
162  {
163  if(it->error > limit)
164  {
165  if(includeLineCp)
166  {
167  // all cp are treated the same
168  // no need for further checks
169  CPtoRemove.insert(index);
170  }
171  else
172  {
173  //check only normal cp
174  if(it->mode == ControlPoint::X_Y)
175  {
176  CPtoRemove.insert(index);
177  };
178  };
179  };
180  index++;
181  };
182 
183  return CPtoRemove;
184 };
185 
187 {
188  HuginBase::UIntSet cps;
189  HuginBase::CPVector cpList=pano.getCtrlPoints();
190  if(!cpList.empty())
191  {
192  for(unsigned int i=0;i<cpList.size();i++)
193  {
194  HuginBase::ControlPoint cp=cpList[i];
195  // ignore line control points
197  continue;
198  bool insideMask=false;
199  // check first image
200  // remark: we could also use pano.getImage(cp.image1Nr).isInside(vigra::Point2D(cp.x1,cp.y1))
201  // this would also check the crop rectangles/circles
202  // but it would require that the pano is correctly align, otherwise the positive masks
203  // would not correctly checked
204  HuginBase::MaskPolygonVector masks=pano.getImage(cp.image1Nr).getMasks();
205  if(!masks.empty())
206  {
207  unsigned int j=0;
208  while((!insideMask) && (j<masks.size()))
209  {
210  insideMask=masks[j].isInside(hugin_utils::FDiff2D(cp.x1,cp.y1));
211  j++;
212  };
213  };
214  // and now the second
215  if(!insideMask)
216  {
217  masks=pano.getImage(cp.image2Nr).getMasks();
218  if(!masks.empty())
219  {
220  unsigned int j=0;
221  while((!insideMask) && (j<masks.size()))
222  {
223  insideMask=masks[j].isInside(hugin_utils::FDiff2D(cp.x2,cp.y2));
224  j++;
225  };
226  };
227  };
228  if(insideMask)
229  cps.insert(i);
230  };
231  }
232  return cps;
233 };
234 
235 } // namespace
static void smartOptimize(PanoramaData &pano)
static void calcCtrlPntsErrorStats(const PanoramaData &pano, double &min, double &max, double &mean, double &var, const int &imgNr=-1, const bool onlyActive=false, const bool ignoreLineCp=false)
std::size_t getNrOfCtrlPoints() const
number of control points
Definition: Panorama.h:306
Panorama getSubset(const UIntSet &imgs) const
get a subset of the panorama
const CPVector & getCtrlPoints() const
get all control point of this Panorama
Definition: Panorama.h:319
bool isInside(vigra::Point2D p, bool ignoreMasks=false) const
check if a coordinate is inside the source image
represents a control point
Definition: ControlPoint.h:38
void setOptimizeVector(const OptimizeVector &optvec)
set optimize setting
Definition: Panorama.cpp:297
std::set< unsigned int > UIntSet
Definition: PanoramaData.h:51
algorithms for remove control points by statistic method
void calcCtrlPointErrors(PanoramaData &pano)
Update the Ctrl Point errors without optimizing.
Model for a panorama.
Definition: Panorama.h:152
std::size_t getNrOfImages() const
number of images.
Definition: Panorama.h:205
UIntSet getCPoutsideLimit_pair(Panorama pano, AppBase::ProgressDisplay &progress, double n)
optimises images pairwise and removes for every image pair control points with error &gt; mean+n*sigma ...
Definition: CleanCP.cpp:37
void setCtrlPoints(const CPVector &points)
set all control points (Ippei: Is this supposed to be &#39;add&#39; method?)
Definition: Panorama.cpp:449
std::vector< MaskPolygon > MaskPolygonVector
Definition: Mask.h:147
!! from PTOptimise.h 1951
Utility calls into PanoTools using CPP interface.
const PanoramaOptions & getOptions() const
returns the options for this panorama
Definition: Panorama.h:481
UIntSet getCPoutsideLimit(Panorama pano, double n, bool skipOptimisation, bool includeLineCp)
optimises the whole panorama and removes all control points with error &gt; mean+n*sigma ...
Definition: CleanCP.cpp:123
static T max(T x, T y)
Definition: svm.cpp:65
unsigned int optimize(PanoramaData &pano, const char *userScript)
optimize the images imgs, for variables optvec, using vars as start.
std::vector< ControlPoint > CPVector
Definition: ControlPoint.h:99
std::vector< std::set< std::string > > OptimizeVector
const SrcPanoImage & getImage(std::size_t nr) const
get a panorama image, counting starts with 0
Definition: Panorama.h:211
void setOptions(const PanoramaOptions &opt)
set new output settings This is not used directly for optimizing/stiching, but it can be feed into ru...
Definition: Panorama.cpp:1531
UIntSet getCPinMasks(HuginBase::Panorama pano)
returns these control points, which are in masks
Definition: CleanCP.cpp:186
All variables of a source image.
Definition: SrcPanoImage.h:194
void setProjection(ProjectionFormat f)
set the Projection format and adjust the hfov/vfov if nessecary
Panorama image options.
static T min(T x, T y)
Definition: svm.cpp:62