CleanCP.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00014  /*  This is free software; you can redistribute it and/or
00015  *  modify it under the terms of the GNU General Public
00016  *  License as published by the Free Software Foundation; either
00017  *  version 2 of the License, or (at your option) any later version.
00018  *
00019  *  This software is distributed in the hope that it will be useful,
00020  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00021  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00022  *  Lesser General Public License for more details.
00023  *
00024  *  You should have received a copy of the GNU General Public
00025  *  License along with this software; if not, write to the Free Software
00026  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00027  *
00028  */
00029 
00030 #include "CleanCP.h"
00031 #include <algorithms/optimizer/PTOptimizer.h>
00032 #include "algorithms/basic/CalculateCPStatistics.h"
00033 #include "hugin_base/panotools/PanoToolsUtils.h"
00034 
00035 namespace HuginBase {
00036 using namespace std;
00037 
00038 UIntSet getCPoutsideLimit_pair(Panorama pano, double n)
00039 {
00040     CPVector allCP=pano.getCtrlPoints();
00041     unsigned int nrImg=pano.getNrOfImages();
00042     PanoramaOptions opts=pano.getOptions();
00043     //set projection to equrectangular for optimisation
00044     PanoramaOptions::ProjectionFormat oldproj=opts.getProjection();
00045     opts.setProjection(PanoramaOptions::EQUIRECTANGULAR);
00046     pano.setOptions(opts);
00047     UIntSet CPtoRemove;
00048 
00049     // do optimisation of all images pair
00050     // after it remove cp with errors > median/mean + n*sigma
00051     for (unsigned int image1=0; image1<nrImg-1; image1++)
00052     {
00053         SrcPanoImage img=pano.getImage(image1);
00054         for (unsigned int image2=image1+1; image2<nrImg; image2++)
00055         {
00056             //do not check linked image pairs
00057             if(img.YawisLinkedWith(pano.getImage(image2)))
00058                 continue;
00059             UIntSet Images;
00060             Images.clear();
00061             Images.insert(image1);
00062             Images.insert(image2);
00063             Panorama clean=pano.getSubset(Images);
00064             // pictures should contain at least 2 control points
00065             if(clean.getNrOfCtrlPoints()>1)
00066             {
00067                 // remove all horizontal and vertical control points
00068                 CPVector cpl = clean.getCtrlPoints();
00069                 CPVector newCP;
00070                 for (CPVector::const_iterator it = cpl.begin(); it != cpl.end(); it++) 
00071                     if (it->mode == ControlPoint::X_Y)
00072                         newCP.push_back(*it);
00073                 clean.setCtrlPoints(newCP);
00074 
00075                 if(clean.getNrOfCtrlPoints()>1)
00076                 {
00077                     //optimize position and hfov
00078                     OptimizeVector optvec;
00079                     std::set<std::string> imgopt;
00080                     //imgopt.insert("v");
00081                     optvec.push_back(imgopt);
00082                     imgopt.insert("r");
00083                     imgopt.insert("p");
00084                     imgopt.insert("y");
00085                     optvec.push_back(imgopt);
00086                     clean.setOptimizeVector(optvec);
00087                     PTools::optimize(clean);
00088                     cpl.clear();
00089                     cpl=clean.getCtrlPoints();
00090                     //calculate statistic and determine limit
00091                     double min,max,mean,var;
00092                     CalculateCPStatisticsError::calcCtrlPntsErrorStats(clean,min,max,mean,var);
00093                     double limit=mean+n*sqrt(var);
00094 
00095                     //identify cp with big error
00096                     unsigned int index=0;
00097                     unsigned int cpcounter=0;
00098                     for (CPVector::const_iterator it = allCP.begin(); it != allCP.end(); it++)
00099                     {
00100                         if(it->mode == ControlPoint::X_Y)
00101                             if((it->image1Nr==image1 && it->image2Nr==image2) ||
00102                                 (it->image1Nr==image2 && it->image2Nr==image1))
00103                             {
00104                                 if (cpl[index].error>limit)
00105                                     CPtoRemove.insert(cpcounter);
00106                                 index++;
00107                             };
00108                         cpcounter++;
00109                     };
00110                 };
00111             };
00112         };
00113     };
00114 
00115     return CPtoRemove;
00116 };
00117 
00118 UIntSet getCPoutsideLimit(Panorama pano, double n, bool skipOptimisation, bool includeLineCp)
00119 {
00120     UIntSet CPtoRemove;
00121     if(skipOptimisation)
00122     {
00123         //calculate current cp errors
00124         HuginBase::PTools::calcCtrlPointErrors(pano);
00125     }
00126     else
00127     {
00128         //optimize pano, after optimization pano contains the cp errors of the optimized project
00129         SmartOptimise::smartOptimize(pano);
00130     };
00131     CPVector allCP=pano.getCtrlPoints();
00132     if(!includeLineCp)
00133     {
00134         //remove all horizontal and vertical CP for calculation of mean and sigma
00135         CPVector CPxy;
00136         for (CPVector::const_iterator it = allCP.begin(); it != allCP.end(); it++)
00137         {
00138             if(it->mode == ControlPoint::X_Y)
00139                 CPxy.push_back(*it);
00140         };
00141         pano.setCtrlPoints(CPxy);
00142     };
00143     //calculate mean and sigma
00144     double min,max,mean,var;
00145     CalculateCPStatisticsError::calcCtrlPntsErrorStats(pano,min,max,mean,var);
00146     if(!includeLineCp)
00147     {
00148         pano.setCtrlPoints(allCP);
00149     };
00150     double limit=mean+n*sqrt(var);
00151 
00152     //now determine all control points with error > limit 
00153     unsigned int index=0;
00154     for (CPVector::const_iterator it = allCP.begin(); it != allCP.end(); it++)
00155     {
00156         if(it->error > limit)
00157         {
00158             if(includeLineCp)
00159             {
00160                 // all cp are treated the same
00161                 // no need for further checks
00162                 CPtoRemove.insert(index);
00163             }
00164             else
00165             {
00166                 //check only normal cp
00167                 if(it->mode == ControlPoint::X_Y)
00168                 {
00169                     CPtoRemove.insert(index);
00170                 };
00171             };
00172         };
00173         index++;
00174     };
00175 
00176     return CPtoRemove;
00177 };
00178 
00179 UIntSet getCPinMasks(HuginBase::Panorama pano)
00180 {
00181     HuginBase::UIntSet cps;
00182     HuginBase::CPVector cpList=pano.getCtrlPoints();
00183     if(cpList.size()>0)
00184     {
00185         for(unsigned int i=0;i<cpList.size();i++)
00186         {
00187             HuginBase::ControlPoint cp=cpList[i];
00188             // ignore line control points
00189             if(cp.mode!=HuginBase::ControlPoint::X_Y)
00190                 continue;
00191             bool insideMask=false;
00192             // check first image
00193             // remark: we could also use pano.getImage(cp.image1Nr).isInside(vigra::Point2D(cp.x1,cp.y1))
00194             //   this would also check the crop rectangles/circles
00195             //   but it would require that the pano is correctly align, otherwise the positive masks
00196             //   would not correctly checked
00197             HuginBase::MaskPolygonVector masks=pano.getImage(cp.image1Nr).getMasks();
00198             if(masks.size()>0)
00199             {
00200                 unsigned int j=0;
00201                 while((!insideMask) && (j<masks.size()))
00202                 {
00203                     insideMask=masks[j].isInside(hugin_utils::FDiff2D(cp.x1,cp.y1));
00204                     j++;
00205                 };
00206             };
00207             // and now the second
00208             if(!insideMask)
00209             {
00210                 masks=pano.getImage(cp.image2Nr).getMasks();
00211                 if(masks.size()>0)
00212                 {
00213                     unsigned int j=0;
00214                     while((!insideMask) && (j<masks.size()))
00215                     {
00216                         insideMask=masks[j].isInside(hugin_utils::FDiff2D(cp.x2,cp.y2));
00217                         j++;
00218                     };
00219                 };
00220             };
00221             if(insideMask)
00222                 cps.insert(i);
00223         };
00224     }
00225     return cps;
00226 };
00227 
00228 }  // namespace

Generated on 26 Nov 2014 for Hugintrunk by  doxygen 1.4.7