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, see
00026  *  <http://www.gnu.org/licenses/>.
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, AppBase::ProgressDisplay& progress, 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     opts.setProjection(PanoramaOptions::EQUIRECTANGULAR);
00045     pano.setOptions(opts);
00046     UIntSet CPtoRemove;
00047 
00048     // do optimisation of all images pair
00049     // after it remove cp with errors > median/mean + n*sigma
00050     for (unsigned int image1=0; image1<nrImg-1; image1++)
00051     {
00052         SrcPanoImage img=pano.getImage(image1);
00053         for (unsigned int image2=image1+1; image2<nrImg; image2++)
00054         {
00055             //do not check linked image pairs
00056             if(img.YawisLinkedWith(pano.getImage(image2)))
00057                 continue;
00058             UIntSet Images;
00059             Images.clear();
00060             Images.insert(image1);
00061             Images.insert(image2);
00062             Panorama clean=pano.getSubset(Images);
00063             // pictures should contain at least 2 control points
00064             if(clean.getNrOfCtrlPoints()>1)
00065             {
00066                 // remove all horizontal and vertical control points
00067                 CPVector cpl = clean.getCtrlPoints();
00068                 CPVector newCP;
00069                 for (CPVector::const_iterator it = cpl.begin(); it != cpl.end(); ++it) 
00070                     if (it->mode == ControlPoint::X_Y)
00071                         newCP.push_back(*it);
00072                 clean.setCtrlPoints(newCP);
00073 
00074                 if(clean.getNrOfCtrlPoints()>1)
00075                 {
00076                     //optimize position and hfov
00077                     OptimizeVector optvec;
00078                     std::set<std::string> imgopt;
00079                     //imgopt.insert("v");
00080                     optvec.push_back(imgopt);
00081                     imgopt.insert("r");
00082                     imgopt.insert("p");
00083                     imgopt.insert("y");
00084                     optvec.push_back(imgopt);
00085                     clean.setOptimizeVector(optvec);
00086                     PTools::optimize(clean);
00087                     cpl.clear();
00088                     cpl=clean.getCtrlPoints();
00089                     //calculate statistic and determine limit
00090                     double min,max,mean,var;
00091                     CalculateCPStatisticsError::calcCtrlPntsErrorStats(clean,min,max,mean,var);
00092                     // if the standard deviation is bigger than the value, assume we have a lot of
00093                     // false cp, in this case take the mean value directly as limit
00094                     double limit = (sqrt(var) > mean) ? mean : (mean + n*sqrt(var));
00095 
00096                     //identify cp with big error
00097                     unsigned int index=0;
00098                     unsigned int cpcounter=0;
00099                     for (CPVector::const_iterator it = allCP.begin(); it != allCP.end(); ++it)
00100                     {
00101                         if(it->mode == ControlPoint::X_Y)
00102                             if((it->image1Nr==image1 && it->image2Nr==image2) ||
00103                                 (it->image1Nr==image2 && it->image2Nr==image1))
00104                             {
00105                                 if (cpl[index].error>limit)
00106                                     CPtoRemove.insert(cpcounter);
00107                                 index++;
00108                             };
00109                         cpcounter++;
00110                     };
00111                 };
00112             };
00113             if (!progress.updateDisplayValue())
00114             {
00115                 return CPtoRemove;
00116             };
00117         };
00118     };
00119 
00120     return CPtoRemove;
00121 };
00122 
00123 UIntSet getCPoutsideLimit(Panorama pano, double n, bool skipOptimisation, bool includeLineCp)
00124 {
00125     UIntSet CPtoRemove;
00126     if(skipOptimisation)
00127     {
00128         //calculate current cp errors
00129         HuginBase::PTools::calcCtrlPointErrors(pano);
00130     }
00131     else
00132     {
00133         //optimize pano, after optimization pano contains the cp errors of the optimized project
00134         SmartOptimise::smartOptimize(pano);
00135     };
00136     CPVector allCP=pano.getCtrlPoints();
00137     if(!includeLineCp)
00138     {
00139         //remove all horizontal and vertical CP for calculation of mean and sigma
00140         CPVector CPxy;
00141         for (CPVector::const_iterator it = allCP.begin(); it != allCP.end(); ++it)
00142         {
00143             if(it->mode == ControlPoint::X_Y)
00144                 CPxy.push_back(*it);
00145         };
00146         pano.setCtrlPoints(CPxy);
00147     };
00148     //calculate mean and sigma
00149     double min,max,mean,var;
00150     CalculateCPStatisticsError::calcCtrlPntsErrorStats(pano,min,max,mean,var);
00151     if(!includeLineCp)
00152     {
00153         pano.setCtrlPoints(allCP);
00154     };
00155     // if the standard deviation is bigger than the value, assume we have a lot of
00156     // false cp, in this case take the mean value directly as limit
00157     double limit = (sqrt(var) > mean) ? mean : (mean + n*sqrt(var));
00158 
00159     //now determine all control points with error > limit 
00160     unsigned int index=0;
00161     for (CPVector::const_iterator it = allCP.begin(); it != allCP.end(); ++it)
00162     {
00163         if(it->error > limit)
00164         {
00165             if(includeLineCp)
00166             {
00167                 // all cp are treated the same
00168                 // no need for further checks
00169                 CPtoRemove.insert(index);
00170             }
00171             else
00172             {
00173                 //check only normal cp
00174                 if(it->mode == ControlPoint::X_Y)
00175                 {
00176                     CPtoRemove.insert(index);
00177                 };
00178             };
00179         };
00180         index++;
00181     };
00182 
00183     return CPtoRemove;
00184 };
00185 
00186 UIntSet getCPinMasks(HuginBase::Panorama pano)
00187 {
00188     HuginBase::UIntSet cps;
00189     HuginBase::CPVector cpList=pano.getCtrlPoints();
00190     if(cpList.size()>0)
00191     {
00192         for(unsigned int i=0;i<cpList.size();i++)
00193         {
00194             HuginBase::ControlPoint cp=cpList[i];
00195             // ignore line control points
00196             if(cp.mode!=HuginBase::ControlPoint::X_Y)
00197                 continue;
00198             bool insideMask=false;
00199             // check first image
00200             // remark: we could also use pano.getImage(cp.image1Nr).isInside(vigra::Point2D(cp.x1,cp.y1))
00201             //   this would also check the crop rectangles/circles
00202             //   but it would require that the pano is correctly align, otherwise the positive masks
00203             //   would not correctly checked
00204             HuginBase::MaskPolygonVector masks=pano.getImage(cp.image1Nr).getMasks();
00205             if(masks.size()>0)
00206             {
00207                 unsigned int j=0;
00208                 while((!insideMask) && (j<masks.size()))
00209                 {
00210                     insideMask=masks[j].isInside(hugin_utils::FDiff2D(cp.x1,cp.y1));
00211                     j++;
00212                 };
00213             };
00214             // and now the second
00215             if(!insideMask)
00216             {
00217                 masks=pano.getImage(cp.image2Nr).getMasks();
00218                 if(masks.size()>0)
00219                 {
00220                     unsigned int j=0;
00221                     while((!insideMask) && (j<masks.size()))
00222                     {
00223                         insideMask=masks[j].isInside(hugin_utils::FDiff2D(cp.x2,cp.y2));
00224                         j++;
00225                     };
00226                 };
00227             };
00228             if(insideMask)
00229                 cps.insert(i);
00230         };
00231     }
00232     return cps;
00233 };
00234 
00235 }  // namespace

Generated on 30 Aug 2015 for Hugintrunk by  doxygen 1.4.7