Panorama scripting in a nutshell

From PanoTools.org Wiki

This is a short document describing the various Open Source tools and techniques available for working with panoramas in a non-GUI environment. The examples are based on Linux experience, but most of them should work on OS X or Windows with minor modifications at most.

This document is also useful for understanding what happens 'under the hood' in hugin itself and recommended reading for anyone looking to work with the hugin sourcecode.

Why would you do that?

Creating and manipulating panoramas is something that should obviously be done in a graphical tool[*]. This is true, but perhaps you find that you are spending more time operating a computer than being a photographer. This is an indication that something is wrong - The computer exists to do the boring work and scripting is one way to make this happen.

PanoTools 'Scripting'

The file format first used in Helmut Dersch's Panorama tools is often referred to as a 'script', but a 'PanoTools' script is really a data file describing a 'panorama stitching project'.

Although these original PanoTools are less used today, the file format is alive and well with several variations used as project files by PTGui[*], PTAssembler[*], hugin and related tools. These files are simple plain-text, sometimes it is useful to modify them directly with a text editor - Further on we will introduce various methods for manipulating them via the 'programming' kind of scripts.

Simple command-line stitching

Lets start with a basic but common use case: Photographers with quality panoramic tripod heads[*] can reproduce identical sets of photos every time, in this situation there is no need to create a new stitching project for every panorama, it is enough to use a single project as a template.

This example takes a pre-existing project called template.pto, created with three photos. It uses nona for remapping, and enblend for blending the remapped photos into a finished TIFF image:

 nona -o out -m TIFF_m template.pto DSC_1234.JPG DSC_1235.JPG DSC_1236.JPG
 enblend -o finished.tif out0000.tif out0001.tif out0002.tif

The first nona command creates three remapped TIFF images called out0000.tif, out0001.tif etc... the list of input images can be substituted with any set of identically sized photos. The second enblend command uses these TIFF files as input and merges them to a file called finished.tif. template.pto

If the internal blender is used, the commands simplify to

 nona -o out -m TIFF template.pto DSC_1234.JPG DSC_1235.JPG DSC_1236.JPG

Creating hugin projects on the command-line

The entire panorama creation process can be performed on the command-line, and therefore scripted, doing this involves a series of steps similar to the workflow in a GUI tool.

Generating the project file

Most of hugin tools take a pto file as input and output. So the first step is to create this pto file. For this purpose use pto_gen.

  pto_gen *.jpg

will put all jpg files in the current directory into one project file with a default name. You can also specify single images and your own project name

  pto_gen -o project.pto image1.jpg image2.jpg image3.jpg

You can specify more options to the project (see pto_gen for details).

Generating control points

There are a number of tools available for generating control points from groups of photos, like cpfind. Here is an example using cpfind

  cpfind --multirow -o project.pto project.pto

Hint: Other control points generator, such as autopano-sift, autopano-sift-c[*], panomatic and match-n-shift[*] take a list of images instead of a project. In this case the pto generation and control point generation are one step. Here is an example for autopano-sift-c:

 autopano-sift-c --projection 0,50 project.pto DSC_1234.JPG DSC_1235.JPG DSC_1236.JPG

This will create a .pto project with control points (if any) linking the three photos, note that the projection format (f0, rectilinear) of the input photos and approximate horizontal angle of view (v50, 50 degrees) have to be specified.

Pruning control points

This still isn't a finished panorama, at the very least this involves optimising the camera positions and then rendering the output.

You could go ahead and optimise this project file straight away, but this can be a bit hit and miss. First it is a good idea to clean up the control points. There are currently two useful tools for cleaning control points: celeste removes points from areas of sky and cpclean removes points with large error distances, first celeste_standalone:

 celeste_standalone -i project.pto -o project.pto

Then cpclean:

 cpclean -o project.pto project.pto

Note that in both cases we are overwriting the input project.pto file with the cleaned output. If you want you can create intermediate temporary files and keep each step in case you need to backtrack.

