PanoCommand.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00006 /*
00007 *  This is free software; you can redistribute it and/or
00008 *  modify it under the terms of the GNU General Public
00009 *  License as published by the Free Software Foundation; either
00010 *  version 2 of the License, or (at your option) any later version.
00011 *
00012 *  This software is distributed in the hope that it will be useful,
00013 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015 *  Lesser General Public License for more details.
00016 *
00017 *  You should have received a copy of the GNU General Public
00018 *  License along with this software. If not, see
00019 *  <http://www.gnu.org/licenses/>.
00020 *
00021 */
00022 
00023 #include "PanoCommand.h"
00024 #include <fstream>
00025 #include <panotools/PanoToolsUtils.h>
00026 
00027 #include <algorithms/nona/CenterHorizontally.h>
00028 #include <algorithms/nona/FitPanorama.h>
00029 #include <algorithms/basic/RotatePanorama.h>
00030 #include <algorithms/basic/TranslatePanorama.h>
00031 #include <algorithms/basic/CalculateMeanExposure.h>
00032 #include <algorithms/basic/StraightenPanorama.h>
00033 #include <panodata/ParseExp.h>
00034 
00035 namespace PanoCommand
00036 {
00037     CombinedPanoCommand::~CombinedPanoCommand()
00038     {
00039         for (std::vector<PanoCommand*>::iterator it = commands.begin(); it != commands.end(); ++it)
00040         {
00041             delete *it;
00042         }
00043     }
00044 
00045     bool CombinedPanoCommand::processPanorama(HuginBase::Panorama & pano)
00046     {
00047         bool result = true;
00048         for (std::vector<PanoCommand*>::iterator it = commands.begin(); it != commands.end(); ++it)
00049         {
00050             result &= (**it).processPanorama(pano);
00051         }
00053         return result;
00054     };
00055 
00056     bool NewPanoCmd::processPanorama(HuginBase::Panorama& pano)
00057     {
00058         pano.reset();
00059         return true;
00060     }
00061 
00062     bool AddImagesCmd::processPanorama(HuginBase::Panorama& pano)
00063     {
00064         std::vector<HuginBase::SrcPanoImage>::const_iterator it;
00065         for (it = imgs.begin(); it != imgs.end(); ++it)
00066         {
00067             pano.addImage(*it);
00068         }
00069         return true;
00070     }
00071 
00072     bool RemoveImageCmd::processPanorama(HuginBase::Panorama& pano)
00073     {
00074         pano.removeImage(imgNr);
00075         return true;
00076     }
00077 
00078     bool RemoveImagesCmd::processPanorama(HuginBase::Panorama& pano)
00079     {
00080         for (HuginBase::UIntSet::reverse_iterator it = imgNrs.rbegin();
00081             it != imgNrs.rend(); ++it)
00082         {
00083             pano.removeImage(*it);
00084         }
00085         return true;
00086     }
00087 
00088     bool UpdateVariablesCmd::processPanorama(HuginBase::Panorama& pano)
00089     {
00090         pano.updateVariables(vars);
00091         return true;
00092     }
00093 
00094     bool UpdateCPsCmd::processPanorama(HuginBase::Panorama& pano)
00095     {
00096         HuginBase::CPVector::const_iterator it;
00097         unsigned int i = 0;
00098         for (it = cps.begin(); it != cps.end(); ++it, i++)
00099         {
00100             pano.changeControlPoint(i, *it);
00101         }
00102         if (updateCPError)
00103         {
00104             HuginBase::PTools::calcCtrlPointErrors(pano);
00105         };
00106 
00107         return true;
00108     }
00109 
00110     bool UpdateVariablesCPCmd::processPanorama(HuginBase::Panorama& pano)
00111     {
00112         pano.updateVariables(vars);
00113         pano.updateCtrlPointErrors(cps);
00114         return true;
00115     }
00116 
00117     bool UpdateVariablesCPSetCmd::processPanorama(HuginBase::Panorama& pano)
00118     {
00119         pano.updateVariables(m_imgs, vars);
00120         pano.updateCtrlPointErrors(m_imgs, cps);
00121         pano.markAsOptimized();
00122         return true;
00123     }
00124 
00125     bool UpdateImageVariablesCmd::processPanorama(HuginBase::Panorama& pano)
00126     {
00127         pano.updateVariables(imgNr, vars);
00128         return true;
00129     }
00130 
00131     bool UpdateImagesVariablesCmd::processPanorama(HuginBase::Panorama& pano)
00132     {
00133         HuginBase::UIntSet::iterator it;
00134         HuginBase::VariableMapVector::const_iterator v_it = vars.begin();
00135         for (it = change.begin(); it != change.end(); ++it)
00136         {
00137             pano.updateVariables(*it, *v_it);
00138             ++v_it;
00139         }
00140         HuginBase::PTools::calcCtrlPointErrors(pano);
00141         return true;
00142     }
00143 
00144     bool UpdateVariablesByParseExpression::processPanorama(HuginBase::Panorama& pano)
00145     {
00146         if (!m_expression.empty())
00147         {
00148             Parser::PanoParseExpression(pano, m_expression);
00149             return true;
00150         }
00151         else
00152         {
00153             return false;
00154         };
00155     }
00156 
00157     bool UpdateOptimizeVectorCmd::processPanorama(HuginBase::Panorama & pano)
00158     {
00159         pano.setOptimizeVector(m_optvec);
00160         return true;
00161     }
00162 
00163 
00164     bool UpdateOptimizerSwitchCmd::processPanorama(HuginBase::Panorama & pano)
00165     {
00166         pano.setOptimizerSwitch(m_mode);
00167         return true;
00168     }
00169 
00170     bool UpdatePhotometricOptimizerSwitchCmd::processPanorama(HuginBase::Panorama & pano)
00171     {
00172         pano.setPhotometricOptimizerSwitch(m_mode);
00173         return true;
00174     }
00175 
00176     bool SetVariableCmd::processPanorama(HuginBase::Panorama& pano)
00177     {
00178         HuginBase::UIntSet::iterator it;
00179         for (it = images.begin(); it != images.end(); ++it)
00180         {
00181             pano.updateVariable(*it, var);
00182         }
00183         HuginBase::PTools::calcCtrlPointErrors(pano);
00184 
00185         return true;
00186     }
00187 
00188     bool CenterPanoCmd::processPanorama(HuginBase::Panorama& pano)
00189     {
00190         HuginBase::CenterHorizontally(pano).run();
00191         // adjust canvas size
00192         HuginBase::CalculateFitPanorama fitPano(pano);
00193         fitPano.run();
00194         HuginBase::PanoramaOptions opts = pano.getOptions();
00195         opts.setHFOV(fitPano.getResultHorizontalFOV());
00196         opts.setHeight(hugin_utils::roundi(fitPano.getResultHeight()));
00197         pano.setOptions(opts);
00198 
00199         return true;
00200     }
00201 
00202     bool StraightenPanoCmd::processPanorama(HuginBase::Panorama& pano)
00203     {
00204         HuginBase::StraightenPanorama(pano).run();
00205 
00206         HuginBase::PanoramaOptions opts = pano.getOptions();
00207         if (opts.getHFOV()<360)
00208         {
00209             // center non 360 deg panos
00210             HuginBase::CenterHorizontally(pano).run();
00211         };
00212         // adjust canvas size
00213         HuginBase::CalculateFitPanorama fitPano(pano);
00214         fitPano.run();
00215         opts.setHFOV(fitPano.getResultHorizontalFOV());
00216         opts.setHeight(hugin_utils::roundi(fitPano.getResultHeight()));
00217         pano.setOptions(opts);
00218         return true;
00219     }
00220 
00221     bool AddCtrlPointCmd::processPanorama(HuginBase::Panorama& pano)
00222     {
00223         pano.addCtrlPoint(point);
00224         HuginBase::PTools::calcCtrlPointErrors(pano);
00225         return true;
00226     }
00227 
00228     bool AddCtrlPointsCmd::processPanorama(HuginBase::Panorama& pano)
00229     {
00230         for (HuginBase::CPVector::iterator it = cps.begin(); it != cps.end(); ++it)
00231         {
00232             pano.addCtrlPoint(*it);
00233         }
00234         HuginBase::PTools::calcCtrlPointErrors(pano);
00235         return true;
00236     }
00237 
00238     bool RemoveCtrlPointCmd::processPanorama(HuginBase::Panorama& pano)
00239     {
00240         pano.removeCtrlPoint(pointNr);
00241         return true;
00242     }
00243 
00244     bool RemoveCtrlPointsCmd::processPanorama(HuginBase::Panorama& pano)
00245     {
00246         for (HuginBase::UIntSet::reverse_iterator it = m_points.rbegin(); it != m_points.rend(); ++it)
00247         {
00248             pano.removeCtrlPoint(*it);
00249         }
00250         return true;
00251     }
00252 
00253     bool ChangeCtrlPointCmd::processPanorama(HuginBase::Panorama& pano)
00254     {
00255         pano.changeControlPoint(pNr, point);
00256         HuginBase::PTools::calcCtrlPointErrors(pano);
00257         return true;
00258     }
00259 
00260     bool SetActiveImagesCmd::processPanorama(HuginBase::Panorama& pano)
00261     {
00262         HuginBase::UIntSet::iterator it;
00263         for (unsigned int i = 0; i < pano.getNrOfImages(); i++)
00264         {
00265             if (set_contains(m_active, i))
00266             {
00267                 pano.activateImage(i, true);
00268             }
00269             else
00270             {
00271                 pano.activateImage(i, false);
00272             };
00273         }
00274         return true;
00275     }
00276 
00277     bool SwapImagesCmd::processPanorama(HuginBase::Panorama& pano)
00278     {
00279         pano.swapImages(m_i1, m_i2);
00280         return true;
00281     }
00282 
00283     bool MoveImageCmd::processPanorama(HuginBase::Panorama& pano)
00284     {
00285         pano.moveImage(m_i1, m_i2);
00286         return true;
00287     }
00288 
00289     bool MergePanoCmd::processPanorama(HuginBase::Panorama& pano)
00290     {
00291         pano.mergePanorama(newPano);
00292         HuginBase::PTools::calcCtrlPointErrors(pano);
00293         return true;
00294     }
00295 
00296     bool UpdateSrcImageCmd::processPanorama(HuginBase::Panorama& pano)
00297     {
00298         pano.setSrcImage(imgNr, img);
00299         return true;
00300     }
00301 
00302     bool UpdateSrcImagesCmd::processPanorama(HuginBase::Panorama& pano)
00303     {
00304         int i = 0;
00305         for (HuginBase::UIntSet::iterator it = imgNrs.begin(); it != imgNrs.end(); ++it)
00306         {
00307             pano.setSrcImage(*it, imgs[i]);
00308             i++;
00309         }
00310         HuginBase::PTools::calcCtrlPointErrors(pano);
00311         return true;
00312     }
00313 
00314     bool SetPanoOptionsCmd::processPanorama(HuginBase::Panorama& pano)
00315     {
00316         pano.setOptions(options);
00317         return true;
00318     }
00319 
00320     LoadPTProjectCmd::LoadPTProjectCmd(HuginBase::Panorama & p, const std::string  & filename, const std::string & prefix)
00321         : PanoCommand(p), filename(filename), prefix(prefix)
00322     {
00323         m_clearDirty = true;
00324     }
00325 
00326     bool LoadPTProjectCmd::processPanorama(HuginBase::Panorama& pano)
00327     {
00328         std::ifstream in(filename.c_str());
00329         AppBase::DocumentData::ReadWriteError err = pano.readData(in);
00330         if (err != AppBase::DocumentData::SUCCESSFUL)
00331         {
00332             DEBUG_ERROR("could not load panotools script");
00333             return false;
00334         }
00335         in.close();
00336         return true;
00337     }
00338 
00339     bool RotatePanoCmd::processPanorama(HuginBase::Panorama& pano)
00340     {
00341         HuginBase::RotatePanorama(pano, y, p, r).run();
00342         return true;
00343     }
00344 
00345     bool TranslatePanoCmd::processPanorama(HuginBase::Panorama& pano)
00346     {
00347         HuginBase::TranslatePanorama(pano, X, Y, Z).run();
00348         return true;
00349     }
00350 
00351     bool UpdateFocalLengthCmd::processPanorama(HuginBase::Panorama& pano)
00352     {
00353         pano.UpdateFocalLength(imgNrs, m_focalLength);
00354         return true;
00355     }
00356 
00357     bool UpdateCropFactorCmd::processPanorama(HuginBase::Panorama& pano)
00358     {
00359         //search all image with the same lens, otherwise the crop factor is updated via links, 
00360         //but not the hfov if the image is not the given HuginBase::UIntSet
00361         HuginBase::UIntSet allImgWithSameLens;
00362         HuginBase::UIntSet testedLens;
00363         HuginBase::StandardImageVariableGroups variable_groups(pano);
00364         HuginBase::ImageVariableGroup & lenses = variable_groups.getLenses();
00365         for (HuginBase::UIntSet::const_iterator it = imgNrs.begin(); it != imgNrs.end(); ++it)
00366         {
00367             allImgWithSameLens.insert(*it);
00368             unsigned int lensNr = lenses.getPartNumber(*it);
00369             if (set_contains(testedLens, lensNr))
00370             {
00371                 continue;
00372             };
00373             testedLens.insert(lensNr);
00374             for (unsigned int i = 0; i<pano.getNrOfImages(); i++)
00375             {
00376                 if (lenses.getPartNumber(i) == lensNr)
00377                 {
00378                     allImgWithSameLens.insert(i);
00379                 };
00380             };
00381         };
00382         pano.UpdateCropFactor(allImgWithSameLens, m_cropFactor);
00383         return true;
00384     }
00385 
00386     bool ChangePartNumberCmd::processPanorama(HuginBase::Panorama& pano)
00387     {
00388         // it might change as we are setting them
00389         std::size_t new_new_part_number = new_part_number;
00390         HuginBase::ImageVariableGroup group(variables, pano);
00391         for (HuginBase::UIntSet::iterator it = image_numbers.begin(); it != image_numbers.end(); ++it)
00392         {
00393             group.switchParts(*it, new_new_part_number);
00394             // update the lens number if it changes.
00395             new_new_part_number = group.getPartNumber(*it);
00396         }
00397         return true;
00398     }
00399 
00400     bool ChangePartImagesLinkingCmd::processPanorama(HuginBase::Panorama& pano)
00401     {
00402         HuginBase::ImageVariableGroup group(groupVariables, pano);
00403         if (new_linked_state)
00404         {
00405             for (HuginBase::UIntSet::iterator imageIt = image_numbers.begin(); imageIt != image_numbers.end(); ++imageIt)
00406             {
00407                 // link the variables
00408                 for (std::set<HuginBase::ImageVariableGroup::ImageVariableEnum>::iterator variableIt = changeVariables.begin();
00409                     variableIt != changeVariables.end(); ++variableIt)
00410                 {
00411                     group.linkVariableImage(*variableIt, *imageIt);
00412                 }
00413             }
00414         }
00415         else
00416         {
00417             for (HuginBase::UIntSet::iterator imageIt = image_numbers.begin(); imageIt != image_numbers.end(); ++imageIt)
00418             {
00419                 // unlink the variable
00420                 for (std::set<HuginBase::ImageVariableGroup::ImageVariableEnum>::iterator variableIt = changeVariables.begin();
00421                     variableIt != changeVariables.end(); ++variableIt)
00422                 {
00423                     group.unlinkVariableImage(*variableIt, *imageIt);
00424                     group.updatePartNumbers();
00425                 }
00426             }
00427         }
00428         return true;
00429     }
00430 
00431     bool LinkLensVarsCmd::processPanorama(HuginBase::Panorama& pano)
00432     {
00433         HuginBase::StandardImageVariableGroups variable_groups(pano);
00434         HuginBase::ImageVariableGroup & lenses = variable_groups.getLenses();
00435         std::set<HuginBase::ImageVariableGroup::ImageVariableEnum>::iterator it;
00436         for (it = variables.begin(); it != variables.end(); ++it)
00437         {
00438             lenses.linkVariablePart(*it, lens_number);
00439         }
00440         return true;
00441     }
00442 
00444 #define image_variable( name, type, default_value )\
00445     bool ChangeImage##name##Cmd::processPanorama(HuginBase::Panorama& pano)\
00446         {\
00447         for (HuginBase::UIntSet::iterator it = image_numbers.begin(); it != image_numbers.end(); it++)\
00448         {\
00449             HuginBase::SrcPanoImage img = pano.getSrcImage(*it);\
00450             img.set##name(value);\
00451             pano.setSrcImage(*it, img);\
00452         }\
00453         return true;\
00454         };
00455 #include <panodata/image_variables.h>
00456 #undef image_variable
00457 
00458     bool NewPartCmd::processPanorama(HuginBase::Panorama& pano)
00459     {
00460         // unlink all the variables in the first image.
00461         DEBUG_ASSERT(image_numbers.size() > 0);
00462         unsigned int image_index = *image_numbers.begin();
00463         for (std::set<HuginBase::ImageVariableGroup::ImageVariableEnum>::iterator it = vars.begin(); it != vars.end(); ++it)
00464         {
00465             switch (*it)
00466             {
00467 #define image_variable( name, type, default_value )\
00468                     case HuginBase::ImageVariableGroup::IVE_##name:\
00469                         pano.unlinkImageVariable##name(image_index);\
00470                         break;
00471 #include <panodata/image_variables.h>
00472 #undef image_variable
00473             }
00474         }
00475         // now the first image should have a new part in the group.
00476         // we want to switch the rest of the images to the new part.
00477         HuginBase::ImageVariableGroup group(vars, pano);
00478         for (HuginBase::UIntSet::iterator it = ++image_numbers.begin(); it != image_numbers.end(); ++it)
00479         {
00480             std::size_t part_number = group.getPartNumber(image_index);
00481             group.switchParts(*it, part_number);
00482         }
00483         return true;
00484     }
00485 
00486     bool UpdateMaskForImgCmd::processPanorama(HuginBase::Panorama& pano)
00487     {
00488         pano.updateMasksForImage(m_img, m_mask);
00489         return true;
00490     }
00491 
00492     bool UpdateWhiteBalance::processPanorama(HuginBase::Panorama& pano)
00493     {
00494         pano.updateWhiteBalance(m_red, m_blue);
00495         return true;
00496     }
00497 
00498     bool ResetToMeanExposure::processPanorama(HuginBase::Panorama& pano)
00499     {
00500         HuginBase::PanoramaOptions opts = pano.getOptions();
00501         opts.outputExposureValue = HuginBase::CalculateMeanExposure::calcMeanExposure(pano);
00502         pano.setOptions(opts);
00503         return true;
00504     }
00505 
00506     bool DistributeImagesCmd::processPanorama(HuginBase::Panorama& pano)
00507     {
00508         const size_t nrImages = pano.getNrOfImages();
00509         if (nrImages>0)
00510         {
00511             const HuginBase::SrcPanoImage& img = pano.getImage(0);
00512             const double hfov = img.getHFOV();
00513             size_t imgsPerRow;
00514             //distribute all images
00515             //for rectilinear images calculate number of rows
00516             if (img.getProjection() == HuginBase::SrcPanoImage::RECTILINEAR)
00517             {
00518                 imgsPerRow = std::max(3, int(360 / (0.8*hfov)));
00519                 imgsPerRow = std::min(imgsPerRow, nrImages);
00520             }
00521             else
00522             {
00523                 //all other images do in one row to prevent cluttered images with fisheye images and the like
00524                 imgsPerRow = nrImages;
00525             };
00526             double offset = 0.75*hfov;
00527             if ((imgsPerRow - 1.0)*offset>360)
00528             {
00529                 offset = 360 / (imgsPerRow - 1.0);
00530             };
00531             double yaw = -(imgsPerRow - 1.0) / 2.0*offset;
00532             double pitch = 0;
00533             if (imgsPerRow<nrImages)
00534             {
00535                 pitch = (-(std::ceil(double(nrImages) / double(imgsPerRow)) - 1.0) / 2.0*offset);
00536             };
00537             HuginBase::VariableMapVector varsVec = pano.getVariables();
00538             size_t counter = 0;
00539             for (size_t i = 0; i<nrImages; i++)
00540             {
00541                 HuginBase::VariableMap::iterator it = varsVec[i].find("y");
00542                 if (it != varsVec[i].end())
00543                 {
00544                     it->second.setValue(yaw);
00545                 };
00546                 it = varsVec[i].find("p");
00547                 if (it != varsVec[i].end())
00548                 {
00549                     it->second.setValue(pitch);
00550                 };
00551                 yaw += offset;
00552                 counter++;
00553                 if (counter == imgsPerRow)
00554                 {
00555                     counter = 0;
00556                     pitch += offset;
00557                     yaw = -(imgsPerRow - 1.0) / 2.0*offset;
00558                 };
00559             };
00560             pano.updateVariables(varsVec);
00561         };
00562         return true;
00563     }
00564 
00565 } // namespace PanoCommand

Generated on 23 Jan 2018 for Hugintrunk by  doxygen 1.4.7