Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PTOptimizer.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
28 #include "PTOptimizer.h"
29 
30 #include "ImageGraph.h"
38 #include <vigra_ext/ransac.h>
39 
40 #if DEBUG
41 #include <fstream>
42 // pano13 include <Carbon/Carbon.h> -> /usr/include/MacTypes.h, causing a name collision with boost
43 #if defined(__APPLE__) && defined(nil)
44 #undef nil
45 #endif
46 #include <boost/graph/graphviz.hpp>
47 #endif
48 
49 namespace HuginBase {
50 
52 {
54  return true; // let's hope so.
55 }
56 
57 // small helper class
59 {
60 public:
61  OptVarSpec(int img, std::string name)
62  : m_img(img), m_name(name)
63  {
64  }
65 
66  double get(PanoramaData & pano) const
67  {
68  return pano.getImage(m_img).getVar(m_name);
69  }
70  void set(PanoramaData & pano, double x) const
71  {
73  }
74  int m_img;
75  std::string m_name;
76 };
77 
80 {
81 
82 public:
83 
84  PTOptEstimator(PanoramaData & pano, int i1, int i2, double maxError,
85  bool optHFOV, bool optB)
86  {
87  m_maxError = maxError;
88 
89  UIntSet imgs;
90  imgs.insert(i1);
91  imgs.insert(i2);
92  m_localPano = (pano.getNewSubset(imgs)); // don't forget to delete
93  m_li1 = (i1 < i2) ? 0 : 1;
94  m_li2 = (i1 < i2) ? 1 : 0;
95  // get control points
97  // only use 2D control points
98  for (size_t i = 0; i < m_cps.size();++i)
99  {
100  const ControlPoint& kp=m_cps[i];
101  if (kp.mode == ControlPoint::X_Y)
102  {
103  m_xy_cps.push_back(kp);
104  }
105  }
106 
107  if (optHFOV)
108  m_optvars.push_back(OptVarSpec(0,std::string("v")));
109  if (optB)
110  m_optvars.push_back(OptVarSpec(0,std::string("b")));
111  m_optvars.push_back(OptVarSpec(m_li2,"r"));
112  m_optvars.push_back(OptVarSpec(m_li2,"p"));
113  m_optvars.push_back(OptVarSpec(m_li2,"y"));
114  if (optHFOV)
115  m_optvars.push_back(OptVarSpec(0,"v"));
116  if (optB)
117  m_optvars.push_back(OptVarSpec(0,"b"));
118 
120  m_opt_first_pass.resize(2);
121  m_opt_first_pass[1].insert("r");
122  m_opt_first_pass[1].insert("p");
123  m_opt_first_pass[1].insert("y");
124 
126  if (optHFOV || optB) {
128  if (optHFOV)
129  m_opt_second_pass[0].insert("v");
130  if (optB)
131  m_opt_second_pass[0].insert("b");
132  }
133 
134  // number of points required for estimation
135  m_numForEstimate = (m_optvars.size()+1)/2;
136 
137  // extract initial parameters from pano
138  m_initParams.resize(m_optvars.size());
139  for (size_t i = 0; i < m_optvars.size(); ++i)
140  {
141  m_initParams[i] = m_optvars[i].get(*m_localPano);
142  DEBUG_DEBUG("get init var: " << m_optvars[i].m_name << ", " << m_optvars[i].m_img << ": " << m_initParams[i]);
143  }
144 }
145 
151  bool estimate(const std::vector<const ControlPoint *> & points, std::vector<double> & p) const
152  {
153  // reset to the initial parameters.
154  p.resize(m_initParams.size());
155  std::copy(m_initParams.begin(), m_initParams.end(), p.begin());
156 
157  return leastSquaresEstimate(points, p);
158  }
159 
160 
161 
162  bool leastSquaresEstimate(const std::vector<const ControlPoint *> & points, std::vector<double> & p) const
163  {
164  // copy points into panorama object
165  CPVector cpoints(points.size());
166  for (size_t i=0; i < points.size(); i++) {
167  cpoints[i] = *points[i];
168  }
169 
170  m_localPano->setCtrlPoints(cpoints);
171 
172  PanoramaData * pano = const_cast<PanoramaData *>(m_localPano);
173  // set parameters in pano object
174  for (size_t i = 0; i < m_optvars.size(); ++i)
175  {
176  m_optvars[i].set(*pano, p[i]);
177  DEBUG_DEBUG("Initial " << m_optvars[i].m_name << ": i1:" << pano->getImage(m_li1).getVar(m_optvars[i].m_name) << ", i2: " << pano->getImage(m_li2).getVar(m_optvars[i].m_name));
178  }
179 
181  // optimize parameters using panotools (or use a custom made optimizer here?)
182  UIntSet imgs;
183  imgs.insert(0);
184  imgs.insert(1);
185  //std::cout << "Optimizing without hfov:" << std::endl;
186  //pano->printPanoramaScript(std::cerr, m_localPano->getOptimizeVector(), pano->getOptions(), imgs, true );
187  PTools::optimize(*pano);
188  //std::cout << "result:" << std::endl;
189  //pano->printPanoramaScript(std::cerr, m_localPano->getOptimizeVector(), pano->getOptions(), imgs, true );
190 
191  if (!m_opt_second_pass.empty()) {
193  //std::cout << "Optimizing with hfov" << std::endl;
194  //pano->printPanoramaScript(std::cerr, m_localPano->getOptimizeVector(), pano->getOptions(), imgs, true );
195  PTools::optimize(*pano);
196  //std::cout << "result:" << std::endl;
197  //pano->printPanoramaScript(std::cerr, m_localPano->getOptimizeVector(), pano->getOptions(), imgs, true );
198  }
199 
200  // get optimized parameters
201  for (size_t i = 0; i < m_optvars.size(); ++i)
202  {
203  p[i] = m_optvars[i].get(*pano);
204  DEBUG_DEBUG("Optimized " << m_optvars[i].m_name << ": i1:" << pano->getImage(m_li1).getVar(m_optvars[i].m_name) << ", i2: " << pano->getImage(m_li2).getVar(m_optvars[i].m_name));
205  }
206  return true;
207  }
208 
209 
210  bool agree(std::vector<double> &p, const ControlPoint & cp) const
211  {
212  PanoramaData * pano = const_cast<PanoramaData *>(m_localPano);
213  // set parameters in pano object
214  for (size_t i = 0; i < m_optvars.size(); ++i)
215  {
216  m_optvars[i].set(*pano, p[i]);
217  }
218  // TODO: argh, this is slow, we should really construct this only once
219  // and reuse it for all calls...
220  PTools::Transform trafo_i1_to_pano;
222  PTools::Transform trafo_pano_to_i2;
224 
225  double x1,y1,x2,y2,xt,yt,x2t,y2t;
226  if (cp.image1Nr == m_li1) {
227  x1 = cp.x1;
228  y1 = cp.y1;
229  x2 = cp.x2;
230  y2 = cp.y2;
231  } else {
232  x1 = cp.x2;
233  y1 = cp.y2;
234  x2 = cp.x1;
235  y2 = cp.y1;
236  }
237  trafo_i1_to_pano.transformImgCoord(xt, yt, x1, y1);
238  trafo_pano_to_i2.transformImgCoord(x2t, y2t, xt, yt);
239  DEBUG_DEBUG("Trafo i1 (0 " << x1 << " " << y1 << ") -> ("<< xt <<" "<< yt<<") -> i2 (1 "<<x2t<<", "<<y2t<<"), real ("<<x2<<", "<<y2<<")")
240  // compute error in pixels...
241  x2t -= x2;
242  y2t -= y2;
243  double e = hypot(x2t,y2t);
244  DEBUG_DEBUG("Error ("<<x2t<<", "<<y2t<<"), " << e)
245  return e < m_maxError;
246  }
247 
249  {
250  delete m_localPano;
251  }
252 
253  int numForEstimate() const
254  {
255  return m_numForEstimate;
256  }
257 
258 public:
260  std::vector<double> m_initParams;
261  std::vector<OptVarSpec> m_optvars;
262 
263 private:
264  int m_li1, m_li2;
265  double m_maxError;
268  std::vector<std::set<std::string> > m_opt_first_pass;
269  std::vector<std::set<std::string> > m_opt_second_pass;
271 };
272 
273 
274 std::vector<int> RANSACOptimizer::findInliers(PanoramaData & pano, int i1, int i2, double maxError, Mode rmode)
275 {
276  bool optHFOV = false;
277  bool optB = false;
278  switch (rmode) {
279  case HOMOGRAPHY:
280  case RPYV:
281  optHFOV = true;
282  break;
283  case RPYVB:
284  optHFOV = true;
285  optB = true;
286  case AUTO:
287  case RPY:
288  break;
289  }
290 
291  DEBUG_DEBUG("Optimizing HFOV:" << optHFOV << " b:" << optB)
292  PTOptEstimator estimator(pano, i1, i2, maxError, optHFOV, optB);
293 
294  std::vector<double> parameters(estimator.m_initParams.size());
295  std::copy(estimator.m_initParams.begin(),estimator.m_initParams.end(), parameters.begin());
296  std::vector<int> inlier_idx;
297  DEBUG_DEBUG("Number of control points: " << estimator.m_xy_cps.size() << " Initial parameter[0]" << parameters[0]);
298  std::vector<const ControlPoint *> inliers = Ransac::compute(parameters, inlier_idx, estimator, estimator.m_xy_cps, 0.999, 0.3);
299  DEBUG_DEBUG("Number of inliers:" << inliers.size() << "optimized parameter[0]" << parameters[0]);
300 
301  // set parameters in pano object
302  for (size_t i = 0; i < estimator.m_optvars.size(); ++i)
303  {
304  // TODO: check when to use i1..
305  pano.updateVariable(i2, Variable(estimator.m_optvars[i].m_name, parameters[i]));
306  }
307 
308 
309  // TODO: remove bad control points from pano
310  return inlier_idx;
311 }
312 
313 
315 {
317  return true; // let's hope so.
318 }
319 
321 {
322 public:
323  explicit AutoOptimiseVisitor(PanoramaData* pano, const std::set<std::string>& optvec)
324  : m_opt(optvec), m_pano(pano)
325  {};
326  void Visit(const size_t vertex, const HuginBase::UIntSet& visitedNeighbors, const HuginBase::UIntSet& unvisitedNeighbors)
327  {
328  UIntSet imgs(visitedNeighbors);
329  imgs.insert(vertex);
330 
331  if (imgs.size() > 1)
332  {
333  // get pano with neighbouring images.
334  PanoramaData* localPano = m_pano->getNewSubset(imgs); // don't forget to delete
335 
336  // find number of current image in subset
337  unsigned currImg = 0;
338  unsigned cnt = 0;
339  for (UIntSet::const_iterator it = imgs.begin(); it != imgs.end(); ++it)
340  {
341  if (vertex == *it)
342  {
343  currImg = cnt;
344  }
345  cnt++;
346  }
347 
348  OptimizeVector optvec(imgs.size());
349  optvec[currImg] = m_opt;
350  localPano->setOptimizeVector(optvec);
351  PTools::optimize(*localPano);
352  m_pano->updateVariables(vertex, localPano->getImageVariables(currImg));
353  delete localPano;
354  };
355  };
356 private:
357  const std::set<std::string>& m_opt;
359 };
360 
361 void AutoOptimise::autoOptimise(PanoramaData& pano, bool optRoll)
362 {
363  // remove all connected images, keep only a single image for each connected stack
364  UIntSetVector imageGroups;
365  // don't forget to delete at end
366  PanoramaData* optPano = pano.getUnlinkedSubset(imageGroups);
367 
368  std::set<std::string> optvars;
369  if(optRoll)
370  {
371  optvars.insert("r");
372  };
373  optvars.insert("p");
374  optvars.insert("y");
375 
376  // start a breadth first traversal of the graph, and optimize
377  // the links found (every vertex just once.)
378  HuginGraph::ImageGraph graph(*optPano);
379  AutoOptimiseVisitor visitor(optPano, optvars);
380  graph.VisitAllImages(optPano->getOptions().optimizeReferenceImage, true, &visitor);
381 
382  // now translate to found positions to initial pano
383  for (size_t i = 0; i < optPano->getNrOfImages(); ++i)
384  {
385  pano.updateVariables(*imageGroups[i].begin(), optPano->getImageVariables(i));
386  };
387  delete optPano;
388 }
389 
390 
392 {
393  // use m-estimator with sigma 2
394  PanoramaOptions opts = optPano.getOptions();
395  double oldSigma = opts.huberSigma;
396  opts.huberSigma = 2;
397  optPano.setOptions(opts);
398 
399  // remove vertical and horizontal control points
400  CPVector cps = optPano.getCtrlPoints();
401  CPVector newCP;
402  for (CPVector::const_iterator it = cps.begin(); it != cps.end(); ++it) {
403  if (it->mode == ControlPoint::X_Y)
404  {
405  newCP.push_back(*it);
406  }
407  }
408  optPano.setCtrlPoints(newCP);
410 
411  // do global optimisation of position with all control points.
412  optPano.setCtrlPoints(cps);
414  optPano.setOptimizeVector(optvars);
415  PTools::optimize(optPano);
416 
417  //Find lenses.
418  StandardImageVariableGroups variable_groups(optPano);
419 
420  // allow parameter evaluation.
421  // this could be probably done in better way because this
422  // will optimize them also in case they are intentionally set to 0
423  double origLensPar[5];
424  origLensPar[0] = const_map_get(optPano.getImageVariables(0),"a").getValue();
425  origLensPar[1] = const_map_get(optPano.getImageVariables(0),"b").getValue();
426  origLensPar[2] = const_map_get(optPano.getImageVariables(0),"c").getValue();
427  origLensPar[3] = const_map_get(optPano.getImageVariables(0),"d").getValue();
428  origLensPar[4] = const_map_get(optPano.getImageVariables(0),"e").getValue();
429  bool alreadyCalibrated = false;
430  for (int i = 0; i < 5; i++) {
431  if (origLensPar[i] != 0) {
432  alreadyCalibrated = true;
433  break;
434  }
435  }
436  bool singleStack=false;
437  if(!alreadyCalibrated) {
438  UIntSet images;
439  fill_set(images, 0, optPano.getNrOfImages()-1);
440  std::vector<UIntSet> stacks = getHDRStacks(optPano, images, optPano.getOptions());
441  singleStack = (stacks.size() == 1);
442  };
443  // check if lens parameter values were loaded from ini file
444  // and should not be changed
445  // also don't optimize lens parameters for single stack projects
446  if (!alreadyCalibrated && !singleStack) {
447  //---------------------------------------------------------------
448  // Now with lens distortion
449 
450  // force inherit for all d/e values
451  for (unsigned i=0; i< variable_groups.getLenses().getNumberOfParts(); i++)
452  {
453  variable_groups.getLenses().linkVariablePart(ImageVariableGroup::IVE_RadialDistortion, i);
454  variable_groups.getLenses().linkVariablePart(ImageVariableGroup::IVE_RadialDistortionCenterShift, i);
455  }
456 
457  int optmode = OPT_POS;
458  double origHFOV = const_map_get(optPano.getImageVariables(0),"v").getValue();
459 
460  // determine which parameters to optimize
461  double rmin, rmax, rmean, rvar, rq10, rq90;
462  CalculateCPStatisticsRadial::calcCtrlPntsRadiStats(optPano, rmin, rmax, rmean, rvar, rq10, rq90);
463 
464  DEBUG_DEBUG("Ctrl Point radi statistics: min:" << rmin << " max:" << rmax << " mean:" << rmean << " var:" << rvar << " q10:" << rq10 << " q90:" << rq90);
465 
466  if (origHFOV > 60) {
467  // only optimize principal point if the hfov is high enough for sufficient perspective effects
468  optmode |= OPT_DE;
469  }
470 
471  // heuristics for distortion and fov optimisation
472  if ( (rq90 - rq10) >= 1.2) {
473  // very well distributed control points
474  // TODO: other criterion when to optimize HFOV, too
475  optmode |= OPT_AC | OPT_B;
476  } else if ( (rq90 - rq10) > 1.0) {
477  optmode |= OPT_AC | OPT_B;
478  } else {
479  optmode |= OPT_B;
480  }
481 
482  // check if this is a 360 deg pano.
483  CenterHorizontally(optPano).run();
484  //FDiff2D fov = CalculateFOV(optPano).run<CalculateFOV>().getResultFOV();
486 
487  if (fov.x >= 150) {
488  // optimize HFOV for 150 deg panos
489  optmode |= OPT_HFOV;
490  }
491 
492  DEBUG_DEBUG("second optimization: " << optmode);
493 
494  // save old variables, might be needed if optimization went wrong
495  VariableMapVector oldVars = optPano.getVariables();
496  DEBUG_DEBUG("oldVars[0].b: " << const_map_get(oldVars[0],"b").getValue());
497  optvars = createOptVars(optPano, optmode, optPano.getOptions().optimizeReferenceImage);
498  optPano.setOptimizeVector(optvars);
499  // global optimisation.
500  DEBUG_DEBUG("before opt 1: newVars[0].b: " << const_map_get(optPano.getVariables()[0],"b").getValue());
501  PTools::optimize(optPano);
502  // --------------------------------------------------------------
503  // do some plausibility checks and reoptimize with less variables
504  // if something smells fishy
505  bool smallHFOV = false;
506  bool highDist = false;
507  bool highShift = false;
508  const VariableMapVector & vars = optPano.getVariables();
509  DEBUG_DEBUG("after opt 1: newVars[0].b: " << const_map_get(vars[0],"b").getValue());
510  DEBUG_DEBUG("after opt 1: oldVars[0].b: " << const_map_get(oldVars[0],"b").getValue());
511  for (VariableMapVector::const_iterator it = vars.begin() ; it != vars.end(); ++it)
512  {
513  if (const_map_get(*it,"v").getValue() < 1.0) smallHFOV = true;
514  if (fabs(const_map_get(*it,"a").getValue()) > 0.2) highDist = true;
515  if (fabs(const_map_get(*it,"b").getValue()) > 0.2) highDist = true;
516  if (fabs(const_map_get(*it,"c").getValue()) > 0.2) highDist = true;
517  if (fabs(const_map_get(*it,"d").getValue()) > 1000) highShift = true;
518  if (fabs(const_map_get(*it,"e").getValue()) > 1000) highShift = true;
519  }
520 
521  if (smallHFOV || highDist || highShift) {
522  DEBUG_DEBUG("Optimization with strange result. status: HFOV: " << smallHFOV << " dist:" << highDist << " shift:" << highShift);
523  // something seems to be wrong
524  if (smallHFOV) {
525  // do not optimize HFOV
526  optmode &= ~OPT_HFOV;
527  }
528  if (highDist) {
529  optmode &= ~OPT_AC;
530  }
531  if (highShift) {
532  optmode &= ~OPT_DE;
533  }
534 
535  // revert and redo optimisation
536  DEBUG_DEBUG("oldVars[0].b: " << const_map_get(oldVars[0],"b").getValue());
537  optPano.updateVariables(oldVars);
538  DEBUG_DEBUG("before opt 2: newVars[0].b: " << const_map_get(optPano.getVariables()[0],"b").getValue());
539  optvars = createOptVars(optPano, optmode, optPano.getOptions().optimizeReferenceImage);
540  optPano.setOptimizeVector(optvars);
541  DEBUG_DEBUG("recover optimisation: " << optmode);
542  // global optimisation.
543  PTools::optimize(optPano);
544 
545  // check again, maybe b shouldn't be optimized either
546  bool highDist = false;
547  const VariableMapVector & vars = optPano.getVariables();
548  DEBUG_DEBUG("after opt 2: newVars[0].b: " << const_map_get(vars[0],"b").getValue());
549  DEBUG_DEBUG("after opt 2: oldVars[0].b: " << const_map_get(oldVars[0],"b").getValue());
550  for (VariableMapVector::const_iterator it = vars.begin() ; it != vars.end(); ++it)
551  {
552  if (fabs(const_map_get(*it,"b").getValue()) > 0.2) highDist = true;
553  }
554  if (highDist) {
555  optmode &= ~OPT_B;
556  DEBUG_DEBUG("recover optimisation (2): " << optmode);
557  // revert and redo optimisation
558  optPano.updateVariables(oldVars);
559  DEBUG_DEBUG("before opt 3: newVars[0].b: " << const_map_get(optPano.getVariables()[0],"b").getValue());
560  optvars = createOptVars(optPano, optmode, optPano.getOptions().optimizeReferenceImage);
561  optPano.setOptimizeVector(optvars);
562  // global optimisation.
563  PTools::optimize(optPano);
564  const VariableMapVector & vars = optPano.getVariables();
565  DEBUG_DEBUG("after opt 3: newVars[0].b: " << const_map_get(vars[0],"b").getValue());
566  DEBUG_DEBUG("after opt 3: oldVars[0].b: " << const_map_get(oldVars[0],"b").getValue());
567 
568  }
569  }
570  }
571  opts.huberSigma = oldSigma;
572  optPano.setOptions(opts);
573 }
574 
575 OptimizeVector SmartOptimizerStub::createOptVars(const PanoramaData& optPano, int mode, unsigned anchorImg)
576 {
577  OptimizeVector optvars;
578  const SrcPanoImage & anchorImage = optPano.getImage(anchorImg);
579  for (unsigned i=0; i < optPano.getNrOfImages(); i++) {
580  std::set<std::string> imgopt;
581  // do not optimize anchor image's stack for position.
582  const SrcPanoImage & iImage = optPano.getImage(i);
583  if (!iImage.RollisLinkedWith(anchorImage) &&
584  !iImage.PitchisLinkedWith(anchorImage) &&
585  !iImage.YawisLinkedWith(anchorImage))
586  {
587  if (mode & OPT_POS) {
588  imgopt.insert("r");
589  imgopt.insert("p");
590  imgopt.insert("y");
591  }
592  }
593  //we need to optimize roll and pitch to level the pano
594  //possible after introduction of line finder
595  if((i==anchorImg) && (mode & OPT_POS))
596  {
597  imgopt.insert("r");
598  imgopt.insert("p");
599  };
600  // do not optimise anchor image for exposure.
601  if (i!=anchorImg)
602  {
603  if (mode & OPT_EXP) {
604  imgopt.insert("Eev");
605  }
606  if (mode & OPT_WB) {
607  imgopt.insert("Er");
608  imgopt.insert("Eb");
609  }
610  }
611  if (mode & OPT_HFOV) {
612  imgopt.insert("v");
613  }
614  if (mode & OPT_B)
615  imgopt.insert("b");
616  if (mode & OPT_AC) {
617  imgopt.insert("a");
618  imgopt.insert("c");
619  }
620  if (mode & OPT_DE) {
621  imgopt.insert("d");
622  imgopt.insert("e");
623  }
624  if (mode & OPT_GT) {
625  imgopt.insert("g");
626  imgopt.insert("t");
627  }
628  if (mode & OPT_VIG) {
629  imgopt.insert("Vb");
630  imgopt.insert("Vc");
631  imgopt.insert("Vd");
632  }
633  if (mode & OPT_VIGCENTRE) {
634  imgopt.insert("Vx");
635  imgopt.insert("Vy");
636  }
637  if ((mode & OPT_RESP) && iImage.getResponseType() == HuginBase::SrcPanoImage::RESPONSE_EMOR) {
638  // ignore Ra..Re if reponse is linear
639  imgopt.insert("Ra");
640  imgopt.insert("Rb");
641  imgopt.insert("Rc");
642  imgopt.insert("Rd");
643  imgopt.insert("Re");
644  }
645  optvars.push_back(imgopt);
646  }
647 
648  return optvars;
649 }
650 
651 } //namespace
virtual bool runAlgorithm()
calls PTools::optimize()
Definition: PTOptimizer.cpp:51
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
virtual void setOptimizeVector(const OptimizeVector &optvec)=0
set optimize setting
std::vector< UIntSet > UIntSetVector
Definition: PanoramaData.h:56
Generic implementation of the RanSaC algorithm.
virtual void setCtrlPoints(const CPVector &points)=0
set all control points (Ippei: Is this supposed to be &#39;add&#39; method?)
PanoramaData * m_localPano
virtual const VariableMap getImageVariables(unsigned int imgNr) const =0
get variables of an image
static void smartOptimize(PanoramaData &pano)
static std::vector< const T * > compute(S &parameters, std::vector< int > &inliers, const Estimator &paramEstimator, const std::vector< T > &data, double desiredProbabilityForNoOutliers, double maximalOutlierPercentage)
Estimate the model parameters using the RanSac framework.
Definition: ransac.h:175
bool leastSquaresEstimate(const std::vector< const ControlPoint * > &points, std::vector< double > &p) const
virtual void updateVariable(unsigned int imgNr, const Variable &var)=0
update a single variable
static hugin_utils::FDiff2D calcFOV(const PanoramaData &panorama)
Somewhere to specify what variables belong to what.
static std::vector< int > findInliers(PanoramaData &pano, int i1, int i2, double maxError, Mode mode=RPY)
std::vector< double > m_initParams
a variable has a value and a name.
void Visit(const size_t vertex, const HuginBase::UIntSet &visitedNeighbors, const HuginBase::UIntSet &unvisitedNeighbors)
wraps around PTOptimizer
virtual void run()
runs the algorithm.
Estimator for RANSAC based adjustment of pairwise parameters.
Definition: PTOptimizer.cpp:79
represents a control point
Definition: ControlPoint.h:38
const Map::mapped_type & const_map_get(const Map &m, const typename Map::key_type &key)
Definition: stl_utils.h:110
void linkVariablePart(ImageVariableEnum variable, unsigned int partNr)
link one of the variables across a given part
static void calcCtrlPntsRadiStats(const PanoramaData &pano, double &min, double &max, double &mean, double &var, double &q10, double &q90, const int &imgNr=-1)
std::set< unsigned int > UIntSet
Definition: PanoramaData.h:51
virtual PanoramaData * getUnlinkedSubset(UIntSetVector &imageGroups) const =0
std::vector< VariableMap > VariableMapVector
empirical model of response
Definition: SrcPanoImage.h:100
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
void createInvTransform(const vigra::Diff2D &srcSize, VariableMap srcVars, Lens::LensProjectionFormat srcProj, const vigra::Diff2D &destSize, PanoramaOptions::ProjectionFormat destProj, const std::vector< double > &destProjParam, double destHFOV, const vigra::Diff2D &origSrcSize)
create image-&gt;pano transformation
OptVarSpec(int img, std::string name)
Definition: PTOptimizer.cpp:61
virtual bool runAlgorithm()
calls PTools::optimize()
virtual void setOptions(const PanoramaOptions &opt)=0
set new output settings This is not used directly for optimizing/stiching, but it can be feed into ru...
std::vector< int > o_inliers
Definition: PTOptimizer.h:96
virtual const PanoramaOptions & getOptions() const =0
returns the options for this panorama
bool agree(std::vector< double > &p, const ControlPoint &cp) const
ImageVariableGroup & getLenses()
Get the ImageVariableGroup representing the group of lens variables.
Model for a panorama.
Definition: PanoramaData.h:81
void set(PanoramaData &pano, double x) const
Definition: PTOptimizer.cpp:70
virtual const SrcPanoImage & getImage(std::size_t nr) const =0
get a panorama image, counting starts with 0
double getVar(const std::string &name) const
!! from PTOptimise.h 1951
virtual const CPVector & getCtrlPoints() const =0
get all control point of this Panorama
const std::set< std::string > & m_opt
bool transformImgCoord(double &x_dest, double &y_dest, double x_src, double y_src) const
like transform, but return image coordinates, not cartesian coordinates
std::vector< std::set< std::string > > m_opt_first_pass
AutoOptimiseVisitor(PanoramaData *pano, const std::set< std::string > &optvec)
Holds transformations for Image -&gt; Pano and the other way.
#define DEBUG_DEBUG(msg)
Definition: utils.h:68
unsigned int optimize(PanoramaData &pano, const char *userScript)
optimize the images imgs, for variables optvec, using vars as start.
virtual VariableMapVector getVariables() const =0
get variables of this panorama
std::vector< ControlPoint > CPVector
Definition: ControlPoint.h:99
std::vector< std::set< std::string > > OptimizeVector
void fill_set(_Container &c, typename _Container::key_type begin, typename _Container::key_type end)
Definition: stl_utils.h:81
std::vector< std::set< std::string > > m_opt_second_pass
virtual std::size_t getNrOfImages() const =0
number of images.
std::size_t getNumberOfParts() const
get the number of parts.
All variables of a source image.
Definition: SrcPanoImage.h:194
Panorama image options.
PTOptEstimator(PanoramaData &pano, int i1, int i2, double maxError, bool optHFOV, bool optB)
Definition: PTOptimizer.cpp:84
bool estimate(const std::vector< const ControlPoint * > &points, std::vector< double > &p) const
Perform exact estimate.
virtual void updateVariables(const VariableMapVector &vars)=0
Set the variables.
static OptimizeVector createOptVars(const PanoramaData &optPano, int mode, unsigned anchorImg=0)
helper function for optvar creation
void createTransform(const vigra::Diff2D &srcSize, VariableMap srcVars, Lens::LensProjectionFormat srcProj, const vigra::Diff2D &destSize, PanoramaOptions::ProjectionFormat destProj, const std::vector< double > &destProjParam, double destHFOV, const vigra::Diff2D &origSrcSize)
initialize pano-&gt;image transformation
abstract base functor for breadth first search in ImageGraph
Definition: ImageGraph.h:35
std::vector< OptVarSpec > m_optvars
static void autoOptimise(PanoramaData &pano, bool optRoll=true)
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