00001
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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
00210 HuginBase::CenterHorizontally(pano).run();
00211 };
00212
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
00360
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
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
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
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
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
00461 DEBUG_ASSERT(!image_numbers.empty());
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
00476
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
00515
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
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 }