Command line tool
How to use
Soil-align application has a command line interface. If you launch it without arguments the following short help appears:
% soil-align
Abrupt ending of the input: argument #<ARGUMENT {11004A6423}> missing
Usage: soil-align [-v|--verbose] [-t|--threads N] [-w|--workspace-side S]
[-O|--transform-output m.npy] [-o|--output out.npy]
[--rotation-constraint AXIS] [-s|--scaling]
[-b|--background-color COLOR] [--dist-ratio C]
[--fit-error E] [--ransac-iterations M]
reference source
Description of flags and options
--ransac-iterations M Number of RANSAC iterations
--fit-error E The maximal allowed fit error to treat a sample as inlier
--dist-ratio C Controls what we consider a match
-b|--background-color COLOR Background color
-s|--scaling Add uniform scaling to the model
--rotation-constraint AXIS Constrain rotation to be around only one axis (0, 1 or 2)
-o|--output out.npy Output file name for a transformed image (.npy or .raw)
-O|--transform-output m.npy Output file name for a transform matrix (.npy)
-w|--workspace-side S Side of a workspace which is cut from center of the input images
-t|--threads N Number of threads to use
-v|--verbose Be verbose
Two mandatory arguments reference and source are two input
images. Soil-align will try to bring a source image into a reference'
coordinate system and write a result image (if -o option is specified)
and/or write a transform matrix (if -O option is specified). The
transform matrix is 4×4 matrix in Numpy format which when left-multiplied by
an augmented coordinate vector \((x, y, z, 1)^T\) in the reference'
coordinate system produces a coordinate vector \((x', y', z', 1)^T\) in the
source' coordinate system.
Here we discuss not-so-important options:
-v— Be more verbose-t— Number of threads. Used when computing image feature points and matching descriptors. On FreeBSD platform the default is a half of available cores, but no more than 10. On other platforms the default is 1.-w— Used to crop a big input image. When not specified the whole image is used to compute feature points. When specified, a window of this side is cut from the center of an image. Feature points are only found in this window--rotation-constraint— When finding a transform between the reference' and source' coordinate systems constrain possible rotations, so only a rotation around this axis (0, 1 or 2) is allowed. When not specified, all rotations are allowed. Numeration of axes is in row-major order (i.e. if an arraya[i, j ,k]is a pixel in your image, theniis the 0th index,jis the 1st index andkis the 3rd index)-s— Allow scaling (assume the images are of different resolution) when finding a transform between the reference' and source' coordinate systems. This feature is experimental and is turned off by default.-b— What color to use for out-of-bounds array access. Used to produce the resulting image. Can range from 0 to 255.--dist-ratio— Feature points are matched using 2-nearest neighbors according to Euclidean distance between corresponding descriptors. Two points \(p_{ref}\) and \(p_{src}\) match if \(d \rho(p_{ref}, p_{src}) < \rho(p_{ref}, p'_{src})\). Here \(p'_{src}\) is the second-nearest feature point and \(d\) is the distance ratio. The default value is 1.2--fit-error— A parameter used in the RANSAC algorithm to determine if a model fits a point. The default value is 100.0--ransac-iterations— A number of RANSAC iterations to find a model which fits the feature points. The default value is 5000.
Soil-align utilises LMDB to store image descriptors. The DB is written at
~/.local/share/soil-align/ by default, but the path can be overwritten
with SOIL_ALIGN_DB environment variable. The DB accelerates registration
within the same dataset. After working with the dataset it's recommended to
manually remove the database. No DB pruning or what else to reduce the DB
size is implemented at the moment.
Output explained
A typical output of soil-align when being run with -v option is the
following:
<INFO> [15:01:00] soil-align/cli cli.lisp (top level form %main) - Starting
<INFO> [15:01:00] soil-align/cli cli.lisp (top level form %main) -
Will use 6 threads
<INFO> [15:17:13] soil-align/cli cli.lisp (top level form %main log-eval) -
SOIL-ALIGN/CLI::MESSAGE: "Got descriptors of the source image"
<INFO> [15:34:03] soil-align/cli cli.lisp (top level form %main log-eval) -
SOIL-ALIGN/CLI::MESSAGE: "Got descriptors of the reference image"
<INFO> [15:36:00] soil-align/cli cli.lisp (top level form %main) -
Found matches between images
<INFO> [15:36:00] soil-align/cli cli.lisp (top level form %main) -
Found a transform matrix
<INFO> [15:36:12] soil-align/cli cli.lisp (top level form %main log-eval) -
SOIL-ALIGN/CLI::MESSAGE: "Computed a transformed image"
<INFO> [15:36:12] soil-align/cli cli.lisp (top level form %main) -
Summary: 281390/300000 descriptors, 379 independent parameters, 996 matches, 842 inliers, 805.0559 fit error
As you can see it took 35 minutes to process a pair of images. In this example a workspace size of 800 were used. Each image contains about 300000 feature points but there are only 996 matches between images. This is because there was a process of drying between the images which changed the structure of the porous medium. Nevertheless soil-align was able to register the images. It constructed a transform which fitted 842 descriptors with total error of 805 (the error is computed as \(\sqrt{\sum_i |T(x_i) - y_i|^2}\)) where \(x_i\) is a coordinate of a feature point on the source image, \(y_i\) is a coordinate of a feature point on the reference image and \(T\) is a transform between source and reference coordinate systems.
If you run soil-align again with the same reference image, the execution time is reduced to 17 minutes due to use of LMDB.
<INFO> [15:59:34] soil-align/cli cli.lisp (top level form %main) - Starting
<INFO> [15:59:34] soil-align/cli cli.lisp (top level form %main) -
Will use 6 threads
<INFO> [16:15:09] soil-align/cli cli.lisp (top level form %main log-eval) -
SOIL-ALIGN/CLI::MESSAGE: "Got descriptors of the source image"
<INFO> [16:15:16] soil-align/cli cli.lisp (top level form %main log-eval) -
SOIL-ALIGN/CLI::MESSAGE: "Got descriptors of the reference image"
<INFO> [16:17:00] soil-align/cli cli.lisp (top level form %main) -
Found matches between images
<INFO> [16:17:02] soil-align/cli cli.lisp (top level form %main) -
Found a transform matrix
<INFO> [16:17:13] soil-align/cli cli.lisp (top level form %main log-eval) -
SOIL-ALIGN/CLI::MESSAGE: "Computed a transformed image"
<INFO> [16:17:14] soil-align/cli cli.lisp (top level form %main) -
Summary: 251890/300000 descriptors, 379 independent parameters, 2025 matches,
1868 inliers, 1068.2292 fit error
Supported formats
- Numpy arrays (.npy files). These arrays must have rank 3 and dtype 'uint8'. Elements of an array encode pixel intensity at the point.
- Multipage TIFF images. Each image in a multipage file must have the
same dimensions. Multipage images can be easily created and split into
multiple one-page tiff images with
tiffcpandtiffsplitcommand line tools shipped with libtiff. - Raw files (not recommended!)
To use raw files (once again: not recommended!) you need to create a metadata
file with extension s-exp for each input file. It contents should be:
(quoted-name-of-raw-file dim-x dim-y dim-z)
for example
("foo.raw" 1000 1000 600)
It is expected that raw file has its content in row-major order with one unsigned octet per voxel. For output files you don't need metadata (dimensions of the output = dimensions of the source).