Hugin trunk 0.1
Loading...
Searching...
No Matches
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
49namespace HuginBase {
50
52{
54 return true; // let's hope so.
55}
56
57// small helper class
59{
60public:
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
82public:
83
84 PTOptEstimator(PanoramaData & pano, int i1, int i2, double maxError,
85 bool optHFOV, bool optB)
86 {
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 {
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
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...
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
258public:
260 std::vector<double> m_initParams;
261 std::vector<OptVarSpec> m_optvars;
262
263private:
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
274std::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{
322public:
323 explicit AutoOptimiseVisitor(PanoramaData* pano, const std::set<std::string>& optvec)
324 : m_opt(optvec), m_pano(pano)
325 {};
327 {
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);
352 m_pano->updateVariables(vertex, localPano->getImageVariables(currImg));
353 delete localPano;
354 };
355 };
356private:
357 const std::set<std::string>& m_opt;
359};
360
362{
363 // remove all connected images, keep only a single image for each connected stack
365 // don't forget to delete at end
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.)
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();
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);
413 OptimizeVector optvars = createOptVars(optPano, OPT_POS, optPano.getOptions().optimizeReferenceImage);
414 optPano.setOptimizeVector(optvars);
416
417 //Find lenses.
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
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;
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.
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());
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
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.
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.
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
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
declaration of functions to handle stacks and layers
!! from PTOptimise.h 1951
wraps around PTOptimizer
Somewhere to specify what variables belong to what.
const std::set< std::string > & m_opt
AutoOptimiseVisitor(PanoramaData *pano, const std::set< std::string > &optvec)
void Visit(const size_t vertex, const HuginBase::UIntSet &visitedNeighbors, const HuginBase::UIntSet &unvisitedNeighbors)
static void autoOptimise(PanoramaData &pano, bool optRoll=true)
@ RESPONSE_EMOR
empirical model of response
static void calcCtrlPntsRadiStats(const PanoramaData &pano, double &min, double &max, double &mean, double &var, double &q10, double &q90, const int &imgNr=-1)
static hugin_utils::FDiff2D calcFOV(const PanoramaData &panorama)
represents a control point
OptVarSpec(int img, std::string name)
double get(PanoramaData &pano) const
void set(PanoramaData &pano, double x) const
Estimator for RANSAC based adjustment of pairwise parameters.
bool leastSquaresEstimate(const std::vector< const ControlPoint * > &points, std::vector< double > &p) const
bool agree(std::vector< double > &p, const ControlPoint &cp) const
std::vector< OptVarSpec > m_optvars
std::vector< std::set< std::string > > m_opt_second_pass
bool estimate(const std::vector< const ControlPoint * > &points, std::vector< double > &p) const
Perform exact estimate.
std::vector< double > m_initParams
PTOptEstimator(PanoramaData &pano, int i1, int i2, double maxError, bool optHFOV, bool optB)
std::vector< std::set< std::string > > m_opt_first_pass
virtual bool runAlgorithm()
calls PTools::optimize()
Holds transformations for Image -> Pano and the other way.
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->image transformation
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->pano transformation
virtual void run()
runs the algorithm.
Model for a panorama.
virtual const PanoramaOptions & getOptions() const =0
returns the options for this panorama
virtual void setOptimizeVector(const OptimizeVector &optvec)=0
set optimize setting
virtual PanoramaData * getNewSubset(const UIntSet &imgs) const =0
virtual void updateVariable(unsigned int imgNr, const Variable &var)=0
update a single variable
virtual const CPVector & getCtrlPoints() const =0
get all control point of this Panorama
virtual const SrcPanoImage & getImage(std::size_t nr) const =0
get a panorama image, counting starts with 0
virtual void updateVariables(const VariableMapVector &vars)=0
Set the variables.
virtual PanoramaData * getUnlinkedSubset(UIntSetVector &imageGroups) const =0
virtual void setCtrlPoints(const CPVector &points)=0
set all control points (Ippei: Is this supposed to be 'add' method?)
Panorama image options.
virtual bool runAlgorithm()
calls PTools::optimize()
static std::vector< int > findInliers(PanoramaData &pano, int i1, int i2, double maxError, Mode mode=RPY)
std::vector< int > o_inliers
Definition PTOptimizer.h:96
static void smartOptimize(PanoramaData &pano)
static OptimizeVector createOptVars(const PanoramaData &optPano, int mode, unsigned anchorImg=0)
helper function for optvar creation
All variables of a source image.
double getVar(const std::string &name) const
a variable has a value and a name.
abstract base functor for breadth first search in ImageGraph
Definition ImageGraph.h:36
class to work with images graphs created from a HuginBase::Panorama class it creates a graph based on...
Definition ImageGraph.h:45
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
#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.
mainly consists of wrapper around the pano tools library, to assist in ressource management and to pr...
Definition wxcms.cpp:39
std::vector< VariableMap > VariableMapVector
std::vector< ControlPoint > CPVector
std::vector< std::set< std::string > > OptimizeVector
std::vector< UIntSet > UIntSetVector
std::set< unsigned int > UIntSet
std::vector< UIntSet > getHDRStacks(const PanoramaData &pano, UIntSet allImgs, PanoramaOptions opts)
returns vector of set of output stacks
Generic implementation of the RanSaC algorithm.
void fill_set(_Container &c, typename _Container::key_type begin, typename _Container::key_type end)
Definition stl_utils.h:81
const Map::mapped_type & const_map_get(const Map &m, const typename Map::key_type &key)
Definition stl_utils.h:110
std::vector< deghosting::BImagePtr > threshold(const std::vector< deghosting::FImagePtr > &inputImages, const double threshold, const uint16_t flags)
Threshold function used for creating alpha masks for images.
Definition threshold.h:41