Panotools::Script(3)

πŸ“¦
version 0.29 Β· 2 versions
, in fedora 43

πŸ’– Panotools::Script πŸ’–

okay bestie, welcome to Panotools::Script β€” it's the Perl module for Panorama Tools scripting, and no cap it is lowkey iconic πŸ’…


✨ NAME ✨

Panotools::Script β€” Panorama Tools scripting πŸŽ€


🌸 SYNOPSIS 🌸

Read, write and manipulate hugin script files. that's the whole vibe. periodt.


πŸ¦‹ DESCRIPTION πŸ¦‹

So like, this is a library and utilities for manipulating project files created by the hugin photo stitching software ✨

This file format is shared with various other tools, fr fr β€” in particular, this module is also capable of working with Panorama Tools script files. like, it's bilingual, it's giving main character energy πŸ‘‘


πŸ’œ USAGE πŸ’œ

Okay so first things first, you make yourself a new script object:

my $p = new Panotools::Script;

Then you read stuff in:

$p->Read ('/path/to/script.txt');

And you write stuff out:

$p->Write ('/path/to/script.txt');

heads up bestie 🫢 File paths in a Panorama Tools script file are generally relative to the directory containing the script. So if you wanna modify that, or otherwise prefix the filenames, you supply an optional second argument like this:

$p->Write ('/path/to/script.txt', '../path/to/prefix/tofiles');

Wanna clone a script object? Say less πŸ’…

$clone = $p->Clone;

πŸŽ€ Accessing sections of the scriptfile πŸŽ€

You can grab all the various sections like so:

$p->Mode;          # a L<Panotools::Script::Line::Mode> object
$p->Panorama;      # a L<Panotools::Script::Line::Panorama> object
$p->Variable;      # a L<Panotools::Script::Line::Variable> object

$p->Image;         # an array of L<Panotools::Script::Line::Image> objects
$p->Output;        # an array of L<Panotools::Script::Line::Output> objects
$p->Control;       # an array of L<Panotools::Script::Line::Control> objects
$p->ControlMorph;  # an array of L<Panotools::Script::Line::ControlMorph> objects

🌈 Transforms and lines 🌈

Wanna rotate transform all the images in a project? Angles are in degrees:

$p->Transform ($roll, $pitch, $yaw);

So the tea on the line types β˜• β€” 'o' output lines are generated by PTOptimizer and contain stitching parameters for each input image. Meanwhile 'i' image lines provide parameters for optimisation as well as stitching.

Update the 'image' lines based on 'output' lines and vice-versa like so:

$p->Output2Image;
$p->Image2Output;

πŸ’… Cleaning up control points πŸ’…

Remove duplicate control points from the project, returns a list of deleted points:

my $deleted = $p->Duplicates;

Remove all points with an error distance greater than a threshold measured in pixels, returns a list of deleted points:

my $pruned = $p->Prune (12.345);

πŸ“ Subsets πŸ“

Extract a new object consisting of just the requested images, related control points and optimisation settings:

my $subset = $p->Subset (1, 2, 34, 56);

Images can be requested in any order, but they will be returned in the same order as the 'parent' project. iykyk 😌

🧚 Merging 🧚

Merge a project with another:

$p->Merge ($newstuff);

This adds extra images from $newstuff, skipping duplicates. All control points except exact duplicates are imported regardless.

⭐ Stats ⭐

Get a summary of control point error distances in pixel units scaled to the output panorama:

my ($total, $min, $max, $average, $sigma) = $p->Stats;

πŸ’– Centring πŸ’–

Centre input images into the final panorama:

 $p->Centre ('y');
 $p->Centre ('p');
 $p->Centre ('r');

πŸ‘‘ Stacks and layers πŸ‘‘

Split the project into exposure stacks based in roll, pitch & yaw, or into exposure layers based on EV values:

$stacks = $pto->Stacks;
$layers = $pto->ExposureLayers;

Returns a list of image number lists. e.g. extract the first stack as a new project:

$pto_stack = $pto->Subset (@{$pto->Stacks->[0]});

Split a project into exposure layers, returns a list of lists of image ids:

my $layers = $pto->ExposureLayers (1.0);

Deafults to 0.5EV difference threshold. (yes bestie that's a typo in the original and I am respecting it, we don't touch the source material πŸ™ˆ)

🌸 Groups and connections 🌸

Get a list of unconnected groups, i.e. a list of image id lists:

$groups = $pto->ConnectedGroups;

warn 'just one group' if scalar @{$groups} == 1;

Count the connections between any two images:

$points = $pto->Connections (3, 5);

πŸ¦‹ Lens stuff πŸ¦‹

Given a project with unlinked lens parameters, link them together with the same lens number if all distortion, and photometric parameters match:

$pto->UnifyLenses;

Given a project with stacks indicated by 'j' parameters, hard-link the positions (only recognised by Hugin with layout mode code).

$pto->LinkStacks;

πŸŽ€ Angles and widths πŸŽ€

Return the angular distance in degrees between two images:

$deg = $pto->AngularDistance (3, 5);

Look at all photos and calculate an optimal pixel width for this panorama, optionally supply a scaling factor:

$width = $pto->OptimalWidth (0.7);

This number is rounded up to the nearest multiple of 16 pixels. slay ✨

πŸ”₯ pano_trafo energy πŸ”₯

Hugin ships with a tool called pano_trafo for querying the forward and reverse transform for pixel coordinates in a PTO project.

Initialise this as a service β€” it spawns two pano_trafo processes which are only killed when the perl process finishes:

$pto->InitTrafo ('/path/to/project.pto');
⚠️ bestie listen β€” this is very unlikely to work on non-unixy systems. πŸ’€

Query the forward transform like so:

($X, $Y) = $pto->Trafo ($image_no, $x, $y);

Query the reverse transform like so:

($x, $y) = $pto->TrafoReverse ($image_no, $X, $Y);

Copyright (c) 2001 Bruno Postle <bruno@postle.net>. All Rights Reserved.

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This software is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this software; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA


and that's the whole page bestie 🫢 this was perl v5.42.0, dated 2025-07-25, and it's the Panotools::Script(3) man page β€” go stitch something gorgeous, you absolute icon πŸ’–βœ¨πŸŽ€

πŸ“¦ where this page comes from