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

Generated on 10 Dec 2016 for Hugintrunk by  doxygen 1.4.7