z-stackr

z-stackr-cli · binary z-stackr

The command line

One folder of frames in, one image out, for batch work, scripts and stacks larger than memory.

01Usage

terminal
z-stackr --input-dir ./frames --output-file ./result/stacked.tif --mode apex --tile-size 512
ArgumentMeaning
--input-dir <DIR>Required. The folder with the frames (.jpg, .jpeg, .png, .tif, .tiff, any letter case; camera RAW files in a build with the raw feature), used in natural file-name order; the first is the alignment reference. The output and log files are never read as frames. See --stacks for a folder with subfolders.
--output-file <FILE>Required. The extension picks the format (.png, .tif/.tiff, .jpg/.jpeg); without one, image_saving.output_format decides. PNG and TIFF are 16 bit unless bit_depth = 8. The path is checked before the first frame is decoded. With --mode both or all each method writes its own file, _<method> before the extension: result.png becomes result_relief.png, result_apex.png and, for all, result_strata.png. No file is written under the plain name.
--mode <MODE>Required, in any letter case. apex (Laplacian pyramid), relief (depth map), strata (guided fusion), both (Relief and Apex) or all (Strata, Relief and Apex). both and all align once and fuse the same tile store once per method. Older mode names still work and are logged as renamed.
--tile-size <SIZE>Required. At least 64; 512 is a good value. For Apex it is rounded up to a multiple of 2^(pyramid_levels - 1). Larger tiles lower the overlap overhead. With both and all the tiles are stored once, with the largest apron any of the methods needs.
--optimizer <auto|lk|nm>Optional. The alignment optimizer for this run: auto (Lucas-Kanade, the Nelder-Mead simplex as fallback), lk (Lucas-Kanade only) or nm (simplex only). Overrides optimizer in the settings file; the file is not written back.
--stacks <subfolders|single>Optional. When --input-dir has subfolders that hold frames: subfolders stacks each one on its own and makes --output-file an output folder, with one file per subfolder named by filename_template; single stacks only the images directly in the folder. A failing stack is reported and the others still run. Without the flag a terminal is asked; without a terminal the run stops and asks for it. Not combinable with --monitor in subfolders mode.
--no-gpuOptional; in builds with the gpu feature. Keeps this run on the CPU whatever compute_device says; the same as compute_device = "cpu".
--config <FILE>A settings file (the format the desktop app writes). It must exist and parse: a mistake stops the run instead of silently using defaults.
--write-default-configWith --config: create a missing file with commented defaults first.
--monitorKeep watching --input-dir and stack again when a frame is added or changed.
--log-file <FILE>Also write the structured log to this file.

02The settings file

The command-line tool and the desktop app read and write one TOML format with 39 keys, and every key reaches both. The 38 that apply to the builds described on this site are listed below, with settings_version first. Pass --config settings.toml --write-default-config once to get a commented file with every default.

