27 #include <foreign/levmar/levmar.h> 
   32 #define DEBUG_LOG_VIG 1 
   42         x = sqrt(sigma* (2*x - sigma));
 
   50                                            const std::vector<vigra_ext::PointPairRGB> & 
data,
 
   51                                            double mEstimatorSigma, 
bool symmetric,
 
   53   : m_pano(pano), m_data(data), huberSigma(mEstimatorSigma), symmetricError(symmetric),
 
   54     m_maxIter(maxIter), m_progress(progress)
 
   62     std::vector<std::set<std::string> > usedVars(pano.
getNrOfImages());
 
   65     for (
unsigned i=0; i < optvars.size(); i++) 
 
   67         const std::set<std::string> vars = optvars[i];
 
   69         for (std::set<std::string>::const_iterator it = vars.begin();
 
   70              it != vars.end(); ++it)
 
   78             usedVars[i].insert(var.
type);
 
   80 #define CheckLinked(name)\ 
   81             if(img_i.name##isLinked())\ 
   83                 for(unsigned j=i+1;j<pano.getNrOfImages();j++)\ 
   84                     if(img_i.name##isLinkedWith(pano.getImage(j)))\ 
   87                         usedVars[j].insert(var.type);\ 
  111             if(var.
type==
"Vx" || var.
type==
"Vy")
 
  123     for (
size_t i=0; i < m_vars.size(); i++)
 
  125         assert(!m_vars[i].imgs.empty());
 
  127         unsigned j = *(m_vars[i].imgs.begin());
 
  129         x[i] = m_imgs[j].getVar(m_vars[i].type);
 
  137     for (
size_t i=0; i < m_vars.size(); i++)
 
  140         assert(!m_vars[i].imgs.empty());
 
  142         for (std::set<unsigned>::const_iterator it = m_vars[i].imgs.begin();
 
  143              it != m_vars[i].imgs.end(); ++it)
 
  145             m_imgs[*it].setVar(m_vars[i].type, x[i]);
 
  165     std::ostringstream oss;
 
  166     oss << 
"vig_log_" << iter;
 
  168     std::ofstream 
log(oss.str().c_str());
 
  169     log << 
"VIGparams = [";
 
  170     for (
int i = 0; i < m; i++) {
 
  173     log << 
" ]; " << std::endl;
 
  175     std::ofstream script(
"vig_test.pto");
 
  181     size_t nImg = dat->
m_imgs.size();
 
  182     std::vector<RespFunc> resp(nImg);
 
  183     std::vector<InvRespFunc> invResp(nImg);
 
  184     for (
size_t i=0; i < nImg; i++) {
 
  185         resp[i] = RespFunc(dat->
m_imgs[i]);
 
  186         invResp[i] = InvRespFunc(dat->
m_imgs[i]);
 
  191             int lutsize = resp[i].m_lutR.size();
 
  192             for (
int j=0; j < lutsize-1; j++)
 
  194                 double d = resp[i].m_lutR[j] - resp[i].m_lutR[j+1];
 
  196                     monErr += d*d*lutsize;
 
  202                 resp[i].enforceMonotonicity();
 
  203                 invResp[i].enforceMonotonicity();
 
  211     log << 
"VIGval = [ ";
 
  214     for (std::vector<vigra_ext::PointPairRGB>::const_iterator it = dat->
m_data.begin();
 
  215          it != dat->
m_data.end(); ++it)
 
  217         vigra::RGBValue<double> l2 = invResp[it->imgNr2](it->i2, it->p2);
 
  218         vigra::RGBValue<double> i2ini1 = resp[it->imgNr1](l2, it->p1);
 
  219         vigra::RGBValue<double> error = it->i1 - i2ini1;
 
  224         vigra::RGBValue<double> l1 = invResp[it->imgNr1](it->i1, it->p1);
 
  225         vigra::RGBValue<double> i1ini2 = resp[it->imgNr2](l1, it->p2);
 
  226         vigra::RGBValue<double> error2 = it->i2 - i1ini2;
 
  229         for (
int i=0; i < 3; i++) {
 
  230             sqerror += error[i]*error[i];
 
  231             sqerror += error2[i]*error2[i];
 
  237             for (
int i=0; i < 3; i++) {
 
  251         log << it->i1.green()  << 
" "<< l1.green()  << 
" " << i1ini2.green() << 
"   "  
  252              << it->i2.green()  << 
" "<< l2.green()  << 
" " << i2ini1.green() << 
";  " << std::endl;
 
  257     log << std::endl << 
"VIGerr = [";
 
  258     for (
int i = 0; i < n; i++) {
 
  259         log << x[i] << std::endl;
 
  261     log << 
" ]; " << std::endl;
 
  273     double error = sqrt(sqerror/n)*255;
 
  274     snprintf(tmp,199, 
"Iteration: %d, error: %f", iter, error);
 
  279                                                const std::vector<vigra_ext::PointPairRGB> & correspondences,
 
  280                                                const float imageStepSize,
 
  287     unsigned int optCount=0;
 
  288     for (OptimizeVector::const_iterator it=vars.begin(); it != vars.end(); ++it)
 
  290         std::set<std::string> cvars;
 
  291         for (std::set<std::string>::const_iterator itv = (*it).begin();
 
  292              itv != (*it).end(); ++itv)
 
  294             if ((*itv)[0] == 
'E' || (*itv)[0] == 
'R' || (*itv)[0] == 
'V') {
 
  298         photometricVars.push_back(cvars);
 
  299         optCount+=cvars.size();
 
  308     OptimData data(pano, photometricVars, correspondences, 5 * imageStepSize, 
false, nMaxIter, progress);
 
  310     double info[LM_INFO_SZ];
 
  314     vigra::ArrayVector<double> p(m, 0.0);
 
  318     vigra::ArrayVector<double> x(n, 0.0);
 
  322     printf(
"Parameters before optimisation: ");
 
  323     for(
int i=0; i<m; ++i)
 
  324         printf(
"%.7g ", p[i]);
 
  331     optimOpts[0] = LM_INIT_MU;  
 
  333     optimOpts[1] = LM_STOP_THRESH;   
 
  334     optimOpts[2] = LM_STOP_THRESH;   
 
  335     optimOpts[3] = 
std::pow(imageStepSize*0.1f, 2);   
 
  337     optimOpts[4] = LM_DIFF_DELTA;
 
  339     dlevmar_dif(&
photometricError, &
photometricVis, &(p[0]), &(x[0]), m, n, nMaxIter, optimOpts, info, NULL,NULL, &data);  
 
  342     data.
FromX(p.begin());
 
  347     for (
int i=0; i<n; i++) {
 
  350     error = sqrt(error/n);
 
  353     printf(
"Levenberg-Marquardt returned in %g iter, reason %g\nSolution: ", info[5], info[6]);
 
  354     for(
int i=0; i<m; ++i)
 
  355         printf(
"%.7g ", p[i]);
 
  356     printf(
"\n\nMinimization info:\n");
 
  357     for(
int i=0; i<LM_INFO_SZ; ++i)
 
  358         printf(
"%g ", info[i]);
 
  371     srcImage.setRadialVigCorrCoeff(vigCorr);
 
  372     srcImage.
setSize(vigra::Size2D(500, 500));
 
  374     for (
size_t x = 0; x < 250; x += 10)
 
  377         if (vigFactor < 0.2 || vigFactor > 1.1)
 
  389         if(pano.
getImage(i).getWhiteBalanceBlue()>3)
 
  393         if(pano.
getImage(i).getWhiteBalanceRed()>3)
 
  402                                                           const std::vector<vigra_ext::PointPairRGB> & correspondences,
 
  403                                                           const float imageStepSize, 
 
  411     const bool singleStack = (stacks.size() == 1);
 
  414     if (mode == OPT_PHOTOMETRIC_LDR || mode == OPT_PHOTOMETRIC_LDR_WB)
 
  420                             correspondences, imageStepSize, progress, error);
 
  431                             correspondences, imageStepSize, progress, error);
 
  443     if (mode == OPT_PHOTOMETRIC_LDR_WB || mode == OPT_PHOTOMETRIC_HDR_WB)
 
  450                         correspondences, imageStepSize, progress, error);
 
  455     if(hasHighVignetting)
 
  463     if(hasHighVignetting || hasHighWB)
 
  471                                 correspondences, imageStepSize, progress, error);
 
static int photometricVis(double *p, double *x, int m, int n, int iter, double sqerror, void *data)
 
std::vector< UIntSet > getHDRStacks(const PanoramaData &pano, UIntSet allImgs, PanoramaOptions opts)
returns vector of set of output stacks 
 
AppBase::ProgressDisplay * m_progress
 
declaration of functions to handle stacks and layers 
 
static void photometricError(double *p, double *x, int m, int n, void *data)
 
std::vector< SrcPanoImage > m_imgs
 
const PanoramaData & m_pano
 
void FromX(double *x)
copy new values from x to into this->m_imgs 
 
virtual void printPanoramaScript(std::ostream &o, const OptimizeVector &optvars, const PanoramaOptions &options, const UIntSet &imgs, bool forPTOptimizer, const std::string &stripPrefix="") const =0
create an optimizer script 
 
virtual void setSrcImage(unsigned int nr, const SrcPanoImage &img)=0
set input image parameters TODO: Propagate changes to linked images. 
 
std::vector< float > EMoRParams
 
virtual void cancelAlgorithm()
Call this when the algorithm is cancelled. 
 
bool CheckStrangeWB(PanoramaData &pano)
 
hugin_utils::FDiff2D RadialVigCorrCenterShift
 
std::vector< double > RadialVigCorrCoeff
 
bool IsHighVignetting(std::vector< double > vigCorr)
 
bool set_contains(const _Container &c, const typename _Container::key_type &key)
 
PhotometricOptimizeMode
local optimize definition. 
 
bool updateDisplay()
updates the display, return true, if update was successful, false if cancel was pressed ...
 
vigra::pair< typename ROIImage< Image, Mask >::image_const_traverser, typename ROIImage< Image, Mask >::ImageConstAccessor > srcImage(const ROIImage< Image, Mask > &img)
 
std::set< unsigned > imgs
 
double weightHuber(double x, double sigma)
expects the abs(error) values 
 
unsigned int colorReferenceImage
 
#define CheckLinked(name)
 
void ToX(double *x)
copy optimisation variables into x 
 
virtual bool wasCancelled() const 
 
std::set< unsigned int > UIntSet
 
virtual bool runAlgorithm()
implementation of the algorithm. 
 
std::vector< VariableMap > VariableMapVector
 
empirical model of response 
 
virtual AppBase::ProgressDisplay * getProgressDisplay() const 
 
virtual UIntSet getActiveImages() const =0
get active images 
 
float pow(float a, double b)
 
static void smartOptimizePhotometric(PanoramaData &pano, PhotometricOptimizeMode mode, const std::vector< vigra_ext::PointPairRGB > &correspondences, const float imageStepSize, AppBase::ProgressDisplay *progress, double &error)
use various heuristics to decide what to optimize. 
 
virtual const PanoramaOptions & getOptions() const =0
returns the options for this panorama 
 
virtual const SrcPanoImage & getImage(std::size_t nr) const =0
get a panorama image, counting starts with 0 
 
static void optimizePhotometric(PanoramaData &pano, const OptimizeVector &vars, const PointPairs &correspondences, const float imageStepSize, AppBase::ProgressDisplay *progress, double &error)
 
const PointPairs & o_correspondences
 
vigra::RGBValue< T, RIDX, GIDX, BIDX > log(vigra::RGBValue< T, RIDX, GIDX, BIDX > const &v)
component-wise logarithm 
 
const float o_imageStepSize
 
virtual bool runAlgorithm()
implementation of the algorithm. 
 
options wxIntPtr wxIntPtr sortData std::vector< PanoInfo > * data
 
PanoramaData & o_panorama
 
virtual VariableMapVector getVariables() const =0
get variables of this panorama 
 
void setSize(vigra::Size2D val)
Set the image size in pixels. 
 
static void info(const char *fmt,...)
 
std::vector< std::set< std::string > > OptimizeVector
 
void fill_set(_Container &c, typename _Container::key_type begin, typename _Container::key_type end)
 
std::vector< vigra_ext::PointPairRGB > m_data
 
virtual SrcPanoImage getSrcImage(unsigned imgNr) const =0
get a complete description of a source image 
 
const OptimizeVector & o_vars
 
virtual std::size_t getNrOfImages() const =0
number of images. 
 
All variables of a source image. 
 
virtual void updateVariables(const VariableMapVector &vars)=0
Set the variables. 
 
std::vector< VarMapping > m_vars
 
OptimData(const PanoramaData &pano, const OptimizeVector &optvars, const std::vector< vigra_ext::PointPairRGB > &data, double mEstimatorSigma, bool symmetric, int maxIter, AppBase::ProgressDisplay *progress)