Other control point cleaners are ptscluster[*] and ptoclean. cpclean has largely replaced ptoclean, but you could still run it like this:

 ptoclean -v --output project.pto project.pto


Optimising positions and geometry

Up to now, the project file simply contains an image list and control points, the images are not yet aligned, you can do this by optimising geometric parameters with the autooptimiser tool:

 autooptimiser -a -l -s -o project.pto project.pto

Now you could just skip ahead and render the output if photometric optimisation isn't required.

By adding the -m switch also photometric optimisation is done. So the output project is optimised for positions, geometry and photometric parameters in one run:

 autooptimiser -a -l -s -m -o project.pto project.pto

If you need finer control above the optimisation, set the parameter which should be optimized with pto_var and then run autooptimiser with switch -n:

 pto_var --opt y,p,r -o project.pto project.pto
 autooptimiser -n -o project.pto project.pto

(PToptimizer[*] is an alternative geometrical optimiser)

Optimising photometric parameters

Photos have photometric exposure variables which can be optimised in much the same way as aligning positions. Doing this can remove brightness, white balance and vignetting differences between photos, giving better blending or allowing creation of HDR images.

For doing an automatic photometric optimisation like Hugin's assistant, run autooptimiser with -m switch:

 autooptimiser -m -o project.pto project.pto

For full manual control for photometric parameters use vig_optimize. This program does the equivalent job for photometric parameters as autooptimiser does for geometric parameters. You need to indicate in the .pto project which parameters are 'variables'. For this task you can edit the .pto file or use a tool such as pto_var or ptovariable[*]:

 ptovariable --vignetting --response --exposure project.pto
 vig_optimize -o project.pto project.pto
 pto_var --opt Vb,Vx,Ra,EeV -o project.pto project.pto
 vig_optimize -o project.pto project.pto

Setting output options

For setting the output option (like on the stitcher tab) use pano_modify:

   pano_modify -o project.pto --center --straighten --canvas=AUTO --crop=AUTO project.pto

This command will straighten the pano, center it on the canvas, calculates the optimal size and calculates the optimal output region.

Example work flow similar to assistant in Hugin GUI

Hugins assistant can also be used from the command line

   hugin_executor --assistant project.pto

Or you can also put the task into PTBatcherGUI queue

   PTBatcherGUI --assistant project.pto

In the following the single steps of the assistant are described. We will use the same project file for all single steps. We always overwrite the same project file. You can also use another filename for every step.

1) Generate pto file

    pto_gen -o project.pto *.jpg

2) Find control points with cpfind, with celeste to ignore clouds

    cpfind -o project.pto --multirow --celeste project.pto

3) Control point cleaning

    cpclean -o project.pto project.pto

4) Find vertical lines

    linefind -o project.pto project.pto

5) Optimize position, do photometric optimization, straighten panorama and select suitable output projection

    autooptimiser -a -m -l -s -o project.pto project.pto

6) Calculate optimal crop and optimal size

    pano_modify --canvas=AUTO --crop=AUTO -o project.pto project.pto

7) Now create output

    hugin_executor --stitching --prefix=prefix project.pto

Stitching hugin projects on the command-line

The stitching option of hugin_executor can be broken apart into separate command lines.

The simplest case is remapping and blending.

Remapping (Rendering) images

The hugin tool for remapping and distorting the photos into the final panorama frame is nona, it uses the .pto project file as a set of instructions:

 nona -m TIFF_m -o project project.pto

This nona command creates one remapped TIFF image for each of the input photos, these will be named project0000.tif, project0001.tif, project0002.tif etc...

(PTblender is an alternative renderer to nona)

Blending

nona can do rudimentary assembly of the remapped images, but a much better tool for this is enblend, feed it the images, it will pick seam lines and blend the overlapping areas:

 enblend -o project.tif project0000.tif project0001.tif project0002.tif ...

Finally this produces the stitched panorama: project.tif

Holding it all together with panostart

