pano_modify.cpp

Go to the documentation of this file.
00001 // -*- c-basic-offset: 4 -*-
00002 
00013 /*  This program is free software; you can redistribute it and/or
00014  *  modify it under the terms of the GNU General Public
00015  *  License as published by the Free Software Foundation; either
00016  *  version 2 of the License, or (at your option) any later version.
00017  *
00018  *  This software is distributed in the hope that it will be useful,
00019  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00020  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00021  *  General Public License for more details.
00022  *
00023  *  You should have received a copy of the GNU General Public
00024  *  License along with this software. If not, see
00025  *  <http://www.gnu.org/licenses/>.
00026  *
00027  */
00028 
00029 #include <fstream>
00030 #include <sstream>
00031 #include <cmath>
00032 #include <getopt.h>
00033 #include <panodata/Panorama.h>
00034 #include <algorithms/nona/CenterHorizontally.h>
00035 #include <algorithms/basic/StraightenPanorama.h>
00036 #include <algorithms/basic/RotatePanorama.h>
00037 #include <algorithms/basic/TranslatePanorama.h>
00038 #include <algorithms/nona/FitPanorama.h>
00039 #include <algorithms/basic/CalculateOptimalScale.h>
00040 #include <algorithms/basic/CalculateOptimalROI.h>
00041 #include <algorithms/basic/LayerStacks.h>
00042 #include <algorithms/basic/CalculateMeanExposure.h>
00043 #include "hugin_utils/utils.h"
00044 
00045 static void usage(const char* name)
00046 {
00047     std::cout << name << ": change output parameters of project file" << std::endl
00048          << "pano_modify version " << hugin_utils::GetHuginVersion() << std::endl
00049          << std::endl
00050          << "Usage:  " << name << " [options] input.pto" << std::endl
00051          << std::endl
00052          << "  Options:" << std::endl
00053          << "    -o, --output=file.pto  Output Hugin PTO file. Default: <filename>_mod.pto" << std::endl
00054          << "    -p, --projection=x     Sets the output projection to number x" << std::endl
00055          << "    --projection-parameter=x    Sets the parameter of the projection" << std::endl
00056          << "                                (Several parameters are separated by"<<std::endl
00057          << "                                space or comma)" << std::endl
00058          << "    --fov=AUTO|HFOV|HFOVxVFOV   Sets field of view" << std::endl
00059          << "                                AUTO: calculates optimal fov" << std::endl
00060          << "                                HFOV|HFOVxVFOV: set to given fov" << std::endl
00061          << "    -s, --straighten       Straightens the panorama" << std::endl
00062          << "    -c, --center           Centers the panorama" << std::endl
00063          << "    --canvas=AUTO|num%|WIDTHxHEIGHT  Sets the output canvas size" << std::endl
00064          << "                                AUTO: calculate optimal canvas size" << std::endl
00065          << "                                num%: scales the optimal size by given percent" << std::endl
00066          << "                                WIDTHxHEIGHT: set to given size" << std::endl
00067          << "    --crop=AUTO|AUTOHDR|left,right,top,bottom  Sets the crop rectangle" << std::endl
00068          << "                                AUTO: autocrop panorama" << std::endl
00069          << "                                AUTOHDR: autocrop HDR panorama" << std::endl
00070          << "                                left,right,top,bottom: to given size" << std::endl
00071          << "    --output-exposure=AUTO|num  Sets the output exposure value to mean" << std::endl
00072          << "                                exposure (AUTO) or to given value" << std::endl
00073          << "                                Prefix number with r for relativ change" << std::endl
00074          << "    --output-cropped-tiff    Output cropped tiffs as intermediate images" << std::endl
00075          << "    --output-uncropped-tiff  Output uncropped tiffs as intermediate images" << std::endl
00076          << "    --output-type=str       Sets the type of output" << std::endl
00077          << "                              Valid items are" << std::endl
00078          << "                                NORMAL|N: normal panorama" << std::endl
00079          << "                                STACKSFUSEDBLENDED|BF: LDR panorama with" << std::endl
00080          << "                                    blended stacks" << std::endl
00081          << "                                EXPOSURELAYERSFUSED|FB: LDR panorama with" << std::endl
00082          << "                                    fused exposure layers (any arrangement)" << std::endl
00083          << "                                HDR: HDR panorama" << std::endl
00084          << "                                REMAP: remapped images with corrected exposure" << std::endl
00085          << "                                REMAPORIG: remapped images with" << std::endl
00086          << "                                    uncorrected exposure" << std::endl
00087          << "                                HDRREMAP: remapped images in linear color space" << std::endl
00088          << "                                FUSEDSTACKS: exposure fused stacks" << std::endl
00089          << "                                HDRSTACKS: HDR stacks" << std::endl
00090          << "                                EXPOSURELAYERS: blended exposure layers" << std::endl
00091          << "                              and separated by a comma." << std::endl
00092          << "    --ldr-file=JPG|TIF|PNG  Sets the filetype for LDR panorama output" << std::endl
00093          << "    --ldr-compression=str   Sets the compression for LDR panorama output" << std::endl
00094          << "                              For TIF: NONE|PACKBITS|LZW|DEFLATE" << std::endl
00095          << "                              For JPEG: quality as number" << std::endl
00096          << "    --hdr-file=EXR|TIF      Sets the filetype for HDR panorama output" << std::endl
00097          << "    --hdr-compression=str   Sets the compression for HDR panorama output" << std::endl
00098          << "                              For TIF: NONE|PACKBITS|LZW|DEFLATE" << std::endl
00099          << "    --blender=ENBLEND|INTERNAL  Sets the blender to be used at stitching" << std::endl
00100          << "                            stage." << std::endl
00101          << "    --blender-args=str      Sets the arguments for the blender" << std::endl
00102          << "    --fusion-args=str       Sets the arguments for the fusion program" << std::endl
00103          << "    --hdrmerge-args=str     Setst the arguments for hdrmerge" << std::endl
00104          << "    --rotate=yaw,pitch,roll Rotates the whole panorama with the given angles" << std::endl
00105          << "    --translate=x,y,z       Translate the whole panorama with the given values" << std::endl
00106          << "    --interpolation=int     Sets the interpolation method" << std::endl
00107          << "    -h, --help             Shows this help" << std::endl
00108          << std::endl;
00109 }
00110 
00111 int main(int argc, char* argv[])
00112 {
00113     // parse arguments
00114     const char* optstring = "o:p:sch";
00115 
00116     enum
00117     {
00118         SWITCH_FOV=1000,
00119         SWITCH_CANVAS,
00120         SWITCH_CROP,
00121         SWITCH_ROTATE,
00122         SWITCH_TRANSLATE,
00123         SWITCH_EXPOSURE,
00124         SWITCH_OUTPUT_TYPE,
00125         SWITCH_BLENDER,
00126         SWITCH_LDRFILETYPE,
00127         SWITCH_LDRCOMPRESSION,
00128         SWITCH_HDRFILETYPE,
00129         SWITCH_HDRCOMPRESSION,
00130         SWITCH_CROPPED_TIFF,
00131         SWITCH_UNCROPPED_TIFF,
00132         SWITCH_BLENDER_ARGS,
00133         SWITCH_FUSION_ARGS,
00134         SWITCH_HDRMERGE_ARGS,
00135         SWITCH_PROJECTION_PARAMETER,
00136         SWITCH_INTERPOLATION
00137     };
00138     static struct option longOptions[] =
00139     {
00140         {"output", required_argument, NULL, 'o' },
00141         {"projection", required_argument, NULL, 'p' },
00142         {"projection-parameter", required_argument, NULL, SWITCH_PROJECTION_PARAMETER },
00143         {"fov", required_argument, NULL, SWITCH_FOV },
00144         {"straighten", no_argument, NULL, 's' },
00145         {"center", no_argument, NULL, 'c' },
00146         {"canvas", required_argument, NULL, SWITCH_CANVAS },
00147         {"crop", required_argument, NULL, SWITCH_CROP },
00148         {"output-cropped-tiff", no_argument, NULL, SWITCH_CROPPED_TIFF },
00149         {"output-uncropped-tiff", no_argument, NULL, SWITCH_UNCROPPED_TIFF },
00150         {"output-exposure", required_argument, NULL, SWITCH_EXPOSURE },
00151         {"output-type", required_argument, NULL, SWITCH_OUTPUT_TYPE },
00152         {"blender", required_argument, NULL, SWITCH_BLENDER },
00153         {"blender-args", required_argument, NULL, SWITCH_BLENDER_ARGS },
00154         {"fusion-args", required_argument, NULL, SWITCH_FUSION_ARGS },
00155         {"hdrmerge-args", required_argument, NULL, SWITCH_HDRMERGE_ARGS },
00156         {"ldr-file", required_argument,NULL, SWITCH_LDRFILETYPE },
00157         {"ldr-compression", required_argument, NULL, SWITCH_LDRCOMPRESSION },
00158         {"hdr-file", required_argument, NULL, SWITCH_HDRFILETYPE },
00159         {"hdr-compression", required_argument, NULL, SWITCH_HDRCOMPRESSION },
00160         {"rotate", required_argument, NULL, SWITCH_ROTATE },
00161         {"translate", required_argument, NULL, SWITCH_TRANSLATE },
00162         {"interpolation", required_argument, NULL, SWITCH_INTERPOLATION},
00163         {"help", no_argument, NULL, 'h' },
00164         0
00165     };
00166 
00167     int projection=-1;
00168     std::vector<double> projParameter;
00169     double newHFOV=-1;
00170     double newVFOV=-1;
00171     int scale=100;
00172     int newWidth=-1;
00173     int newHeight=-1;
00174     int outputCroppedTiff=-1;
00175     vigra::Rect2D newROI(0,0,0,0);
00176     bool doFit=false;
00177     bool doStraighten=false;
00178     bool doCenter=false;
00179     bool doOptimalSize=false;
00180     bool doAutocrop=false;
00181     bool autocropHDR=false;
00182     int c;
00183     double yaw = 0;
00184     double pitch = 0;
00185     double roll = 0;
00186     double x = 0;
00187     double y = 0;
00188     double z = 0;
00189     double outputExposure = -1000;
00190     bool relativeExposure = false;
00191     bool calcMeanExposure = false;
00192     std::string outputType;
00193     std::string ldrfiletype;
00194     std::string ldrcompression;
00195     std::string hdrfiletype;
00196     std::string hdrcompression;
00197     std::string output;
00198     std::string param;
00199     std::string blender;
00200 #define EMPTYARG "(empty)"
00201     std::string blenderArgs(EMPTYARG);
00202     std::string fusionArgs(EMPTYARG);
00203     std::string hdrMergeArgs(EMPTYARG);
00204     int interpolation = -1;
00205     while ((c = getopt_long (argc, argv, optstring, longOptions,nullptr)) != -1)
00206     {
00207         switch (c)
00208         {
00209             case 'o':
00210                 output = optarg;
00211                 break;
00212             case 'h':
00213                 usage(hugin_utils::stripPath(argv[0]).c_str());
00214                 return 0;
00215             case 'p':
00216                 //projection
00217                 projection=atoi(optarg);
00218                 if((projection==0) && (strcmp(optarg,"0")!=0))
00219                 {
00220                     std::cerr << hugin_utils::stripPath(argv[0]) << ": Could not parse projection number." << std::endl;
00221                     return 1;
00222                 };
00223                 if(projection>=panoProjectionFormatCount())
00224                 {
00225                     std::cerr << hugin_utils::stripPath(argv[0]) << ": projection " << projection << " is an invalid projection number." << std::endl;
00226                     return 1;
00227                 };
00228                 break;
00229             case SWITCH_PROJECTION_PARAMETER:
00230                 // projection parameters
00231                 {
00232                     // split at space or comma
00233                     std::vector<std::string> parameter = hugin_utils::SplitString(optarg, ", ");
00234                     for(const auto& p: parameter)
00235                     { 
00236                         double d;
00237                         if (hugin_utils::stringToDouble(p, d))
00238                         {
00239                             projParameter.push_back(d);
00240                         }
00241                         else
00242                         { 
00243                             std::cerr << hugin_utils::stripPath(argv[0]) << ": Could not parse projection parameters \"" << optarg << "\"." << std::endl;
00244                             return 1;
00245                         };
00246                     };
00247                 }
00248                 break;
00249             case SWITCH_FOV:
00250                 //field of view
00251                 param=optarg;
00252                 param=hugin_utils::toupper(param);
00253                 if(param=="AUTO")
00254                 {
00255                     doFit=true;
00256                 }
00257                 else
00258                 {
00259                     double hfov, vfov;
00260                     int n=sscanf(optarg, "%lfx%lf", &hfov, &vfov);
00261                     if(n==1)
00262                     {
00263                         if(hfov>0)
00264                         {
00265                             newHFOV=hfov;
00266                         }
00267                         else
00268                         {
00269                             std::cerr << hugin_utils::stripPath(argv[0]) << ": Invalid field of view" << std::endl;
00270                             return 1;
00271                         };
00272                     }
00273                     else
00274                     {
00275                         if (n==2)
00276                         {
00277                             if(hfov>0 && vfov>0)
00278                             {
00279                                 newHFOV=hfov;
00280                                 newVFOV=vfov;
00281                             }
00282                             else
00283                             {
00284                                 std::cerr << hugin_utils::stripPath(argv[0]) << ": Invalid field of view" << std::endl;
00285                                 return 1;
00286                             };
00287                         }
00288                         else
00289                         {
00290                             std::cerr << hugin_utils::stripPath(argv[0]) << ": Could not parse field of view" << std::endl;
00291                             return 1;
00292                         };
00293                     };
00294                 };
00295                 break;
00296             case 's':
00297                 doStraighten=true;
00298                 break;
00299             case 'c':
00300                 doCenter=true;
00301                 break;
00302             case SWITCH_CANVAS:
00303                 //canvas size
00304                 param=optarg;
00305                 param=hugin_utils::toupper(param);
00306                 if(param=="AUTO")
00307                 {
00308                     doOptimalSize=true;
00309                 }
00310                 else
00311                 {
00312                     int pos=param.find("%");
00313                     if(pos!=std::string::npos)
00314                     {
00315                         param=param.substr(0,pos);
00316                         scale=atoi(param.c_str());
00317                         if(scale==0)
00318                         {
00319                             std::cerr << hugin_utils::stripPath(argv[0]) << ": No valid scale factor given." << std::endl;
00320                             return 1;
00321                         };
00322                         doOptimalSize=true;
00323                     }
00324                     else
00325                     {
00326                         int width, height;
00327                         int n=sscanf(optarg, "%dx%d", &width, &height);
00328                         if (n==2)
00329                         {
00330                             if(width>0 && height>0)
00331                             {
00332                                 newWidth=width;
00333                                 newHeight=height;
00334                             }
00335                             else
00336                             {
00337                                 std::cerr << hugin_utils::stripPath(argv[0]) << ": Invalid canvas size" << std::endl;
00338                                 return 1;
00339                             };
00340                         }
00341                         else
00342                         {
00343                             std::cerr << hugin_utils::stripPath(argv[0]) << ": Could not parse canvas size" << std::endl;
00344                             return 1;
00345                         };
00346                     };
00347                 };
00348                 break;
00349             case SWITCH_CROP:
00350                 //crop
00351                 param=optarg;
00352                 param=hugin_utils::toupper(param);
00353                 if(param=="AUTO" || param=="AUTOHDR")
00354                 {
00355                     doAutocrop=true;
00356                     if(param=="AUTOHDR")
00357                     {
00358                         autocropHDR=true;
00359                     };
00360                 }
00361                 else
00362                 {
00363                     int left, right, top, bottom;
00364                     int n=sscanf(optarg, "%d,%d,%d,%d", &left, &right, &top, &bottom);
00365                     if (n==4)
00366                     {
00367                         if(right>left && bottom>top && left>=0 && top>=0)
00368                         {
00369                             newROI.setUpperLeft(vigra::Point2D(left,top));
00370                             newROI.setLowerRight(vigra::Point2D(right,bottom));
00371                         }
00372                         else
00373                         {
00374                             std::cerr << hugin_utils::stripPath(argv[0]) << ": Invalid crop area" << std::endl;
00375                             return 1;
00376                         };
00377                     }
00378                     else
00379                     {
00380                         std::cerr << hugin_utils::stripPath(argv[0]) << ": Could not parse crop values" << std::endl;
00381                         return 1;
00382                     };
00383                 };
00384                 break;
00385             case SWITCH_CROPPED_TIFF:
00386                 outputCroppedTiff = 1;
00387                 break;
00388             case SWITCH_UNCROPPED_TIFF:
00389                 outputCroppedTiff = 0;
00390                 break;
00391             case SWITCH_EXPOSURE:
00392                 param = optarg;
00393                 param = hugin_utils::toupper(param);
00394                 if (param == "AUTO")
00395                 {
00396                     calcMeanExposure = true;
00397                 }
00398                 else
00399                 {
00400                     if (!param.empty())
00401                     {
00402                         // if first character is r assume relative exposure values
00403                         relativeExposure = (param[0] == 'R');
00404                         if (relativeExposure)
00405                         {
00406                             param.erase(0, 1);
00407                         };
00408                         int n = sscanf(param.c_str(), "%lf", &outputExposure);
00409                         if (n != 1)
00410                         {
00411                             std::cerr << hugin_utils::stripPath(argv[0]) << ": Could not parse output exposure value." << std::endl;
00412                             return 1;
00413                         };
00414                     }
00415                     else
00416                     {
00417                         std::cerr << hugin_utils::stripPath(argv[0]) << ": Could not parse output exposure value." << std::endl;
00418                         return 1;
00419                     };
00420                 };
00421                 break;
00422             case SWITCH_OUTPUT_TYPE:
00423                 if (!outputType.empty())
00424                 {
00425                     outputType.append(",");
00426                 };
00427                 outputType.append(optarg);
00428                 break;
00429             case SWITCH_BLENDER:
00430                 blender = hugin_utils::tolower(hugin_utils::StrTrim(optarg));
00431                 break;
00432             case SWITCH_LDRFILETYPE:
00433                 ldrfiletype = hugin_utils::tolower(hugin_utils::StrTrim(optarg));
00434                 break;
00435             case SWITCH_LDRCOMPRESSION:
00436                 ldrcompression = hugin_utils::toupper(hugin_utils::StrTrim(optarg));
00437                 break;
00438             case SWITCH_HDRFILETYPE:
00439                 hdrfiletype = hugin_utils::tolower(hugin_utils::StrTrim(optarg));
00440                 break;
00441             case SWITCH_HDRCOMPRESSION:
00442                 hdrcompression = hugin_utils::toupper(hugin_utils::StrTrim(optarg));
00443                 break;
00444             case SWITCH_BLENDER_ARGS:
00445                 blenderArgs = optarg;
00446                 break;
00447             case SWITCH_FUSION_ARGS:
00448                 fusionArgs = optarg;
00449                 break;
00450             case SWITCH_HDRMERGE_ARGS:
00451                 hdrMergeArgs = optarg;
00452                 break;
00453             case SWITCH_ROTATE:
00454                 {
00455                     int n=sscanf(optarg, "%lf,%lf,%lf", &yaw, &pitch, &roll);
00456                     if(n!=3)
00457                     {
00458                         std::cerr << hugin_utils::stripPath(argv[0]) << ": Could not parse rotate angles values. Given: \"" << optarg << "\"" << std::endl;
00459                         return 1;
00460                     };
00461                 };
00462                 break;
00463             case SWITCH_TRANSLATE:
00464                 {
00465                     int n=sscanf(optarg, "%lf,%lf,%lf", &x, &y, &z);
00466                     if(n!=3)
00467                     {
00468                         std::cerr << hugin_utils::stripPath(argv[0]) << ": Could not parse translation values. Given: \"" << optarg << "\"" << std::endl;
00469                         return 1;
00470                     };
00471                 };
00472                 break;
00473             case SWITCH_INTERPOLATION:
00474                 if (!hugin_utils::stringToInt(optarg, interpolation))
00475                 {
00476                     std::cerr << hugin_utils::stripPath(argv[0]) << ": Could not parse interpolation value. Given: \"" << optarg << "\"" << std::endl;
00477                     return 1;
00478                 };
00479                 if (interpolation<0 || interpolation>vigra_ext::INTERP_SINC_1024)
00480                 {
00481                     std::cerr << hugin_utils::stripPath(argv[0]) << ": Interpolator " << interpolation << " is not valid." << std::endl;
00482                     return 1;
00483                 }
00484                 break;
00485             case ':':
00486             case '?':
00487                 // missing argument or invalid switch
00488                 return 1;
00489                 break;
00490             default:
00491                 // this should not happen
00492                 abort();
00493 
00494         }
00495     }
00496 
00497     if (argc - optind != 1)
00498     {
00499         if (argc - optind < 1)
00500         {
00501             std::cerr << hugin_utils::stripPath(argv[0]) << ": No project file given." << std::endl;
00502         }
00503         else
00504         {
00505             std::cerr << hugin_utils::stripPath(argv[0]) << ": Only one project file expected." << std::endl;
00506         };
00507         return 1;
00508     };
00509 
00510     // set some options which depends on each other
00511     if(doStraighten)
00512     {
00513         doCenter=false;
00514         doFit=true;
00515     };
00516     if(doCenter)
00517     {
00518         doFit=true;
00519     };
00520 
00521     std::string input=argv[optind];
00522     // read panorama
00523     HuginBase::Panorama pano;
00524     std::ifstream prjfile(input.c_str());
00525     if (!prjfile.good())
00526     {
00527         std::cerr << "could not open script : " << input << std::endl;
00528         return 1;
00529     }
00530     pano.setFilePrefix(hugin_utils::getPathPrefix(input));
00531     AppBase::DocumentData::ReadWriteError err = pano.readData(prjfile);
00532     if (err != AppBase::DocumentData::SUCCESSFUL)
00533     {
00534         std::cerr << "error while parsing panos tool script: " << input << std::endl;
00535         std::cerr << "DocumentData::ReadWriteError code: " << err << std::endl;
00536         return 1;
00537     }
00538 
00539     // sets the projection
00540     if(projection!=-1)
00541     {
00542         HuginBase::PanoramaOptions opt = pano.getOptions();
00543         opt.setProjection((HuginBase::PanoramaOptions::ProjectionFormat)projection);
00544         pano_projection_features proj;
00545         if (panoProjectionFeaturesQuery(projection, &proj))
00546         {
00547             std::cout << "Setting projection to " << proj.name << std::endl;
00548         }
00549         pano.setOptions(opt);
00550     };
00551     // set projection parameters
00552     if (!projParameter.empty())
00553     {
00554         HuginBase::PanoramaOptions opt = pano.getOptions();
00555         if (projParameter.size() > opt.m_projFeatures.numberOfParameters)
00556         {
00557             std::cout << "Warning: Given " << projParameter.size() << " projection parameters, but projection supports" << std::endl
00558                 << "         only " << opt.m_projFeatures.numberOfParameters << ". Ignoring surplus parameters." << std::endl;
00559             while (projParameter.size() > opt.m_projFeatures.numberOfParameters)
00560             {
00561                 projParameter.pop_back();
00562             }
00563         }
00564         if (!projParameter.empty())
00565         {
00566             std::vector<double> newProjParameters = opt.getProjectionParameters();
00567             std::copy(projParameter.begin(), projParameter.end(), newProjParameters.begin());
00568             opt.setProjectionParameters(newProjParameters);
00569             // read back, new the limits have been applied
00570             newProjParameters = opt.getProjectionParameters();
00571             auto it = newProjParameters.begin();
00572             std::cout << "Setting projection parameters to: " << *it;
00573             ++it;
00574             while (it != newProjParameters.end())
00575             {
00576                 std::cout << ", " << *it;
00577                 ++it;
00578             }
00579             std::cout << std::endl;
00580             pano.setOptions(opt);
00581         }
00582         else
00583         {
00584             std::cout << "Warning: Current projection does not support projection parameters." << std::endl;
00585         }
00586     }
00587     // output exposure value
00588     if (outputExposure > -1000 || calcMeanExposure)
00589     {
00590         HuginBase::PanoramaOptions opt = pano.getOptions();
00591         if (calcMeanExposure)
00592         {
00593             opt.outputExposureValue = HuginBase::CalculateMeanExposure::calcMeanExposure(pano);
00594         }
00595         else
00596         {
00597             if (relativeExposure)
00598             {
00599                 opt.outputExposureValue += outputExposure;
00600             }
00601             else
00602             {
00603                 opt.outputExposureValue = outputExposure;
00604             };
00605         };
00606         std::cout << "Setting output exposure value to " << opt.outputExposureValue << std::endl;
00607         pano.setOptions(opt);
00608     };
00609     // output type: normal, fused, hdr pano..
00610     if (!outputType.empty())
00611     {
00612         HuginBase::PanoramaOptions opt = pano.getOptions();
00613         // reset all output
00614         // final pano
00615         opt.outputLDRBlended = false;
00616         opt.outputLDRExposureBlended = false;
00617         opt.outputLDRExposureLayersFused = false;
00618         opt.outputHDRBlended = false;
00619         // remapped images
00620         opt.outputLDRLayers = false;
00621         opt.outputLDRExposureRemapped = false;
00622         opt.outputHDRLayers = false;
00623         // stacks
00624         opt.outputLDRStacks = false;
00625         opt.outputHDRStacks = false;
00626         // exposure layers
00627         opt.outputLDRExposureLayers = false;
00628         // now parse string and set corresponding options
00629         std::vector<std::string> tokens = hugin_utils::SplitString(outputType, ",");
00630         size_t counter = 0;
00631         for (size_t i = 0; i < tokens.size(); i++)
00632         {
00633             std::string s = hugin_utils::toupper(hugin_utils::StrTrim(tokens[i]));
00634             if (s == "NORMAL" || s=="N")
00635             {
00636                 opt.outputLDRBlended = true;
00637                 std::cout << "Activate output of normal panorama." << std::endl;
00638                 counter++;
00639                 continue;
00640             };
00641             if (s == "STACKSFUSEDBLENDED" || s == "FB")
00642             {
00643                 opt.outputLDRExposureBlended = true;
00644                 std::cout << "Activate output of LDR panorama: Exposure fused from stacks." << std::endl;
00645                 counter++;
00646                 continue;
00647             };
00648             if (s == "EXPOSURELAYERSFUSED" || s == "BF")
00649             {
00650                 opt.outputLDRExposureLayersFused = true;
00651                 std::cout << "Activate output of LDR panorama: Exposure fused from any arrangement." << std::endl;
00652                 counter++;
00653                 continue;
00654             };
00655             if (s == "HDR")
00656             {
00657                 opt.outputHDRBlended = true;
00658                 std::cout << "Activate output of hdr panorama." << std::endl;
00659                 counter++;
00660                 continue;
00661             };
00662             // single remapped images
00663             if (s == "REMAP")
00664             {
00665                 opt.outputLDRLayers = true;
00666                 std::cout << "Activate output of remapped, exposure corrected images." << std::endl;
00667                 counter++;
00668                 continue;
00669             };
00670             if (s == "REMAPORIG")
00671             {
00672                 opt.outputLDRExposureRemapped = true;
00673                 std::cout << "Activate output of remapped images with unmodified exposure." << std::endl;
00674                 counter++;
00675                 continue;
00676             };
00677             if (s == "HDRREMAP")
00678             {
00679                 opt.outputHDRLayers = true;
00680                 std::cout << "Activate output of remapped hdr images." << std::endl;
00681                 counter++;
00682                 continue;
00683             };
00684             //stacks
00685             if (s == "FUSEDSTACKS")
00686             {
00687                 opt.outputLDRStacks = true;
00688                 std::cout << "Activate output of exposure fused stacks." << std::endl;
00689                 counter++;
00690                 continue;
00691             };
00692             if (s == "HDRSTACKS")
00693             {
00694                 opt.outputHDRStacks = true;
00695                 std::cout << "Activate output of HDR stacks." << std::endl;
00696                 counter++;
00697                 continue;
00698             };
00699             //exposure layers
00700             if (s == "EXPOSURELAYERS")
00701             {
00702                 opt.outputLDRExposureLayers = true;
00703                 std::cout << "Activate output of exposure layers." << std::endl;
00704                 counter++;
00705                 continue;
00706             };
00707             std::cout << "Unknown parameter \"" << s << "\" found in --output-type." << std::endl
00708                 << "Ignoring this parameter." << std::endl;
00709         }
00710         if (counter > 0)
00711         {
00712             pano.setOptions(opt);
00713         }
00714         else
00715         {
00716             std::cout << "No matching output type given. The whole output-type is ignored." << std::endl;
00717         };
00718     };
00719     // cropped or uncropped tiff output
00720     if (outputCroppedTiff != -1)
00721     {
00722         HuginBase::PanoramaOptions opts = pano.getOptions();
00723         opts.tiff_saveROI = (outputCroppedTiff == 1);
00724         std::cout << "Setting support for cropped images: " << ((outputCroppedTiff == 1) ? "yes" : "no") << std::endl;
00725         pano.setOptions(opts);
00726     }
00727     // blender type
00728     if (!blender.empty())
00729     {
00730         HuginBase::PanoramaOptions opt = pano.getOptions();
00731         if (blender == "enblend")
00732         {
00733             opt.blendMode = HuginBase::PanoramaOptions::ENBLEND_BLEND;
00734             std::cout << "Setting blender type to \"ENBLEND\"." << std::endl;
00735         }
00736         else
00737         {
00738             if (blender == "internal" || blender == "verdandi")
00739             {
00740                 opt.blendMode = HuginBase::PanoramaOptions::INTERNAL_BLEND;
00741                 std::cout << "Setting blender type to \"INTERNAL\"." << std::endl;
00742             }
00743             else
00744             {
00745                 std::cout << "Blender \"" << blender << "\" is not a valid blender ." << std::endl
00746                     << "Ignoring parameter." << std::endl;
00747             };
00748         };
00749         pano.setOptions(opt);
00750     }
00751     if (blenderArgs != EMPTYARG)
00752     {
00753         HuginBase::PanoramaOptions opt = pano.getOptions();
00754         switch (opt.blendMode)
00755         {
00756             case HuginBase::PanoramaOptions::ENBLEND_BLEND:
00757                 opt.enblendOptions = blenderArgs;
00758                 std::cout << "Setting enblend arguments to " << blenderArgs << std::endl;
00759                 break;
00760             case HuginBase::PanoramaOptions::INTERNAL_BLEND:
00761                 opt.verdandiOptions = blenderArgs;
00762                 std::cout << "Setting verdandi arguments to " << blenderArgs << std::endl;
00763                 break;
00764             default:
00765                 std::cout << "Unknow blender in pto file." << std::endl;
00766                 break;
00767         };
00768         pano.setOptions(opt);
00769     };
00770     if (fusionArgs != EMPTYARG)
00771     {
00772         HuginBase::PanoramaOptions opt = pano.getOptions();
00773         opt.enfuseOptions = fusionArgs;
00774         std::cout << "Setting enfuse arguments to " << fusionArgs << std::endl;
00775         pano.setOptions(opt);
00776     };
00777     if (hdrMergeArgs != EMPTYARG)
00778     {
00779         HuginBase::PanoramaOptions opt = pano.getOptions();
00780         opt.hdrmergeOptions = hdrMergeArgs;
00781         std::cout << "Setting hugin_hdrdmerge arguments to " << hdrMergeArgs << std::endl;
00782         pano.setOptions(opt);
00783     };
00784     // ldr output file type
00785     if (!ldrfiletype.empty())
00786     {
00787         HuginBase::PanoramaOptions opt = pano.getOptions();
00788         if (ldrfiletype == "jpg" || ldrfiletype == "png" || ldrfiletype == "tif")
00789         {
00790             opt.outputImageType = ldrfiletype;
00791             std::cout << "Setting ldr output to filetype \"" << ldrfiletype << "\"." << std::endl;
00792             pano.setOptions(opt);
00793         }
00794         else
00795         {
00796             std::cout << "LDR file format \"" << ldrfiletype << "\" is not a valid LDR output filetype." << std::endl
00797                 << "Ignoring parameter." << std::endl;
00798         };
00799     };
00800     // ldr compression
00801     if (!ldrcompression.empty())
00802     {
00803         HuginBase::PanoramaOptions opt = pano.getOptions();
00804         if (opt.outputImageType == "tif")
00805         {
00806             if (ldrcompression == "NONE" || ldrcompression == "PACKBITS" || ldrcompression == "LZW" || ldrcompression == "DEFLATE")
00807             {
00808                 opt.outputImageTypeCompression = ldrcompression;
00809                 std::cout << "Setting TIF compression to \"" << ldrcompression << "\"." << std::endl;
00810                 opt.tiffCompression = ldrcompression;
00811             }
00812             else
00813             {
00814                 std::cout << "LDR compression \"" << ldrcompression << "\" is not a valid compression value for TIF files." << std::endl
00815                     << "Ignoring compression." << std::endl;
00816             }
00817         }
00818         else
00819         {
00820             if (opt.outputImageType == "jpg")
00821             {
00822                 int quality = 0;
00823                 quality = atoi(ldrcompression.c_str());
00824                 if (quality != 0)
00825                 {
00826                     if (quality>0 && quality <=100)
00827                     { 
00828                         opt.quality = quality;
00829                         std::cout << "Setting JPEG quality to " << quality << "." << std::endl;
00830                     }
00831                     else
00832                     {
00833                         std::cout << "Given value for JPEG quality is outside the valid range 1..100." << std::endl
00834                             << "Ignoring value." << std::endl;
00835                     };
00836                 }
00837                 else
00838                 {
00839                     std::cout << "Could not parse \"" << ldrcompression << "\" as a valid JPEG quality number." << std::endl
00840                         << "Ignoring value." << std::endl;
00841                 };
00842             }
00843             else
00844             {
00845                 if (opt.outputImageType == "png")
00846                 {
00847                     std::cout << "Setting compression for PNG images is not supported." << std::endl;
00848                 }
00849                 else
00850                 {
00851                     // this should never happen
00852                     std::cout << "Unknown image format" << std::endl;
00853                 };
00854             };
00855         };
00856         pano.setOptions(opt);
00857     };
00858     // hdr output file type
00859     if (!hdrfiletype.empty())
00860     {
00861         HuginBase::PanoramaOptions opt = pano.getOptions();
00862         if (hdrfiletype == "exr" || hdrfiletype == "tif")
00863         {
00864             opt.outputImageTypeHDR = hdrfiletype;
00865             std::cout << "Setting hdr output to filetype \"" << ldrfiletype << "\"." << std::endl;
00866             pano.setOptions(opt);
00867         }
00868         else
00869         {
00870             std::cout << "HDR file format \"" << ldrfiletype << "\" is not a valid HDR output filetype." << std::endl
00871                 << "Ignoring parameter." << std::endl;
00872         };
00873     };
00874     // hdr compression
00875     if (!hdrcompression.empty())
00876     {
00877         HuginBase::PanoramaOptions opt = pano.getOptions();
00878         if (opt.outputImageTypeHDR == "tif")
00879         {
00880             if (hdrcompression == "NONE" || hdrcompression == "PACKBITS" || hdrcompression == "LZW" || hdrcompression == "DEFLATE")
00881             {
00882                 opt.outputImageTypeHDRCompression = hdrcompression;
00883                 std::cout << "Setting HDR-TIF compression to \"" << hdrcompression << "\"." << std::endl;
00884             }
00885             else
00886             {
00887                 std::cout << "HDR compression \"" << ldrcompression << "\" is not a valid compression value for TIF files." << std::endl
00888                     << "Ignoring compression." << std::endl;
00889             }
00890         }
00891         else
00892         {
00893             if (opt.outputImageTypeHDR == "exr")
00894             {
00895                 std::cout << "Setting compression for EXR images is not supported." << std::endl;
00896             }
00897             else
00898             {
00899                 // this should never happen
00900                 std::cout << "Unknown HDR image format" << std::endl;
00901             };
00902         };
00903         pano.setOptions(opt);
00904     };
00905     // rotate complete pano
00906     if (std::abs(yaw) + std::abs(pitch) + std::abs(roll) > 0.0)
00907     {
00908         std::cout << "Rotate panorama (yaw=" << yaw << ", pitch= " << pitch << ", roll=" << roll << ")" << std::endl;
00909         HuginBase::RotatePanorama(pano, yaw, pitch, roll).run();
00910     };
00911     // translate complete pano
00912     if(std::abs(x) + std::abs(y) + std::abs(z) > 0.0)
00913     {
00914         std::cout << "Translate panorama (x=" << x << ", y=" << y << ", z=" << z << ")" << std::endl;
00915         HuginBase::TranslatePanorama(pano, x, y, z).run();
00916     };
00917     // straighten
00918     if(doStraighten)
00919     {
00920         std::cout << "Straighten panorama" << std::endl;
00921         HuginBase::StraightenPanorama(pano).run();
00922         HuginBase::CenterHorizontally(pano).run();
00923     };
00924     // center
00925     if(doCenter)
00926     {
00927         std::cout << "Center panorama" << std::endl;
00928         HuginBase::CenterHorizontally(pano).run();
00929     }
00930     //fit fov
00931     if(doFit)
00932     {
00933         std::cout << "Fit panorama field of view to best size" << std::endl;
00934         HuginBase::PanoramaOptions opt = pano.getOptions();
00935         HuginBase::CalculateFitPanorama fitPano(pano);
00936         fitPano.run();
00937         opt.setHFOV(fitPano.getResultHorizontalFOV());
00938         opt.setHeight(hugin_utils::roundi(fitPano.getResultHeight()));
00939         std::cout << "Setting field of view to " << opt.getHFOV() << " x " << opt.getVFOV() << std::endl;
00940         pano.setOptions(opt);
00941     };
00942     //set field of view manually
00943     if(newHFOV>0)
00944     {
00945         HuginBase::PanoramaOptions opt = pano.getOptions();
00946         opt.setHFOV(newHFOV);
00947         if(opt.fovCalcSupported(opt.getProjection()) && newVFOV>0)
00948         {
00949             opt.setVFOV(newVFOV);
00950         }
00951         std::cout << "Setting field of view to " << opt.getHFOV() << " x " << opt.getVFOV() << std::endl;
00952         pano.setOptions(opt);
00953     };
00954     // calc optimal size
00955     if(doOptimalSize)
00956     {
00957         std::cout << "Calculate optimal size of panorama" << std::endl;
00958         double s = HuginBase::CalculateOptimalScale::calcOptimalScale(pano);
00959         HuginBase::PanoramaOptions opt = pano.getOptions();
00960         opt.setWidth(hugin_utils::roundi(opt.getWidth()*s*scale/100), true);
00961         std::cout << "Setting canvas size to " << opt.getWidth() << " x " << opt.getHeight() << std::endl;
00962         pano.setOptions(opt);
00963     };
00964     // set canvas size
00965     if(newWidth>0 && newHeight>0)
00966     {
00967         HuginBase::PanoramaOptions opt = pano.getOptions();
00968         opt.setWidth(newWidth);
00969         opt.setHeight(newHeight);
00970         std::cout << "Setting canvas size to " << opt.getWidth() << " x " << opt.getHeight() << std::endl;
00971         pano.setOptions(opt);
00972     };
00973     // auto crop
00974     if(doAutocrop)
00975     {
00976         std::cout << "Searching for best crop rectangle" << std::endl;
00977         AppBase::DummyProgressDisplay dummy;
00978         HuginBase::CalculateOptimalROI cropPano(pano, &dummy);
00979         if(autocropHDR)
00980         {
00981             cropPano.setStacks(getHDRStacks(pano,pano.getActiveImages(), pano.getOptions()));
00982         }
00983         cropPano.run();
00984 
00985         vigra::Rect2D roi=cropPano.getResultOptimalROI();
00986         HuginBase::PanoramaOptions opt = pano.getOptions();
00987         //set the ROI - fail if the right/bottom is zero, meaning all zero
00988         if(!roi.isEmpty())
00989         {
00990             opt.setROI(roi);
00991             std::cout << "Set crop size to " << roi.left() << "," << roi.top() << "," << roi.right() << "," << roi.bottom() << std::endl;
00992             pano.setOptions(opt);
00993         }
00994         else
00995         {
00996             std::cout << "Could not find best crop rectangle" << std::endl;
00997         }
00998     };
00999     //setting crop rectangle manually
01000     if(newROI.right() != 0 && newROI.bottom() != 0)
01001     {
01002         HuginBase::PanoramaOptions opt = pano.getOptions();
01003         opt.setROI(newROI);
01004         std::cout << "Set crop size to " << newROI.left() << "," << newROI.right() << "," << newROI.top() << "," << newROI.bottom() << std::endl;
01005         pano.setOptions(opt);
01006     };
01007     //setting interpolation method
01008     if (interpolation>=0)
01009     {
01010         HuginBase::PanoramaOptions opt = pano.getOptions();
01011         opt.interpolator = static_cast<vigra_ext::Interpolator>(interpolation);
01012         std::cout << "Set interpolation method to " << interpolation << std::endl;
01013         pano.setOptions(opt);
01014     };
01015 
01016     //write output
01017     HuginBase::OptimizeVector optvec = pano.getOptimizeVector();
01018     HuginBase::UIntSet imgs;
01019     fill_set(imgs,0, pano.getNrOfImages()-1);
01020     // Set output .pto filename if not given
01021     if (output=="")
01022     {
01023         output=input.substr(0,input.length()-4).append("_mod.pto");
01024     }
01025     std::ofstream of(output.c_str());
01026     pano.printPanoramaScript(of, optvec, pano.getOptions(), imgs, false, hugin_utils::getPathPrefix(input));
01027 
01028     std::cout << std::endl << "Written output to " << output << std::endl;
01029     return 0;
01030 }

Generated on 20 Apr 2018 for Hugintrunk by  doxygen 1.4.7