KeyDefaultValues and effect
settings_version2written by the programs; a file without it is read as a legacy file and migrated (see below)
alignment_mode"registration"translation (shift and uniform scale), registration (shift, scale, rotation), affine (all 6 parameters) or none; see alignment. Any letter case.
optimizer"auto"auto (Lucas-Kanade, the simplex as fallback), lucaskanade or neldermead; lk and nm are accepted. --optimizer overrides it
bounded_searchfalsekeep the search in a band around the start
akaze_seedingfalseseed from feature matches (builds with akaze)
correct_brightnesstruematch each aligned frame's brightness to the reference, in linear light
chain_alignmentfalsealign every frame to its aligned predecessor instead of the first frame
crop_to_common_areatruecrop to the rectangle every frame covers
resize_cropped_to_originalfalsedesktop app: stretch a cropped result back to the original size; no effect in the command line
auto_culltrueleave out frames that add almost nothing
auto_cull_threshold_pct0.00.0 to 50.0, the share of the detail pixels a frame must win; 0 is the automatic rule min(2, 50 / N)
sort_by_sharpnessfalseorder the frames sharpest-first (the sharpest becomes the reference); the multigrid solver needs capture order
stack_every_nth1keep every Nth frame
tile_size0desktop app: out-of-core tile edge, 0 or 64 to 8192; the command line uses --tile-size, which always wins
pyramid_levels8Apex, 2 to 12
use_all_color_channelsfalselet color vote in Apex
grit_suppressiontrue3×3 winner in Apex's finest band
relief_estimation_radius50 to 100
relief_smoothing_radius20 to 50
relief_contrast_pct0.00.0 to 1.0, the fraction of pixels that take the mean
relief_show_previewfalsedesktop app: pause on the mask preview; no effect in the command line
relief_auto_detectfalsethreshold from the median and median absolute deviation of the focus scores
relief_use_multigridfalsesolve the depth as a smooth surface (see multigrid)
strata_base_radius31Strata, 8 to 64: the radius of the base/detail split
strata_detail_focus3Strata, 1 to 5: 1 soft, 5 close to winner-take-all
compute_device"cpu"cpu or gpu (see GPU)
[preprocessing] pre_rotation00, 90, 180 or 270, clockwise
pre_crop_enabledfalseapply the crop below
pre_crop_spec""crop to w,h (centred) or x,y,w,h
pre_resize_percent10010 to 100, Lanczos3
sort_reversefalsereverse the file order (the reference is then the other end)
ignore_exif_orientationfalseload JPEG pixels as stored
[image_saving] output_format"tiff"tiff, png, jpeg
bit_depth168 or 16 (JPEG is always 8)
jpeg_quality951 to 100
filename_template"{name}_stacked"used when --output-file is a folder; the command line knows {name}
default_output_dir""where a bare output file name goes
copy_metadatafalsecopy the first frame's EXIF block into a PNG or JPEG result (orientation set upright); a TIFF cannot carry it and one warning says so

A value out of range is clamped with a warning. The command line is strict about types (a wrongly typed value stops the run); the desktop app keeps the default for that key and shows a warning.

Older files still load. A file without settings_version is migrated so that it keeps its behavior; the details are in alignment. Saving always writes the current names.

03Memory and disk

The command-line tool stores every aligned frame on disk as padded tiles, so its memory does not depend on the image size and only weakly on the number of frames. Alignment holds about 39 bytes per pixel whatever the frame count (chain alignment adds 18); the fusion holds one padded tile of every frame.

The scratch folder takes 12 × ((T + 2A) / T)² bytes per source pixel per frame, where T is the tile size and A the apron:

MethodApron AScratch per pixel and frame at T = 512
Apex, 8 levels (default)512 px108 bytes
Apex, 6 levels128 px27 bytes
Strata101 pxabout 23 bytes
Relief, default radii10 pxabout 13 bytes

For example, 100 frames of 24 megapixels with Apex at 8 levels need about 260 GB of scratch disk; at 6 levels a quarter of that. The tool logs the figure before it starts, and removes the folder when the run ends, also after an error. With --mode both or all the tiles are stored once, with the largest apron of the methods in the run.

The fusion pass holds, for a padded tile of Q = (T + 2A)² pixels, N × 12 × Q bytes of frames plus about 96 × Q for Apex or 10 × Q for Relief. Strata holds 174 × Q whatever the number of frames, because it reads the frames on demand, two at a time. The next tile's frames are read ahead on a second thread, which costs another N × 12 × Q (nothing for Strata). The Relief multigrid solver adds whole-image planes of 6 bytes per pixel while it collects the votes and 28 while it solves. A stack held in memory by the desktop app needs 12 × N bytes per pixel plus about 84 for Apex, 62 for Relief (98 with multigrid) or 150 for Strata.

04Watching a folder

With --monitor the tool keeps running and stacks the folder again whenever a frame is added or changed, for example while a camera tethered to the computer is still shooting. With --mode both or all, the per-method result files next to the frames are never read as frames.