The .pto.mk Makefile helps with the stitching at the end of the process, but doesn't help with the bits at the beginning such as: identifying which photos go in which panorama, generating control points, pruning and optimising.

panostart[*] is a prototype tool that does it all. Given a list of photos in a folder, it identifies likely panoramas by comparing EXIF timestamps and writes a meta-Makefile containing: rules for generating .pto projects with match-n-shift[*], rules for generating corresponding .pto.mk Makefiles with pto2mk[*], rules for stitching the projects with make, plus some other rules for creating useful distributable output.

A typical panostart[*] command for dealing with a folder full of photos taken with a pocket point-and-shoot camera on auto-exposure might look like this:

 panostart --output Makefile --projection 0 --fov 50 --nostacks --loquacious *.JPG

Processing this Makefile is simple:

 make

Some of the resulting panoramas will have position, cropping and stitching errors. Fix these by editing the relevant .pto projects in hugin or another tool, when you type make again on the command-line, only those projects that have changed will be restitched.

Another advantage of doing things this way is reproducibility: delete all the (enormous) TIFF output panoramas and all you need to keep permanently are the photos, the meta-Makefile and the associated .pto projects. If you ever need to recreate the TIFF panoramas in the future, just type make. If you know the name of the TIFF file you want, just type 'make project.tif' and only a single panorama will be processed.

Panotools::Script for manipulating project files

The name is a historical mistake, Panotools::Script[*] is a perl library for working with hugin .pto projects, though it could be extended in the future to cover any of the related file formats. Many of the command-line tools described in this document are written with this library.

Here is a trivial script, all it does is open and save a .pto project, it also resets the output ('p' Panorama line) angle of view to 360 degrees (v360), the projection format to equirectangular (f2) and the output pixel size to 4096x2048 pixels (w4096 h2048):

 #!/usr/bin/perl
 use Panotools::Script;
 my $pto = new Panotools::Script;
 $pto->Read ($ARGV[0]);
 $pto->Panorama->Set (v => 360, f => 2, w => 4096, h = 2048);
 $pto->Write ($ARGV[0]);

Here's slightly more complex script, this iterates over the input images and increments the white balance making the panorama slightly 'warmer':

 #!/usr/bin/perl
 use Panotools::Script;
 my $pto = new Panotools::Script;
 $pto->Read ($ARGV[0]);
 for my $image (@{$pto->Image})
 {
     my $Er_new = $image->{Er} * 100 / 95; # red value
     my $Eb_new = $image->{Eb} * 95 / 100; # blue value
     $image->Set (Er => $Er_new, Eb => $Eb_new);
 }
 $pto->Write ($ARGV[0]);

Full list of command-line tools

Control point generation

  • cpfind - Hugins own control point detector
  • autopano-sift-c[*] - All in one keypoint generator and matcher
  • match-n-shift[*] - All in one wrapper around align_image_stack and autopano-sift-c[*]
  • panomatic - All in one alternative to autopano-sift-c[*]
  • align_image_stack - Generates control points for stacked photos
  • ptoanchor - add control points to a Hugin project
  • ptochain - add control points to a Hugin project between consecutive photos
  • ptobind - Join the ends of linked photos in a Hugin project
  • ptofill - add control points to a Hugin project between likely overlapping photos
  • generatekeys - Keypoint generator
  • autopano - Keypoint matcher, part of autopano-sift-c[*] and not to be confused with autopano

Project file modification

  • pto_gen - Generates a new pto project from image files
  • match-n-shift[*] - (see above) Default usage is to initialise a new .pto project from EXIF data
  • ptoset - Change global parameters and project options
  • ptovariable[*] - Set typical optimisation variables
  • pto_var - Manipulate image variable, can also set optimisation variables
  • pto_lensstack - Manipulate lenses and stacks
  • pto_mask - Add mask to project file
  • pto_template - Apply template to project file
  • ptsed - Set any project parameter, convert .pto into PanoTools format
  • ptosort[*] - Sort control points or images, remove duplicate control points
  • ptopath - Remove file paths in project files
  • transform-pano[*] - Roll, pitch and yaw rotation of .pto projects
  • ptocentre - Rotate projects to put images in panorama centre
  • pano_modify Change output parameters of project file
  • ptomerge[*] - Join two or more projects
  • pto_merge Merges two or more Hugin project files (this is a different tool to ptomerge above)
  • ptosplit[*] - Extract subsets of images from a project into a new project

