Batch and scripting
Batch covers the splitting rules themselves, which are the same in the browser and on the command line. This page is about driving them from a shell.
Directories as inputs
A directory among the inputs stands for the image files in it — PNG, JPEG, TIFF — in natural
order, so f2 sorts before f10 rather than after it.
lapstack -o stacked.tif shoot/subject-01/That alone is often enough: one folder, one stack.
Splitting
# every 30 frames
lapstack --split count:30 -o out.tif shoot/
# a new stack wherever the capture times jump by more than 10 seconds
lapstack --split gap:10 -o '{first}_stacked.tif' shoot/
# one stack per folder
lapstack --split dir -o '{dir}/stacked.tif' shoot/*/gap is the one for a rail: the rail shoots every second or two and the pause while you change
subjects is tens of seconds, so the capture times mark the boundaries themselves.
Times come from EXIF DateTimeOriginal, then DateTimeDigitized, then DateTime, then the XMP packet's CreateDate. A frame with none of those falls back to its file's modification time and says so.
Always dry-run first
lapstack --split gap:10 --dry-run shoot/This prints the stacks it would make — their frames, their output names, and for a gap split
the capture times and the pause before each — and stops.
It costs almost nothing: only the head of each file is read, or for a TIFF whose IFD follows the pixels, a window around that IFD. A hundred frames of 274 MB each take about 0.2 s.
Run it before hours of stacking. It is the only way to see whether the split is what you meant.
Output templates
With more than one stack, -o, --slab-dir, --save-aligned and --depth-raw become
templates:
| Field | Becomes |
|---|---|
{n} | The stack's number |
{first} | Its first frame's file name, without extension |
{dir} | Its folder's name |
A path with no field gets _NN inserted before its extension, so -o out.tif gives
out_01.tif, out_02.tif, … A folder a template names is created. Every other output — depth,
slabs, stereo, rocking, model — follows the stem as always.
Quote templates in the shell. {first} and {n} mean nothing to the shell, but
brace expansion and globbing will happily mangle a path that contains other punctuation.
Skipping and reordering
--skip takes 1-based positions and ranges, counted after directories are expanded and
before any split:
lapstack --skip 1,2,47-50 -o stacked.tif shoot/Each skipped frame is reported. A position past the end, or a backward range, is an error — a typo should not silently stack the wrong frames.
--reverse turns the order round for a stack shot back to front, so frame 0 is the near end
again for --stereo and --mesh. With --split, each stack is reversed on its own, which is
what running a rail backward means for every stack of the batch.
Anything beyond that is the shell's job: the frames are stacked in the order they are given.
# stack in reverse filename order, without --reverse
lapstack -o stacked.tif $(ls -r shoot/*.tif)Exit status and failures
A stack that fails — frames of two sizes, a file that will not decode — is reported, and the
batch goes on. At the end there is a summary and the exit status is 1 if anything failed,
0 otherwise.
if ! lapstack --split dir -o '{dir}/stacked.tif' shoot/*/; then
echo "at least one stack failed; see the log above" >&2
fiA shell loop instead
When each subject needs different settings, a loop is clearer than a split:
for d in shoot/*/; do
name=$(basename "$d")
lapstack --align-coarsen 2 --halo-control 2 --save-depth \
-o "out/${name}.tif" "$d" \
|| echo "failed: $name" >> out/failures.txt
doneDrafting a whole batch
lapstack --split dir --draft 2 -o 'draft/{dir}.tif' shoot/*/Every stack at a sixteenth of the pixels. Look at the drafts, fix whatever is wrong, then run the batch for real. This is worth doing every time the capture setup changes.
Joining rocking views by hand
--video FPS calls ffmpeg for you when it is on the path. When it is not, lapstack prints the
command it would have run. It looks like this:
lapstack --rocking 3:24 -o stacked.tif shoot/
ffmpeg -framerate 24 -i stacked_rocking/view_%02d.tif \
-c:v libx264 -crf 18 -pix_fmt yuv420p stacked_rocking.mp4The rocking sweep is one sine cycle, so the video loops seamlessly with no extra work.
Memory and long runs
Frames stream through the alignment and the fusion one at a time, so neither the number of frames nor the number of stacks drives memory — stacks run in turn, and memory stays that of one stack. What grows with stack length is the depth pass's focus slices, about 45 MB per 45-megapixel frame on the default half grid.
See performance for measured numbers.