void PhotometricOptimizer::optimizePhotometric(PanoramaData & pano, const OptimizeVector & vars, const std::vector<vigra_ext::PointPairRGB> & correspondences, AppBase::ProgressReporter & progress, double & error) { OptimizeVector photometricVars; // keep only the photometric variables unsigned int optCount=0; for (OptimizeVector::const_iterator it=vars.begin(); it != vars.end(); ++it) { std::set<std::string> cvars; for (std::set<std::string>::const_iterator itv = (*it).begin(); itv != (*it).end(); ++itv) { if ((*itv)[0] == 'E' || (*itv)[0] == 'R' || (*itv)[0] == 'V') { cvars.insert(*itv); } } photometricVars.push_back(cvars); optCount+=cvars.size(); } //if no variables to optimize return if(optCount==0) { return; }; int nMaxIter = 250; OptimData data(pano, photometricVars, correspondences, 5/255.0, false, nMaxIter, progress); int ret; //double opts[LM_OPTS_SZ]; double info[LM_INFO_SZ]; // parameters int m=data.m_vars.size(); vigra::ArrayVector<double> p(m, 0.0); // vector for errors int n=2*3*correspondences.size()+pano.getNrOfImages(); vigra::ArrayVector<double> x(n, 0.0); data.ToX(p.begin()); #ifdef DEBUG printf("Parameters before optimisation: "); for(int i=0; i<m; ++i) printf("%.7g ", p[i]); printf("\n"); #endif // covariance matrix at solution vigra::DImage cov(m,m); // TODO: setup optimisation options with some good defaults. double optimOpts[5]; optimOpts[0] = 1E-03; // init mu // stop thresholds optimOpts[1] = 1e-5; // ||J^T e||_inf optimOpts[2] = 1e-5; // ||Dp||_2 optimOpts[3] = 1e-1; // ||e||_2 // difference mode optimOpts[4] = LM_DIFF_DELTA; ret=dlevmar_dif(&photometricError, &photometricVis, &(p[0]), &(x[0]), m, n, nMaxIter, optimOpts, info, NULL, &(cov(0,0)), &data); // no jacobian // copy to source images (data.m_imgs) data.FromX(p.begin()); // calculate error at solution data.huberSigma = 0; photometricError(&(p[0]), &(x[0]), m, n, &data); error = 0; for (int i=0; i<n; i++) { error += x[i]*x[i]; } error = sqrt(error/n); #ifdef DEBUG printf("Levenberg-Marquardt returned %d in %g iter, reason %g\nSolution: ", ret, info[5], info[6]); for(int i=0; i<m; ++i) printf("%.7g ", p[i]); printf("\n\nMinimization info:\n"); for(int i=0; i<LM_INFO_SZ; ++i) printf("%g ", info[i]); printf("\n"); #endif // copy settings to panorama for (unsigned i=0; i<pano.getNrOfImages(); i++) { pano.setSrcImage(i, data.m_imgs[i]); } }