Control point pruning

Optimisation

Rendering

  • nona - Default hugin rendering engine
  • nona-mask[*] - Wrapper around nona for using external bitmap masks
  • PTmender - Render PanoTools format projects
  • PTAInterpolate[*] - Create intermediate images from PanoTools projects

Blending

  • enblend - Merge partially overlapping images with multiresolution splines
  • verdandi - Merge partially overlapping images with watershed algorithm
  • enfuse - Merge overlapping images with exposure fusion
  • PTroller - Merge partially overlapping images with no seaming
  • PTmasker - Compute stitching masks for input by PTroller
  • enblend-mask - Wrapper around enblend for using external bitmap masks
  • enfuse-mask - Wrapper around enfuse for using external bitmap masks
  • deghosting_mask - Creates mask for removing ghosting in images
  • hugin_hdrmerge - Merge bracketed images for HDR generation
  • enblend-svg - Wrapper around enblend for specifying input images via SVG files
  • process-masks - Allow 'positive' masking in external masks for enblend
  • tif2svg - Assemble multiple TIFF images into SVG files for enblend-svg
  • PTblender - Correct colour and brightness of overlapping images

Misc

  • panostart[*] - All-in-one panorama workflow via Makefiles
  • gigastart - All-in-one assembly of multi-row panoramas
  • hugin_executor - Stitch project or run assistant from command line
  • gigatile[*] - Create a Makefile for stitching a project as multi-resolution tiles
  • ptodummy[*] - Generate missing input photos to debug .pto projects
  • calibrate_lens[*] - Automatic lens calibration using straight-line detection
  • pafextract[*] - Tool to use panoglview as a zenith and nadir editor[*]

Chromatic aberration

Querying

  • ptograph - Draw undirected graphs of projects
  • ptoget - Query any project parameter
  • ptoinfo - Generate a report on a project file
  • PTinfo - Display info about a panotools generated TIFF file
  • panoinfo - Display information about installed libpano13[*] library
  • pano_trafo - transform between image and panorama coordinates (and vice versa)

TIFF files

  • PTtiff2psd - Join multiple TIFF images into a multilayer PSD file
  • PTtiffdump - Compare two TIFF files
  • PTcrop - Remove unwanted empty space in TIFF files and replace with offsets
  • PTuncrop - Replace offsets in TIFF files with empty pixels

Output formats

  • erect2cubic - Create a .pto project for extracting cube faces from an equirectangular image
  • erect2planet - Create a .pto project for extracting a 'little planet' from an equirectangular image
  • erect2mercator - Create a .pto project for extracting a mercator view from an equirectangular image

Older tools

Helmut Dersch's PTOptimizer and PTStitcher were the original command-line tools. These are not really recommendable any more as they require an older, buggier version of the libpano12[*] library, they are closed source so don't work on modern systems such as OS X or 64bit Linux, and are lacking in features compared to modern replacements such as autooptimiser and nona.

Useful Image processing tools

  • ImageMagick[*] - Many utilities for converting, manipulating and resizing images
  • GraphicsMagick - A fork of ImageMagick with many improvements
  • libtiff - Supplied with useful tools such as tiffcp for joining and recompression, and tifficc for adding ICC colour profiles
  • exiftool[*] - All purpose reading, setting and copying of EXIF data
  • exiv2 - EXIF manipulation, useful for setting the file modification date from the EXIF date
  • jpegtran - Lossless rotation of JPEG images
  • ufraw-batch - Command-line RAW processing
  • dcraw[*] - Command-line RAW processing