PLASTIMATCH(1)

๐Ÿ“ฆ
version 1.10.0 ยท 2 versions
, in debian trixie, ubuntu questing, ubuntu resolute

โœจ plastimatch ๐Ÿ’–

your girl is section 1 of the manual, and the manual's own name for her is literally just "Plastimatch" โ€” yes bestie, the whole page is named after the vibe ๐Ÿ’…


๐ŸŽ€ NAME

plastimatch โ€” register, convert, warp, and manipulate 3D images


๐Ÿฆ‹ SYNOPSIS

plastimatch command [options]

๐ŸŒธ DESCRIPTION

Okay so the plastimatch executable is the main character of a whole bunch of operations on 2D or 3D images. We're talking image registration, warping, resampling, and file format conversion. The shape of the options depends entirely on which command you asked for. Want the full roster of possible commands? Just type plastimatch with zero extra arguments and she'll spill the tea:

$ plastimatch
plastimatch version 1.10.0
Usage: plastimatch command [options]
Commands:
 add           adjust        average       bbox          boundary
 crop          compare       compose       convert       dice
 diff          dmap          dose          drr           dvh
 fdk          fill          filter        gamma         header
 intersect     jacobian      lm-warp       mabs          mask
 maximum       ml-convert    multiply      probe         register
 resample      scale         segment       sift          stats
 synth         synth-vf      threshold     thumbnail     union
 warp          wed           xf-convert    xf-invert

For detailed usage of a specific command, type:
  plastimatch command

๐Ÿ”ฅ PLASTIMATCH ADD

The add command adds one or more images together and makes an output image. Plot twist: you can weight the contributions of the input images with a weight vector. Queen behavior.

The command line usage goes a lil something like this:

Usage: plastimatch add [options] input_file [input_file ...]
Options:
  --average        produce an output file which is the average of the
                    input files (if no weights are specified), or
                    multiply the weights by 1/n
  --output <arg>   output image
  --weight <arg>   specify a vector of weights; the images are
                    multiplied by the weight prior to adding their
                    values

โœจ Examples

Say you wanna add 01.mha, 02.mha and 03.mha together and drop the result into output.mha โ€” literally just:

plastimatch add --output output.mha 01.mha 02.mha 03.mha

But if you wanted output.mha to be 2 * 01.mha + 0.5 * 02.mha + 0.1 * 03.mha, then bestie, you do this:

plastimatch add \
  --output output.mha \
  --weight "2 0.5 0.1" \
  01.mha 02.mha 03.mha

๐Ÿ’œ PLASTIMATCH ADJUST

The adjust command tweaks the intensity values inside an image. The adjustment operations on the menu are truncation, linear scaling, histogram matching, plus global and local linear matching. It's giving โœจoptionsโœจ.

Command line usage, incoming:

Usage: plastimatch adjust [options]
Options:
  -h, --help                    display this help message
      --hist-levels <arg>       number of histogram bins for histogram
                                 matching, default is 1024
      --hist-match <arg>        reference image for histogram matching
      --hist-points <arg>       number of match points for histogram matching,
                                 default is 10
      --hist-threshold          threshold at mean intensity (simple background
                                 exclusion) for histogram matching
      --input <arg>             input directory or filename
      --input-mask <arg>        input image mask, only affects --linear-match
                                 and --local-match
      --linear <arg>            shift and scale image intensities, provide a
                                 string with "<shift> <scale>"
      --linear-match <arg>      reference image for linear matching with mean
                                 and std
      --local-match <arg>       reference image for patch-wise shift and
                                 scale. You must specify the --patch-size
      --local-blending-off      no trilinear interpolation of shifts and
                                 scales
      --local-scale-out <arg>   filename to store pixel-wise scales
      --local-shift-out <arg>   filename to store pixel-wise shifts
      --output <arg>            output image
      --patch-size <arg>        patch size for local matching; provide 1 "n"
                                 or 3 values "nx ny nz"
      --pw-linear <arg>         a string that forms a piecewise linear map
                                 from input values to output values, of the
                                 form "in1,out1,in2,out2,..."
      --ref-mask <arg>          reference image mask, only affects
                                 --linear-match and --local-match
      --version                 display the program version

So here's the deal ๐Ÿ’ซ โ€” adjust can do a piecewise linear adjustment of your image intensities. The --pw-linear option builds that mapping from input intensities to output intensities. Rules of the road, no exceptions:

  • The input intensities in the curve must increase from left to right in the string. Non-negotiable, bestie.
  • The output intensities? Totally arbitrary. Go feral.
  • Input intensities below the first pair or after the last pair get transformed by extrapolating the curve out to infinity with a slope of +1.
  • Wanna pick a different slope out to positive or negative infinity? Specify the special input values -inf and +inf. In that case the second number in the pair is the slope of the curve, not the output intensity. iykyk.

You can also do a simplified linear transformation of gray levels with the --linear option โ€” for that you hand over a string with "<shift> <scale>".

Oh and you can also adjust intensities based on a reference image. With --linear-match, a linear transformation (shift and scale) is determined from the mean and standard deviation of pixel values in the reference and the input image. If your input image has local intensity inconsistencies, you can go patch-based with --local-match. Similar to --linear-match, shift and scale are computed patch-wise from mean and standard deviation. For both of those options you can provide masks that say which regions get taken into account. And finally, choose --hist-match to perform histogram matching. ๐ŸŽ€

โš ๏ธ You can only choose one of --linear, --pw-linear, --linear-match, --local-match and --hist-match. And beware โ€” a reference filename has to be added for the matching options. Pick one, bestie, she's not poly.

โœจ Examples

This one adds 100 to all voxels in the image:

plastimatch adjust \
  --input infile.nrrd \
  --output outfile.nrrd \
  --pw-linear "0,100"

Same energy, but now with the slope in the extrapolation area spelled out explicitly:

plastimatch adjust \
  --input infile.nrrd \
  --output outfile.nrrd \
  --pw-linear "-inf,1,0,100,inf,1"

This one truncates the inputs to the range of [-1000,+1000]:

plastimatch adjust \
  --input infile.nrrd \
  --output outfile.nrrd \
  --pw-linear "-inf,0,-1000,-1000,+1000,+1000,inf,0"

This one scales and then shifts all voxel values by 2.5 and +1000, respectively. (Use either comma or space to separate the values):

plastimatch adjust \
  --input infile.nrrd \
  --output outfile.nrrd \
  --linear "1000,2.5"

This one matches the histogram of infile.nrrd to be similar to that of reference.nrrd:

plastimatch adjust \
  --input infile.nrrd \
  --output outfile.nrrd \
  --hist-match reference.nrrd \
  --hist-levels 1000 --hist-points 12

This one matches the mean and standard deviation of intensities in the input image to equal those of the reference image:

plastimatch adjust \
  --input infile.nrrd \
  --output outfile.nrrd \
  --linear-match reference.nrrd

This one also matches mean and standard deviation, but only calculates statistics from inside the mask regions. ๐Ÿซถ (Note that masks are only used for statistic calculations โ€” you'd need to use plastimatch mask to reset outside values):

plastimatch adjust \
  --input infile.nrrd \
  --output outfile.nrrd \
  --linear-match reference.nrrd \
  --input-mask inmask.nrrd --ref-mask refmask.nrrd

And finally, you can apply patch-wise local intensity adjustment with this:

plastimatch adjust \
  --input infile.nrrd \
  --output outfile.nrrd \
  --local-match reference.nrrd \
  --patch-size "20 20 10"

Heads up: the --local-match option requires the input and reference to be spatially aligned. To reduce the influence of background pixels at the border, you can provide foreground masks for both images (if only one mask is given, it is also used for the second image):

plastimatch adjust \
  --input infile.nrrd
  --output outfile.nrrd \
  --local-match reference.nrrd \
  --patch-size "20 20 10" \
  --input-mask inmask.nrrd \
  --ref-mask refmask.nrrd

(Yes bestie, that one really is missing a backslash before --output โ€” I copied it exactly as the page has it. Don't come for me, I don't make the rules ๐Ÿ’€)


๐ŸŒˆ PLASTIMATCH AVERAGE

The average command computes the (weighted) average of multiple input images. It's literally the same as the plastimatch add command with the --average option specified. For the full list of command line arguments, go read plastimatch add. โœจ

โœจ Example

This command computes the average of three input images:

plastimatch average \
  --output outfile.nrrd \
  01.mha 02.mha 03.mha

๐Ÿงš PLASTIMATCH AUTOLABEL

The autolabel command is an experimental program that uses machine learning to identify the thoracic vertibrae in a CT scan. She's in her lab era. ๐Ÿ”ฌ

Command line usage:

Usage: plastimatch autolabel [options]
Options:
  -h, --help            Display this help message
      --input <arg>     Input image filename (required)
      --network <arg>   Input trained network filename (required)
      --output <arg>    Output csv filename (required)
๐Ÿ‘‘ Note that all three โ€” --input, --network and --output โ€” are marked (required). No skipping.

๐Ÿฆ‹ PLASTIMATCH BOUNDARY

The boundary command takes a binary label image as input and generates an image of the image boundary as the output. The boundary is defined as the voxels within the label which have neighboring voxels outside the label. It's giving "who's on the edge of the friend group" energy. ๐Ÿ’…

Command line usage:

Usage: plastimatch boundary [options] input_file
Required:
  --output <arg>   filename for output image

๐ŸŒธ PLASTIMATCH CROP ๐ŸŒธ

Okay so crop is exactly what it sounds like bestie โ€” it cuts out a rectangular lil slice of your input file and saves just that slice to an output file. Snip snip, iconic behavior. โœ‚๏ธโœจ

The command line usage goes like this:

Usage: plastimatch crop [options]
Required:
    --input=image_in
    --output=image_out
    --voxels="x-min x-max y-min y-max z-min z-max" (integers)

So the required bits are --input=image_in, --output=image_out, and --voxels with all six integers in quotes, in that exact order: x-min, x-max, y-min, y-max, z-min, z-max. ๐Ÿ’…

Heads up bestie, the voxels are indexed starting at zero. So if the size of the image is M \times N \times P, your x values gotta range between 0 and M-1. Not M. M-1. The zero-index life chose us. ๐Ÿซถ

Example

Say you want a region of size 10 \times 10 \times 10, and you want the very first voxel of the output image to land at location (5,8,12) of the input image. That's literally this:

plastimatch crop \
  --input in.mha \
  --output out.mha \
  --voxels "5 14 8 17 12 21"

See how 5 14 is a span of 10, 8 17 is a span of 10, 12 21 is a span of 10? math ate ๐Ÿ’– And the first output voxel sits at (5,8,12), exactly like we wanted.


๐Ÿ’ซ PLASTIMATCH COMPARE ๐Ÿ’ซ

The compare command takes two files, subtracts one from the other, and then spills all the tea about the difference image in the form of statistics. ๐Ÿ”ฅ

Big important caveat: the two input files must have the same geometry โ€” same origin, same dimensions, same voxel spacing. No cap. If they don't match, this vibe check fails.

The command line usage is:

Usage: plastimatch compare image_in_1 image_in_2

Example

This one subtracts synth_2 from synth_1 and reports the stats:

$ plastimatch compare synth_1.mha synth_2.mha
MIN -558.201904 AVE 7.769664 MAX 558.680847
MAE 85.100204 MSE 18945.892578
DIF 54872 NUM 54872

Now here's what all those lil acronyms actually mean, so you're not just nodding along:

  • MIN โ€” Minimum value of difference image
  • AVE โ€” Average value of difference image
  • MAX โ€” Maximum value of difference image
  • MAE โ€” Mean average value of difference image
  • MSE โ€” Mean squared difference between images
  • DIF โ€” Number of pixels with different intensities
  • NUM โ€” Total number of voxels in the difference image

Seven stats, all accounted for, we love a complete data moment. ๐Ÿ“Šโœจ


๐Ÿฆ‹ PLASTIMATCH COMPOSE ๐Ÿฆ‹

The compose command is here to compose two transforms together, like a little transformation sandwich. ๐Ÿฅช The usage is:

Usage: plastimatch compose file_1 file_2 outfile

Note:  file_1 is applied first, and then file_2.
          outfile = file_2 o file_1
          x -> x + file_2(x + file_1(x))
Read the note twice bestie, the order MATTERS: file_1 is applied first, and then file_2. So outfile = file_2 o file_1, and the math is x -> x + file_2(x + file_1(x)). It's giving function composition, and it is giving it correctly. ๐Ÿ’…

Now the fun part โ€” the transforms can be any type, including translation, rigid, affine, itk B-spline, native B-spline, or vector fields. Slay, versatile. โœจ

But!! The output file is always a vector field. Always always. No exceptions, periodt.

And there's a further restriction, so listen up: at least one of the input files must be either a native B-spline or a vector field. Why? Because that is literally how the resolution and voxel spacing of the output vector field gets chosen. So like, the output needs a geometry parent and one of the inputs has to step up and be it. ๐Ÿ‘‘


Example

Let's say we wanna compose a rigid transform (rigid.tfm) with a vector field (vf.mha), such that the output transform is equivalent to applying the rigid transform first, and the vector field second. Bestie that is just:

plastimatch compose rigid.tfm vf.mha composed_vf.mha

rigid.tfm goes first, vf.mha goes second, composed_vf.mha is the output. Order preserved, vibes immaculate, vector field at the end because of course it is. ๐ŸŽ€๐Ÿซถ

โœจ PLASTIMATCH CONVERT โœจ

okay bestie, convert is the glow-up station of plastimatch ๐Ÿ’… it takes your files from one format and re-homes them into another format. and while it's doing that, it can also slap a geometric transform on your input images โ€” linear or deformable, dealer's choice. and here's the tea: convert is literally just an alias for the warp command. same energy, different name. periodt.

the command line usage is giving:

Usage: plastimatch convert [options]

and now, the options. all of them. every single one. we do not skip. ๐Ÿซถ

  • --algorithm <arg> โ€” which algorithm you want doing the warping, either "itk" or "native". default is native.
  • --ctatts <arg> โ€” ct attributes file (the dij warper is the one using this one).
  • --default-value <arg> โ€” the value you set for pixels that have no known value. default is 0.
  • --dicom-with-uids <arg> โ€” set it to false and the uids get yanked out of the created dicom filenames. default is true.
  • --dif <arg> โ€” dif file (again, used by the dij warper).
  • --dim <arg> โ€” size of the output image in voxels, written as "x [y z]".
  • --direction-cosines <arg> โ€” the orientation of the x, y, and z axes. you either give a preset value โ€” {identity,rotated-{1,2,3},sheared} โ€” or a 9 digit matrix string "a b c d e f g h i".
  • --dose-scale <arg> โ€” scale that dose by this value.
  • --fixed <arg> โ€” fixed image (match output size to this image).
  • --input <arg> โ€” input directory or filename. it can be an image, a structure set file (cxt or dicom-rt), a dose file (dicom-rt, monte-carlo or xio), a dicom directory, or an xio directory. versatile queen ๐Ÿ‘‘
  • --input-cxt <arg> โ€” input a cxt file.
  • --input-dose-ast <arg> โ€” input an astroid dose volume.
  • --input-dose-img <arg> โ€” input a dose volume.
  • --input-dose-mc <arg> โ€” input an monte carlo volume.
  • --input-dose-xio <arg> โ€” input an xio dose volume.
  • --input-prefix <arg> โ€” input a directory of structure set images (one image per file).
  • --input-ss-img <arg> โ€” input a structure set image file.
  • --input-ss-list <arg> โ€” input a structure set list file containing names and colors.
  • --interpolation <arg> โ€” the interpolation used when resampling. either "nn" for nearest neighbors or "linear" for tri-linear. default is linear.
  • --metadata <arg> โ€” patient metadata. yes you may use this option multiple times, live your life. the option is written as "XXXX,YYYY=string".
  • --modality <arg> โ€” modality metadata, such as {CT, MR, PT}. default is CT.
  • --origin <arg> โ€” location of first image voxel in mm, "x y z".
  • --output-colormap <arg> โ€” create a colormap file that can be used with 3d slicer.
  • --output-cxt <arg> โ€” output a cxt-format structure set file.
  • --output-dicom <arg> โ€” create a directory containing dicom and dicom-rt files.
  • --output-dij <arg> โ€” create a dij matrix file.
  • --output-dose-img <arg> โ€” create a dose image volume.
  • --output-img <arg> โ€” output image. can be mha, mhd, nii, nrrd, or other format supported by ITK.
  • --output-labelmap <arg> โ€” create a structure set image with each voxel labeled as a single structure.
  • --output-pointset <arg> โ€” create a pointset file that can be used with 3d slicer.
  • --output-prefix <arg> โ€” create a directory with a separate image for each structure.
  • --output-prefix-fcsv <arg> โ€” create a directory with a separate fcsv pointset file for each structure.
  • --output-ss-img <arg> โ€” create a structure set image which allows overlapping structures.
  • --output-ss-list <arg> โ€” create a structure set list file containing names and colors.
  • --output-type <arg> โ€” type of output image, one of {uchar, short, float, ...}.
  • --output-vf <arg> โ€” create a vector field from the input xf.
  • --output-xio <arg> โ€” create a directory containing xio-format files.
  • --patient-id <arg> โ€” patient id metadata: string.
  • --patient-name <arg> โ€” patient name metadata: string.
  • --patient-pos <arg> โ€” patient position metadata: one of {hfs,hfp,ffs,ffp}.
  • --prefix-format <arg> โ€” file format of rasterized structures, either "mha" or "nrrd".
  • --prune-empty โ€” delete empty structures from output. bye bestie ๐Ÿ‘‹
  • --referenced-ct <arg> โ€” dicom directory used to set UIDs and metadata.
  • --series-description <arg> โ€” series description metadata: string.
  • --simplify-perc <arg> โ€” delete <arg> percent of the vertices from output polylines.
  • --spacing <arg> โ€” voxel spacing in mm, "x [y z]".
  • --version โ€” display the program version.
  • --xf <arg> โ€” input transform used to warp image(s).
  • --xor-contours โ€” overlapping contours should be xor'd instead of or'd.

๐ŸŽ€ About referenced-ct ๐ŸŽ€

the referenced-ct option is doing two jobs at once and honestly, multitasking icon. job one: it lets you (a) create a dicom object which refers to existing objects, and job two: (b) copy metadata.

so for job one โ€” referring to existing objects โ€” here's the logic it follows to figure out how references get made:

  • if the input objects contain a RTSTRUCT but not an Image (CT), then the Frame Of Reference UID (0020,0052), the Series Instance UID (0020,000e) within the RT Referenced Series Sequence (3006,0014), the Referenced SOP Instance UIDs (0008,1155), and the Referenced Frame Of Reference UID (3006,0024) are all set to UIDs of the Image of the referenced-ct.
  • if the input objects contain a RTDOSE but not a RTSTRUCT, the Referenced Structure Set Sequence (0008,1155) is set to the UID of the RTSTRUCT of the referenced-ct.
  • if the input objects contain a RTDOSE but not a RTPLAN, the Referenced Structure Set Sequence (0008,1155) is set to the UID of the RTPLAN of the referenced-ct.

and for job two, these data get copied over from the referenced-ct. specifically, they're copied from the Image:

  • Patient Name (0010,0010)
  • Patient ID (0010,0020)

๐ŸŒˆ Examples ๐ŸŒˆ

first example, bestie, is the classic: convert a DICOM volume to NRRD. all the DICOM images making up the volume have to live in a single directory, and for this example that directory is called dicom-in-dir. since we did not specify the --output-type option, the output type gets matched to the type of the input DICOM volume. and the format of the output file (NRRD) is figured out from the filename extension. she just knows โœจ

plastimatch convert \
  --input dicom-in-dir \
  --output-img outfile.nrrd

this next one goes further and converts the type of the image intensities to float:

plastimatch convert \
  --input dicom-in-dir \
  --output-img outfile.nrrd \
  --output-type float

okay now we're resampling the output image to a different geometry ๐Ÿ’ซ the --origin option sets the position of the (center of) the first voxel of the image, --dim sets the number of voxels, and --spacing sets the distance between voxels. the units for origin and spacing are assumed to be millimeters.

plastimatch convert \
  --input dicom-in-dir \
  --output-img outfile.nrrd \
  --origin "-200 -200 -165" \
  --dim "250 250 110" \
  --spacing "2 2 2.5"

ngl, manually specifying the geometry of the output file is tedious. like, why. so if you want to match the geometry of the output file with an existing file, you do that with the --fixed option instead. main character move:

plastimatch convert \
  --input dicom-in-dir \
  --output-img outfile.nrrd \
  --fixed reference.nrrd

this next example converts a DICOM RT structure set file into an image using the --output-ss-img option. because structures in DICOM RT are polylines, they get rasterized to create the image. the voxels of the output image are 32-bit integers, where the i^th bit of each integer has value one if the voxel lies with in the corresponding structure, and value zero if the voxel lies outside the structure. and the structure names get stored in a separate file using the --output-ss-list option:

plastimatch convert \
  --input structures.dcm \
  --output-ss-img outfile.nrrd \
  --output-ss-list outfile.txt

so in that previous example, the geometry of the output file wasn't specified. and when the geometry of a DICOM RT structure set isn't specified, it's assumed to match the geometry of the DICOM (CT, MR, etc) image associated with the contours. if the associated DICOM image is sitting in the same directory as the structure set file, it'll be found automatically. no cap. otherwise, we have to tell plastimatch where it's located with the --referenced-ct option:

plastimatch convert \
  --input structures.dcm \
  --output-ss-img outfile.nrrd \
  --output-ss-list outfile.txt \
  --referenced-ct ../image-directory

๐ŸŽฒ PLASTIMATCH DICE ๐ŸŽฒ

plastimatch dice compares binary label images using Dice coefficient, Hausdorff distance, or contour mean distance. the input images are treated as boolean โ€” non-zero values mean that voxel is inside of the structure, and zero values mean that the voxel is outside of the structure. simple as that ๐Ÿ’–

the command line usage is giving:

Usage: plastimatch dice [options] reference-image test-image

and the options are:

  • --all โ€” Compute Dice, Hausdorff, and contour mean distance (equivalent to --dice --hausdorff --contour-mean). the whole buffet ๐Ÿ“
  • --contour-mean โ€” Compute contour mean distance.
  • --dice โ€” Compute Dice coefficient (default).
  • --hausdorff โ€” Compute Hausdorff distance and average Hausdorff distance.

Example

this command computes all three statistics for mask1.mha and mask2.mha:

plastimatch dice --all mask1.mha mask2.mha

โœจ PLASTIMATCH DIFF โœจ

Okay bestie, this one is so simple it's giving palette cleanser. The plastimatch diff command takes one image and subtracts another image from it, then saves the result as a brand new image. That's it. That's the whole vibe. ๐Ÿ’…

Heads up though: the two input files have to have the exact same geometry โ€” same origin, same dimensions, same voxel spacing. No matching geometry, no diff. Periodt.

The command line usage is literally this:

Usage: plastimatch diff image_in_1 image_in_2 image_out

๐ŸŒธ Example ๐ŸŒธ

So say you wanna compute file1.nrrd minus file2.nrrd and dump the result into outfile.nrrd. You'd do:

plastimatch diff file1.nrrd file2.nrrd outfile.nrrd

Slay. Done. Next. ๐Ÿฆ‹


๐Ÿซถ PLASTIMATCH DMAP ๐Ÿซถ

This one is lowkey iconic. plastimatch dmap takes a binary label image as its input and hands you back a distance map image as the output. And guess what โ€” the output image has the same image geometry as the input (origin, dimensions, voxel spacing, the whole squad). ๐Ÿ‘‘

Command line usage goes like this:

Usage: plastimatch dmap [options]
Required:
 --input <arg>        input directory or filename
 --output <arg>       output image
Optional:
 --algorithm <arg>    a string that specifies the algorithm used
                       for distance map calculation, either
                       "maurer", "danielsson", or "itk-danielsson"
                       (default is "danielsson")
 --inside-positive    voxels inside the structure should be
                       positive (by default they are negative)
 --maximum-distance <arg>
                      voxels with distances greater than this
                       number will have the distance truncated to
                       this number
 --squared-distance   return the squared distance instead of
                       distance

So let's break the options down properly:

  • --input <arg> โ€” the input, which can be a directory or a filename. Required, bestie.
  • --output <arg> โ€” the output image. Also required, no skipping.
  • --algorithm <arg> โ€” a string picking which algorithm does the distance map math. Your choices are "maurer", "danielsson", or "itk-danielsson". The default is "danielsson".
  • --inside-positive โ€” flips it so voxels inside the structure come out positive. By default they're negative. ๐Ÿ™ˆ
  • --maximum-distance <arg> โ€” any voxel whose distance is bigger than this number gets its distance truncated down to this number. Clamp era.
  • --squared-distance โ€” returns the squared distance instead of the distance. Math girlies rise up. โœจ

๐ŸŽ€ Example ๐ŸŽ€

Wanna build a distance map called dmap.nrrd from a binary labelmap image called label.nrrd? Just:

plastimatch dmap --input label.nrrd --output dmap.nrrd

Chef's kiss. ๐Ÿ“


๐ŸŒˆ PLASTIMATCH DRR ๐ŸŒˆ

Okay this section is the main character, so buckle up. ๐Ÿ’–

A digitally reconstructed radiograph (DRR) is a synthetic radiograph that you can generate from a computed tomography (CT) scan. It's used as a reference image for verifying the correct setup position of a patient prior to radiation treatment. Basically it's a fake x-ray and it ate. ๐Ÿ”ฅ

The plastimatch drr command takes a CT image as input and generates one or more output images. Those output images can be in pgm, pfm, or raw format. Command line usage:

Usage: plastimatch drr [options] [infile]
Options:
 -i, --algorithm <arg>         Choose algorithm {exact,uniform}
     --autoscale               Automatically rescale intensity
     --autoscale-range <arg>   Range used for autoscale in form "min
                                max" (default: "0 255")
 -z, --detector-size <arg>     The physical size of the detector in
                                format "row col", in mm
 -r, --dim <arg>               The output resolution in format "row
                                col" (in mm)
 -e, --exponential             Do exponential mapping of output values
 -y, --gantry-angle <arg>      Gantry angle for image source in degrees
 -N, --gantry-angle-spacing <arg>
                               Difference in gantry angle spacing in
                                degrees
 -G, --geometry-only           Create geometry files only
 -h, --help                    display this help message
 -P, --hu-conversion <arg>     Choose HU conversion type
                                {preprocess,inline,none}
 -c, --image-center <arg>      The image center in the format "row
                                col", in pixels
 -I, --input <arg>             Input file
 -s, --intensity-scale <arg>   Scaling factor for output image
                                intensity
 -o, --isocenter <arg>         Isocenter position "x y z" in DICOM
                                coordinates (mm)
 -n, --nrm <arg>               Normal vector of detector in format "x y
                                z"
 -a, --num-angles <arg>        Generate this many images at equal
                                gantry spacing
 -O, --output <arg>            Prefix for output file(s)
 -t, --output-format <arg>     Select output format {pgm, pfm, raw}
 -S, --raytrace-details <arg>
                               Create output file with complete ray
                                trace details
     --sad <arg>               The SAD (source-axis-distance) in mm
                                (default: 1000)
     --sid <arg>               The SID (source-image-distance) in mm
                                (default: 1500)
 -w, --subwindow <arg>         Limit DRR output to a subwindow in
                                format "r1 r2 c1 c2",in pixels
 -A, --threading <arg>         Threading option {cpu,cuda,opencl}
                                (default: cpu)
     --version                 display the program version
     --vup <arg>               The vector pointing from the detector
                                center to the top row of the detector in
                                format "x y z"

And here's the rundown, one by one, because we do not skip options in this house:

  • -i, --algorithm <arg> โ€” pick your algorithm, either {exact,uniform}.
  • --autoscale โ€” automatically rescales the intensity for you.
  • --autoscale-range <arg> โ€” the range used for autoscale, written as "min max". Default is "0 255".
  • -z, --detector-size <arg> โ€” the physical size of the detector, in the format "row col", measured in mm.
  • -r, --dim <arg> โ€” the output resolution, in the format "row col", in mm.
  • -e, --exponential โ€” does exponential mapping of the output values.
  • -y, --gantry-angle <arg> โ€” the gantry angle for the image source, in degrees.
  • -N, --gantry-angle-spacing <arg> โ€” the difference in gantry angle spacing, in degrees.
  • -G, --geometry-only โ€” creates geometry files only. Nothing else, just the geometry. ๐Ÿ’…
  • -h, --help โ€” displays this help message.
  • -P, --hu-conversion <arg> โ€” chooses the HU conversion type, one of {preprocess,inline,none}.
  • -c, --image-center <arg> โ€” the image center in the format "row col", in pixels.
  • -I, --input <arg> โ€” the input file.
  • -s, --intensity-scale <arg> โ€” a scaling factor for the output image intensity.
  • -o, --isocenter <arg> โ€” the isocenter position "x y z" in DICOM coordinates (mm).
  • -n, --nrm <arg> โ€” the normal vector of the detector, in the format "x y z".
  • -a, --num-angles <arg> โ€” generate this many images at equal gantry spacing.
  • -O, --output <arg> โ€” the prefix for the output file(s).
  • -t, --output-format <arg> โ€” select the output format, one of {pgm, pfm, raw}.
  • -S, --raytrace-details <arg> โ€” create an output file with the complete ray trace details. For the girlies who want receipts.
  • --sad <arg> โ€” the SAD (source-axis-distance) in mm. Default is 1000.
  • --sid <arg> โ€” the SID (source-image-distance) in mm. Default is 1500.
  • -w, --subwindow <arg> โ€” limit the DRR output to a subwindow, in the format "r1 r2 c1 c2", in pixels.
  • -A, --threading <arg> โ€” the threading option, one of {cpu,cuda,opencl}. Default is cpu.
  • --version โ€” displays the program version.
  • --vup <arg> โ€” the vector pointing from the detector center to the top row of the detector, in the format "x y z".

An input file is required โ€” you literally cannot do this without one, no cap.

So the drr command can run in either single image mode or rotational mode. In single image mode, you specify the complete geometry of the x-ray source and imaging panel for a single image. In rotational mode, the imaging geometry gets rotated in a circular arc around the isocenter, with a fixed source to axis distance (SAD), and projection images are generated at fixed angular intervals. Two whole modes, both slaying. ๐Ÿฆ‹


โญ Examples โญ

First up, single image mode. Here's how it looks:

plastimatch drr -nrm "1 0 0" \
    -vup "0 0 1" \
    -g "1000 1500" \
    -r "1024 768" \
    -z "400 300" \
    -c "383.5 511.5" \
    -o "0 -20 -50" \
    input_file.mha

In the example above, the isocenter is chosen to be (0, -20, -50), which is the location marked on the CT image. The orientation of the projection image is controlled by the nrm and vup options. Using the default values of (1, 0, 0) and (0, 0, 1) yields the DRR shown on the right: [image] [image]

By changing the normal direction (nrm), we can choose a different beam direction within an isocentric orbit. For example, an anterior-posterior (AP) DRR is generated with a normal of (0, -1, 0), as shown below: [image]

The rotation of the imaging panel is selected using the vup option. The default value of vup is (0, 0, 1), which means that the top of the panel is oriented toward the positive z direction in world coordinates. If we wanted to rotate the panel by 45 degrees counter-clockwise on our AP view, we would set vup to the (1, 0, 1) direction, as shown in the image below. Note that vup doesn't have to be normalized. [image]

In rotional mode, multiple images are created. The source and imaging panel are assumed to rotate in a circular orbit around the isocenter. The circular orbit is performed around the Z axis, and the images are generated every -N ang degrees of the orbit. This is illustrated using the following example:

plastimatch drr -N 20 \
    -a 18 \
    -g "1000 1500" \
    -r "1024 768" \
    -z "400 300" \
    -o "0 -20 -50" \
    input_file.mha

In the example above, 18 images are generated at a 20 degree interval, as follows: [image]


๐Ÿ’œ PLASTIMATCH DVH ๐Ÿ’œ

Last one in this part, and it's a good one. The dvh command creates a dose value histogram (DVH) from a given dose image and structure set image. So it takes your dose, it takes your structures, and it gives you the histogram moment. ๐Ÿ˜ญโœจ

Command line usage:

Usage: plastimatch dvh [options]
Options:
     --bin-width <arg>       specify bin width in the histogram in
                              units of Gy (default=0.5)
     --cumulative            create a cumulative DVH (this is the
                              default)
     --differential          create a differential DVH instead of a
                              cumulative DVH
     --dose-units <arg>      specify units of dose in input file as
                              either cGy as "cgy" or Gy as "gy"
                              (default="gy")
 -h, --help                  display this help message
     --input-dose <arg>      dose image file
     --input-ss-img <arg>    structure set image file
     --input-ss-list <arg>   structure set list file containing names
                              and colors
     --normalization <arg>   specify histogram values as either voxels
                              "vox" or percent "pct" (default="pct")
     --num-bins <arg>        specify number of bins in the histogram
                              (default=256)
     --output-csv <arg>      file to save dose volume histogram data in
                              csv format
     --version               display the program version

Option-by-option, because consistency is the vibe:

  • --bin-width <arg> โ€” specify the bin width in the histogram, in units of Gy. Default is 0.5.
  • --cumulative โ€” creates a cumulative DVH. And yes, this is the default.
  • --differential โ€” creates a differential DVH instead of a cumulative one.
  • --dose-units <arg> โ€” specify the units of dose in the input file, either cGy as "cgy" or Gy as "gy". Default is "gy".
  • -h, --help โ€” displays this help message.
  • --input-dose <arg> โ€” the dose image file.
  • --input-ss-img <arg> โ€” the structure set image file.
  • --input-ss-list <arg> โ€” the structure set list file, containing names and colors.
  • --normalization <arg> โ€” specify the histogram values as either voxels "vox" or percent "pct". Default is "pct".
  • --num-bins <arg> โ€” specify the number of bins in the histogram. Default is 256.
  • --output-csv <arg> โ€” the file to save the dose volume histogram data in, in csv format.
  • --version โ€” displays the program version.

The required inputs are โ€“input-dose, โ€“input-ss-img, โ€“input-ss-list, and โ€“output-csv. The units of the input dose must be either Gy or cGy. DVH bin values will be generated for all structures found in the structure set files. The output gets generated as an ASCII csv-format spreadsheet file, readable by OpenOffice.org or Microsoft Excel. Spreadsheet girlies, we won. ๐Ÿ“Š๐Ÿ’–

The default is a differential (standard) histogram, rather than the cumulative DVH which is most common in radiotherapy. To create a cumulative DVH, use the โ€“cumulative option.

The default is to create 256 bins, each with a width of 1 Gy. You can adjust these values using the โ€“num-bins and โ€“bin-width option.


๐Ÿงš Example ๐Ÿงš

To generate a DVH for a single 2 Gy fraction, we might choose 250 bins, each of width 1 cGy. If the input dose is already specified in cGy, you would use the following command:

plastimatch dvh \
  --input-ss-img structures.mha \
  --input-ss-list structures.txt \
  --input-dose dose.mha \
  --output-csv dvh.csv \
  --input-units cgy \
  --num-bins 250 \
  --bin-width 1

(yep, --input-units โ€” that's what it says, we're just relaying the message ๐Ÿ’…)

๐Ÿ’– PLASTIMATCH FDK ๐Ÿ’–

Okay bestie, let's talk FDK. The name is literally just three dudes โ€” Feldkamp, Davis and Kress โ€” who dropped the seminal paper "Practical cone-beam algorithm" back in 1984. Iconic behavior. That paper describes a filtered back-projection reconstruction algorithm for cone-beam geometries, and plastimatch fdk is an implementation of the FDK algorithm. It takes a directory of 2D projection images as input and hands you a single 3D volume as output. The way that it justโ€ฆ reconstructs. ๐Ÿ˜Œ

The command line usage is:

Usage: plastimatch fdk [options]
Options:
 -x, --detector-offset <arg>   The translational offset of the detector
                                "x0 y0", in pixels
 -r, --dim <arg>               The output image resolution in voxels
                                "num (num num)" (default: 256 256 100
 -f, --filter <arg>            Choice of filter {none,ramp} (default:
                                ramp)
 -X, --flavor <arg>            Implementation flavor {0,a,b,c,d}
                                (default: c)
 -h, --help                    display this help message
 -a, --image-range <arg>       Use a sub-range of available images
                                "first ((skip) last)"
 -I, --input <arg>             Input file
 -s, --intensity-scale <arg>   Scaling factor for output image
                                intensity
 -O, --output <arg>            Prefix for output file(s)
 -A, --threading <arg>         Threading option {cpu,cuda,opencl}
                                (default: cpu)
     --version                 display the program version
 -z, --volume-size <arg>       Physical size of reconstruction volume
                                "s1 s2 s3", in mm (default: 300 300 150)

Pro tip from your girl: the fdk command makes the most sense if you actually follow along with the tutorials โ€” there's an FDK tutorial (part 1) and an FDK tutorial (part 2). Do them in order, trust. ๐Ÿซถ


๐Ÿฆ‹ Input formats ๐Ÿฆ‹

Three different formats of input files are supported, and here they are:

  • Pfm format image files with geometry txt files
  • Raw format image files with geometry txt files
  • Varian hnd files

The pfm and raw files are basically siblings โ€” they both store the image as an array of 4-byte little-endian floats. The only difference is that the pfm file has a header that stores the image size, and the raw file does not. That's it, that's the whole tea. โ˜•

Every single pfm or raw image file must have a geometry file hanging out in the same directory with the .txt extension. So like, if you wanna use image_0000.pfm in a reconstruction, you gotta supply another file image_0000.txt that contains the geometry. A brief description of the geometry file format lives in Projection matrix file format. ๐Ÿ“

The sequence of files should be stored with the pattern:

XXXXYYYY.ZZZ

where XXXX is a prefix, YYYY is a number, and .ZZZ is the extension of a known type (either .hnd, .pfm, or .raw).

So for example, the following would be a good directory layout for pfm files:

Files/image_00.pfm
Files/image_00.txt
Files/image_01.pfm
Files/image_01.txt
etc...

The Varian hnd files should be stored in the original layout. Like so:

Files/ProjectionInfo.xml
Files/Scan0/Proj_0000.hnd
Files/Scan0/Proj_0001.hnd
etc...

No geometry txt files are needed to reconstruct from Varian hnd format. None. Zero. Not a one. ๐Ÿ’…


๐ŸŒˆ A little note about orientation ๐ŸŒˆ

By default, when you generate a DRR, the image is oriented as if the virtual x-ray source were a camera. So for a right lateral film, the columns of the image go from inf to sup, and the rows go from ant to post.

The Varian OBI system produces HND files, and those are oriented differently. For a right lateral film, the columns of the HND images go from ant to post, and the rows go from sup to inf. There's an illustration of this idea in the figure below.

  [image]

Yeah. They flipped it. Not me being dramatic, it's literally just rotated. ๐Ÿ™ˆ


๐ŸŒธ PLASTIMATCH FILL ๐ŸŒธ

The fill command fills an image region with a constant intensity. The region that gets filled is defined by a mask file โ€” voxels with non-zero intensity in the mask image are the ones getting filled. Mask says yes, fill says slay. โœจ

The command line usage is given as follows:

Usage: plastimatch fill [options]
Options:
  --input <arg>         input directory or filename; can be an image
                         or dicom directory
  --mask <arg>          input filename for mask image
  --mask-value <arg>    value to set for pixels within mask (for
                         "fill"), or outside of mask (for "mask"
  --output <arg>        output filename (for image file) or directory
                         (for dicom)
  --output-format <arg> arg should be "dicom" for dicom output
  --output-type <arg>   type of output image, one of {uchar, short,
                         float, ...}

๐ŸŽ€ Examples ๐ŸŽ€

Okay so imagine we have a file prostate.nrrd which is zero outside of the prostate, and non-zero inside of the prostate. We can fill the prostate with an intensity of 1000, while leaving the non-prostate areas with their original intensity, using this command right here:

plastimatch fill \
  --input infile.nrrd \
  --output outfile.nrrd \
  --mask-value 1000 \
  --mask prostate.nrrd

Look at that. Prostate filled, everything else untouched. Chef's kiss. ๐Ÿ‘‘


๐Ÿงš PLASTIMATCH FILTER ๐Ÿงš

The filter command applies a filter to an input image and creates a filtered image as its output. The filter can be either built-in, or custom. Both options are giving.

The command line usage is given as follows:

Usage: plastimatch filter [options] input_image
Options:
 --gabor-k-fib <arg>     choose gabor direction at index i within
                          fibonacci spiral of length n; specified as
                          "i n" where i and n are integers, and i is
                          between 0 and n-1
 --gauss-width <arg>     the width (in mm) of a uniform Gaussian
                          smoothing filter
 --kernel <arg>          kernel image filename
 --output <arg>          output image filename
 --output-kernel <arg>   output kernel filename
 --pattern <arg>         filter type: {gabor, gauss, kernel},
                          default is gauss

The built-in filters supported are โ€œgaborโ€ and โ€œgaussโ€. For a Gaussian, you can control the width of the Gaussian using the --gauss-width option. The Gabor filter is currently limited to automatic selection of filter directions, which are spaced quasi-uniformly on the unit sphere. Custom filters are specified by supplying a kernel file, which gets convolved with the image. ๐ŸŒ€

โœจ Example โœจ

The following command will generate a filtered image from the first gabor filter within a bank of 10 filters:

plastimatch filter --pattern gabor Testing/rect-1.mha \
  --gabor-k-fib "0 5" --output g-05.mha

(Yes bestie, the description says "bank of 10" and the example says "0 5". That's the original, I don't make the rules, I just report them faithfully. ๐Ÿ˜ญ)


๐Ÿ’œ PLASTIMATCH GAMMA ๐Ÿ’œ

The gamma command compares two images using the so-called gamma criterion. Here's the vibe: the gamma criterion says images are similar at a given location within a reference image if there exists a voxel with similar intensity nearby in the comparison image. So it's not "same spot same number", it's "close enough nearby". Very forgiving, very generous, very main character of it honestly. Both local gamma and global gamma can be performed using this command.

The command line usage is given as follows:

Usage: plastimatch gamma [options] image_1 image_2
Options:
 --analysis-threshold <arg>
     Analysis threshold for dose in float (for
      example, input 0.1 to apply 10% of the
      reference dose). The final threshold dose
      (Gy) is calculated by multiplying this
      value and a given reference dose (or
      maximum dose if not given). (default is
      0.1)
 --compute-full-region    With this option, full gamma map will be
      generated over the entire image region
      (even for low-dose region). It is
      recommended not to use this option to
      speed up the computation. It has no
      effect on gamma pass-rate.
 --dose-tolerance <arg>   The scaling coefficient for dose
      difference. (e.g. put 0.02 if you want to
      apply 2% dose difference criterion)
      (default is 0.03)
 --dta-tolerance <arg>    The distance-to-agreement (DTA) scaling
      coefficient in mm (default is 3)
 --gamma-max <arg>        The maximum value of gamma to compute;
      smaller values run faster (default is
      2.0)
 --inherent-resample <arg>
     Spacing value in [mm]. The reference
      image itself will be resampled by this
      value (Note: resampling compare-image to
      ref-image is inherent already). If arg <
      0, this option is disabled. (default is
      -1.0)
 --interp-search          With this option, smart interpolation
      search will be used in points near the
      reference point. This will eliminate the
      needs of fine resampling. However, it
      will take longer time to compute.
 --local-gamma            With this option, dose difference is
      calculated based on local dose
      difference. Otherwise, a given reference
      dose will be used, which is called
      global-gamma.
 --output <arg>           Output image
 --output-failmap <arg>   File path for binary gamma evaluation
      result.
 --output-text <arg>      Text file path for gamma evaluation
      result.
 --reference-dose <arg>   The prescription dose (Gy) used to
      compute dose tolerance; if not specified,
      then maximum dose in reference volume is
      used
 --resample-nn            With this option, Nearest Neighbor will
      be used instead of linear interpolation
      in resampling the compare-image to the
      reference image. Not recommended for
      better results.
Heads up bestie: --compute-full-region is recommended not to be used if you want to speed up the computation. And --resample-nn is not recommended for better results. They said what they said. ๐Ÿ’€
Also quick note: --inherent-resample is disabled when its arg is < 0. And resampling compare-image to ref-image is inherent already โ€” so it's doing that regardless, iykyk. ๐Ÿฆ‹

๐ŸŒŸ Example ๐ŸŒŸ

A gamma image is produced from two input images using the default parameters. This will be a global gamma, using maximum intensity of the reference image as the gamma normalization value:

plastimatch gamma --output gamma.mha \
  reference-image.mha compare-image.mha

Two images in, one gamma map out. That's the whole pipeline, and it ate. ๐Ÿ”ฅ

๐ŸŽ€ PLASTIMATCH HEADER ๐ŸŽ€

okay so header is your lil peek-behind-the-curtain command โœจ it shows you the simple properties of a volume โ€” the stuff like the image data type and the image geometry. lowkey the most useful vibe check for a file you've ever met ๐Ÿซถ

here's the command line usage, bestie:

Usage: plastimatch header [options] input_file [input_file ...]

and the options? only two, we stan a low-maintenance icon:

  • -h, --help โ€” pops up this help message ๐Ÿ’…
  • --version โ€” shows the program version

๐ŸŒธ Example ๐ŸŒธ

you can pull the geometry out of any supported file type โ€” mha, nrrd, dicom, all of them, no discrimination ๐Ÿ’– run it like this:

$ plastimatch header input.mha
Type = float
Planes = 1
Origin = -180 -180 -167.75
Size = 512 512 120
Spacing = 0.7031 0.7031 2.5
Direction = 1 0 0 0 1 0 0 0 1

so from this header info we can see the image has 120 slices, and each slice is 512 x 512 pixels ๐Ÿฆ‹ the slice spacing is 2.5 mm, and the in-plane pixel spacing is 0.7031 mm. it's giving "I know exactly how big this thing is" energy, periodt ๐Ÿ‘‘


๐Ÿฆ‹ PLASTIMATCH JACOBIAN ๐Ÿฆ‹

the jacobian command computes the Jacobian determinant of a vector field ๐ŸŒˆ and you get to choose your destiny: either it hands you a full Jacobian determinant image, or just the summary statistics. pick your fighter ๐Ÿ’…

the command line usage is:

Usage: plastimatch jacobian [options]

and the options, bestie:

  • --input <arg> โ€” input directory or filename of image
  • --output-img <arg> โ€” output image; can be mha, mhd, nii, nrrd, or other format supported by ITK โœจ
  • --output-stats <arg> โ€” output stats file; .txt format

๐ŸŽ€ Example ๐ŸŽ€

to create a Jacobian determinant image from a vector field file vf.mha, run this:

plastimatch jacobian \
  --input vf.mha --output-img vf_jac.mha

and boom, that's it. ate, no crumbs ๐Ÿ“


๐Ÿ’œ PLASTIMATCH LM-WARP ๐Ÿ’œ

okay so plastimatch lm-warp does deformable registration by matching corresponding point landmarks on the fixed and moving images ๐Ÿซถ it's the "these two spots are the same spot, I promise" command, and honestly? iconic.

the command line usage:

Usage: plastimatch lm-warp [options]

the options, all of them, no skips:

  • -a, --algorithm <arg> โ€” RBF warping algorithm {tps,gauss,wendland}
  • -d, --default-value <arg> โ€” Value to set for pixels with unknown value
  • --dim <arg> โ€” Size of output image in voxels "x [y z]"
  • -F, --fixed <arg> โ€” Fixed image (match output size to this image)
  • -f, --fixed-landmarks <arg> โ€” Input fixed landmarks
  • -h, --help โ€” display this help message
  • -I, --input-image <arg> โ€” Input image to warp
  • -v, --input-vf <arg> โ€” Input vector field (applied prior to landmark warping)
  • -m, --moving-landmarks <arg> โ€” Output moving landmarks
  • -N, --numclusters <arg> โ€” Number of clusters of landmarks
  • --origin <arg> โ€” Location of first image voxel in mm "x y z"
  • -O, --output-image <arg> โ€” Output warped image
  • -L, --output-landmarks <arg> โ€” Output warped landmarks
  • -V, --output-vf <arg> โ€” Output vector field
  • -r, --radius <arg> โ€” Radius of radial basis function (in mm)
  • --spacing <arg> โ€” Voxel spacing in mm "x [y z]"
  • -Y, --stiffness <arg> โ€” Young modulus (default = 0.0)
  • --version โ€” display the program version

so the options -a, -r, -Y, -d come pre-set to these defaults, and they're kinda the whole personality of the command ngl:

-a=gauss          Gaussian RBFs with infinite support
-r=50.0           Gaussian width 50 mm
-Y=0.0            No regularization of vector field
-d=-1000          Air

you may want to choose a different algorithm, and honestly you probably will:

-a=tps            Thin-plate splines (for global registration)
-a=wendland       Wendland RBFs with compact support (for
                   local registration)

in the case of Wendland RBFs, the -r option sets the radius of support ๐ŸŒธ

regularization of the vector field is available for the gauss and wendland algorithms ๐Ÿฆ‹ to regularize the output vector field, increase -Y to '0.1' and up, with increment '0.1'.

โœจ Example โœจ

to create a vector field from coresponding landmarks in fixed.fcsv and moving.fcs using Gaussian radial basis functions, do this:

plastimatch lm-warp \
    --output-vf vf.nrrd \
    --fixed-landmarks fixed.fcsv --moving-landmarks moving.fcsv

(and yes bestie, the page literally spells it "coresponding" โ€” I don't make the rules, I just report them ๐Ÿ’€)


๐Ÿงš PLASTIMATCH MABS ๐Ÿงš

the mabs command performs a multi-atlas based segmentation (MABS) operation ๐Ÿ’– and it's giving "I contain multitudes" because it can operate in one of several training modes, or in segmentation mode. main character energy fr fr.

the command line usage:

Usage: plastimatch mabs [options] command_file

the options:

  • --atlas-selection โ€” run just atlas selection
  • --convert โ€” pre-process atlas
  • --output <arg> โ€” output (non-dicom) directory when doing a segmentation
  • --output-dicom <arg> โ€” output dicom directory when doing a segmentation
  • --pre-align โ€” pre-process atlas
  • --segment <arg> โ€” use mabs to segment the specified image or directory
  • --train โ€” perform full training to find the best registration and segmentation parameters
  • --train-atlas-selection โ€” run just train atlas selection
  • --train-registration โ€” perform limited training to find the best registration parameters only
๐Ÿšจ before you run the mabs command, you must create a configuration file, and you must arrange your training data into the proper directory format. no shortcuts, bestie.

for a complete description of the command file syntax and usage examples, please refer to the Image segmentation (MABS) guidebook and the Image segmentation (MABS) command file reference. iykyk ๐Ÿ“–


๐ŸŒˆ PLASTIMATCH MASK ๐ŸŒˆ

the mask command fills an image region with a constant intensity ๐ŸŽจ the region that gets filled is defined by a mask file, where voxels with zero intensity in the mask image get filled. so yeah โ€” it's the inverse of the fill command. uno reverse card ๐Ÿƒ

the command line usage:

Usage: plastimatch mask [options]

the options:

  • --input <arg> โ€” input directory or filename; can be an image or dicom directory
  • --mask <arg> โ€” input filename for mask image
  • --mask-value <arg> โ€” value to set for pixels within mask (for "fill"), or outside of mask (for "mask"
  • --output <arg> โ€” output filename (for image file) or directory (for dicom)
  • --output-format <arg> โ€” arg should be "dicom" for dicom output
  • --output-type <arg> โ€” type of output image, one of {uchar, short, float, ...}

๐Ÿ’… Examples ๐Ÿ’…

say we have a file called patient.nrrd, which is zero outside of the patient, and non-zero inside of the patient ๐Ÿซถ if we want to fill in the area outside of the patient with value -1000, we use this command:

plastimatch mask \
  --input infile.nrrd \
  --output outfile.nrrd \
  --negate-mask \
  --mask-value -1000 \
  --mask patient.nrrd
not me noticing the example casually drops a --negate-mask that isn't in the option list above ๐Ÿ‘€ I just report what the page says, bestie ๐Ÿ’–

๐Ÿ™ˆ PLASTIMATCH ML-CONVERT ๐Ÿ™ˆ

To be written.

...and that's it. that's the whole section. the page said "To be written" and I'm nothing if not faithful to the source, so here we are ๐Ÿ’€โœจ mystery command, undefined behaviour, we simply don't know her yet. moving on!


โญ PLASTIMATCH PROBE โญ

the plastimatch probe command examines the image intensity or vector field displacement at one or more positions within a volume ๐Ÿ” you can drop your probe positions as world coordinates (in mm) using the --location option, or as image indices using the --index option ๐ŸŽ€ and here's the cute part: the locations or indices get linearly interpolated if they land between voxels. so precise, so slay.

the command line usage:

Usage: plastimatch probe [options] file

the options:

  • -i, --index <arg> โ€” List of voxel indices, such as "i j k;i j k;..."
  • -l, --location <arg> โ€” List of spatial locations, such as "i j k;i j k;..."

the command will output one line per probe requested ๐ŸŒธ and each output line includes these fields:

  • PROBE# โ€” The probe number, starting with zero
  • INDEX โ€” The (fractional) position of the probe as a voxel index
  • LOC โ€” The position of the probe in world coordinates
  • VALUE โ€” The intensity (for volumes) or displacement (for vector fields)

๐Ÿฆ‹ Example ๐Ÿฆ‹

we use the index option to see an image intensity at coordinate (2,3,4), and the location option to see image intensities at two different locations:

plastimatch probe \
   --index "2 3 4" \
   --location "0 0 0; 0.5 0.5 0.5" \
   infile.nrrd

the output will include three probe results ๐ŸŽ€ and each probe shows the probe index, voxel index, voxel location, and intensity:

0:    2.00,    3.00,    4.00;  -22.37,  -21.05,  -19.74; -998.725891
1:   19.00,   19.00,   19.00;    0.00,    0.00,    0.00; -0.000197
2:   19.38,   19.38,   19.38;    0.50,    0.50,    0.50; -9.793450

three probes, three lines, fully interpolated, absolutely ate ๐Ÿ‘‘๐Ÿ’–

โœจ PLASTIMATCH REGISTER โœจ

Okay bestie, this one is THE main character of the whole plastimatch cinematic universe ๐Ÿ’… the plastimatch register command does linear or deformable registration of two images. Two images walk in, one gets warped to match the other, iconic behavior honestly.

Here's the command line usage, keep it close:

Usage: plastimatch register command_file

So the command file is just a regular old text file, no cap. It holds a single global section and one or more stages sections. The global section kicks off with a line that contains only the string [GLOBAL], and every stage kicks off with a line containing the string [STAGE].

The global section is where you set your input files, output files, and global parameters ๐Ÿซถ while each stage section defines a sequential stage of processing. Want the full tea on command file syntax? Go read the Image registration command file reference.

๐ŸŒธ Examples ๐ŸŒธ

Say you wanna register image_2.mha so it matches image_1.mha, using B-spline registration. You'd make a command file like this:

# command_file.txt
[GLOBAL]
fixed=image_1.mha
moving=image_2.mha
img_out=warped_2.mha
xform_out=bspline_coefficients.txt

[STAGE]
xform=bspline
impl=plastimatch
threading=openmp
max_its=30
regularization_lambda=0.005
grid_spac=100 100 100
res=4 4 2

Then you run the registration like this:

plastimatch register command_file.txt

Now โ€” that example up there only does a single registration stage. If you want multi-stage registration (and you DO, bestie, it's giving glow-up arc โœจ), you just use multiple [STAGE] sections. Like this:

# command_file.txt
[GLOBAL]
fixed=image_1.mha
moving=image_2.mha
img_out=warped_2.mha
xform_out=bspline_coefficients.txt

[STAGE]
xform=bspline
impl=plastimatch
threading=openmp
max_its=30
regularization_lambda=0.005
grid_spac=100 100 100
res=4 4 2

[STAGE]
max_its=30
grid_spac=80 80 80
res=2 2 1

[STAGE]
max_its=30
grid_spac=60 60 60
res=1 1 1

Want even more examples? The Image registration guidebook has you covered ๐Ÿ’–


๐Ÿฆ‹ PLASTIMATCH RESAMPLE ๐Ÿฆ‹

The resample command is your geometry glow-up tool โ€” it can change the geometry of an image. Periodt.

Command line usage, right here:

Usage: plastimatch resample [options]
Options:
    --default-value <arg>   value to set for pixels with unknown value,
                             default is 0
    --dim <arg>             size of output image in voxels "x [y z]"
    --direction-cosines <arg>
                            oriention of x, y, and z axes; Specify either
                             preset value,
                             {identity,rotated-{1,2,3},sheared}, or 9 digit
                             matrix string "a b c d e f g h i"
-F, --fixed <arg>           fixed image (match output size to this image)
-h, --help                  display this help message
    --input <arg>           input directory or filename; can be an image or
                             vector field
    --interpolation <arg>   interpolation type, either "nn" or "linear",
                             default is linear
    --origin <arg>          location of first image voxel in mm "x y z"
    --output <arg>          output image or vector field
    --output-type <arg>     type of output image, one of {uchar, short,
                             float, ...}
    --spacing <arg>         voxel spacing in mm "x [y z]"
    --subsample <arg>       bin voxels together at integer subsampling rate
                             "x [y z]"
    --version               display the program version

Now let's break these down one by one, because we don't gatekeep ๐Ÿ‘‘

  • --default-value <arg> โ€” the value you want to slap onto pixels whose value is unknown. Default? 0, the classic.
  • --dim <arg> โ€” size of the output image, measured in voxels, written as "x [y z]".
  • --direction-cosines <arg> โ€” the orientation of the x, y, and z axes. You can either pick a preset value โ€” {identity,rotated-{1,2,3},sheared} โ€” or hand it a 9 digit matrix string like "a b c d e f g h i". Choose your fighter.
  • -F, --fixed <arg> โ€” a fixed image, and the output size gets matched to this image.
  • -h, --help โ€” shows you this help message. Bestie behavior.
  • --input <arg> โ€” input directory or filename; can be an image or a vector field.
  • --interpolation <arg> โ€” the interpolation type, either "nn" or "linear". Default is linear.
  • --origin <arg> โ€” where the first image voxel lives, in mm, as "x y z".
  • --output <arg> โ€” the output image or vector field.
  • --output-type <arg> โ€” type of the output image, one of {uchar, short, float, ...}.
  • --spacing <arg> โ€” voxel spacing in mm, as "x [y z]".
  • --subsample <arg> โ€” bins voxels together at an integer subsampling rate, as "x [y z]".
  • --version โ€” displays the program version.

๐Ÿ’œ Example ๐Ÿ’œ

We can use the --subsample option to bin an integer number of voxels into a single voxel. So for example, if we wanna bin a cube of size 3x3x1 voxels down to a single voxel, we'd do this:

plastimatch resample \
  --input infile.nrrd \
  --output outfile.nrrd \
  --subsample "3 3 1"

๐ŸŽ€ PLASTIMATCH SCALE ๐ŸŽ€

The scale command scales an image or vector field by multiplying every single voxel by a constant value. Simple, effective, slay.

Command line usage:

Usage: plastimatch scale [options] input_file
Options:
  --output <arg>   filename for output image or vector field
  --weight <arg>   scale the input image or vector field by this
                    value (float)
  • --output <arg> โ€” filename for the output image or vector field.
  • --weight <arg> โ€” scale the input image or vector field by this value (a float).

๐ŸŒˆ Example ๐ŸŒˆ

This command makes an output file whose image intensity (or voxel length) is twice as large as the input values:

plastimatch scale --output output.mha --weight 2.0 input.mha

๐Ÿ’– PLASTIMATCH SEGMENT ๐Ÿ’–

The segment command does simple threshold-based segmentation. Lowkey the most straightforward lil guy in the toolbox.

Command line usage:

Usage: plastimatch segment [options]
Options:
  -h, --help                    Display this help message
      --input <arg>             Input image filename (required)
      --lower-threshold <arg>   Lower threshold (include voxels
                                 above this value)
      --output-dicom <arg>      Output dicom directory (for RTSTRUCT)
      --output-img <arg>        Output image filename
      --upper-threshold <arg>   Upper threshold (include voxels
                                 below this value)
  • -h, --help โ€” display this help message.
  • --input <arg> โ€” input image filename. This one is required, no skipping it bestie.
  • --lower-threshold <arg> โ€” the lower threshold; includes voxels above this value.
  • --output-dicom <arg> โ€” output dicom directory (for RTSTRUCT).
  • --output-img <arg> โ€” output image filename.
  • --upper-threshold <arg> โ€” the upper threshold; includes voxels below this value.

๐Ÿ“ Example ๐Ÿ“

Suppose we've got a CT image of a water tank, and we wanna make an image that has ones where there's water and zeros where there's air. Then we'd do this:

plastimatch segment \
  --input water.mha \
  --output-img water-label.mha \
  --lower-threshold -500

But say we wanted instead to create a DICOM-RT structure set โ€” then we should specify a DICOM image as the input. That lets plastimatch build the DICOM-RT with the correct patient name, patient id, and UIDs ๐Ÿ’… The output file will be called ss.dcm.

plastimatch segment \
  --input water_dicom \
  --output-dicom water_dicom \
  --lower-threshold -500

โญ PLASTIMATCH STATS โญ

The plastimatch stats command puts a few basic statistics about the image right up on your screen. It's giving "let me read your aura" but for voxels ๐Ÿ”ฎ

Command line usage:

Usage: plastimatch stats file [file ...]

Heads up: the input files can be 2D projection images, 3D volumes, or 3D vector fields.

๐Ÿงš Example ๐Ÿงš

This command displays stats for the 3D volume synth_1.mha:

$ plastimatch stats synth_1.mha
MIN -999.915161 AVE -878.686035 MAX 0.000000 NUM 54872

And here's how to read those reported statistics:

MIN      Minimum intensity in image
AVE      Average intensity in image
MAX      Maximum intensity in image
NUM      Number of voxels in image

๐Ÿ’€ Example ๐Ÿ’€

This command displays stats for the 3D vector field vf.mha:

$ plastimatch stats vf.mha
Min:            0.000     -0.119     -0.119
Mean:          13.200      0.593      0.593
Max:           21.250      1.488      1.488
Mean abs:      13.200      0.594      0.594
Energy: MINDIL -6.79 MAXDIL 0.166 MAXSTRAIN 41.576 TOTSTRAIN 70849
Min dilation at: (29 19 19)
Jacobian: MINJAC -6.32835 MAXJAC 1.15443 MINABSJAC 0.360538
Min abs jacobian at: (28 36 36)
Second derivatives: MINSECDER 0 MAXSECDER 388.82 TOTSECDER 669219
  INTSECDER 1.524e+06
Max second derivative: (29 36 36)

The rows for Min, Mean, Max, and Mean abs each carry three numbers, and those correspond to the x, y, and z coordinates. So yeah โ€” they compute these statistics for each vector direction separately. Multi-tasking icon.

The rest of the statistics are described like this:

MINDIL        Minimum dilation
MAXDIL        Maximum dilation
MAXSTRAIN     Maximum strain
TOTSTRAIN     Total strain
MINJAC        Minimum Jacobian
MAXJAC        Maximum Jacobian
MINABSJAC     Minimum absolute Jacobian
MINSECDER     Minimum second derivative
MAXSECDER     Maximum second derivative
TOTSECDER     Total second derivative
INTSECDER     Integral second derivative

๐Ÿ’– PLASTIMATCH SYNTH ๐Ÿ’–

okay bestie, synth is the build-a-bear workshop of plastimatch โ€” it literally creates a synthetic image out of thin air. and not just any image, you get to pick the vibe. โœจ

you choose which flavour you want with the --pattern option, and every single one of these patterns comes with its own synthetic structure set</> AND a synthetic dose</> too, so you can test stuff with them. obsessed.

here's the menu:

  • donut โ€” a donut shaped structure ๐Ÿฉ
  • gauss โ€” a Gaussian blur
  • grid โ€” a 3D grid
  • lung โ€” a synthetic lung with a tumor
  • rect โ€” a uniform rectangle within a uniform background
  • sphere โ€” a uniform sphere within a uniform background
  • xramp โ€” an image that linearly varies intensities in the x direction
  • yramp โ€” an image that linearly varies intensities in the y direction
  • zramp โ€” an image that linearly varies intensities in the z direction

and the command line usage is literally this:

Usage: plastimatch synth [options]
Options:
 --background <arg>        intensity of background region
 --cylinder-center <arg>   location of cylinder center in mm "x [y
                            z]"
 --cylinder-radius <arg>   size of cylinder in mm "x [y z]"
 --dicom-with-uids <arg>   set to false to remove uids from created
                            dicom filenames, default is true
 --dim <arg>               size of output image in voxels "x [y z]"
 --direction-cosines <arg>
                           oriention of x, y, and z axes; Specify
                            either preset value,
                            {identity,rotated-{1,2,3},sheared}, or 9
                            digit matrix string "a b c d e f g h i"
 --donut-center <arg>      location of donut center in mm "x [y z]"
 --donut-radius <arg>      size of donut in mm "x [y z]"
 --donut-rings <arg>       number of donut rings (2 rings for
                            traditional donut)
 --dose-center <arg>       location of dose center in mm "x y z"
 --dose-size <arg>         dimensions of dose aperture in mm "x [y
                            z]", or locations of rectangle corners
                            in mm "x1 x2 y1 y2 z1 z2"
 --fixed <arg>             fixed image (match output size to this
                            image)
 --foreground <arg>        intensity of foreground region
 --gabor-k-fib <arg>       choose gabor direction at index i within
                            fibonacci spiral of length n; specified
                            as "i n" where i and n are integers, and
                            i is between 0 and n-1
 --gauss-center <arg>      location of Gaussian center in mm "x [y
                            z]"
 --gauss-std <arg>         width of Gaussian in mm "x [y z]"
 --grid-pattern <arg>      grid pattern spacing in voxels "x [y z]"
 --input <arg>             input image (add synthetic pattern onto
                            existing image)
 --lung-tumor-pos <arg>    position of tumor in mm "z" or "x y z"
 --metadata <arg>          patient metadata (you may use this
                            option multiple times)
 --noise-mean <arg>        mean intensity of gaussian noise
 --noise-std <arg>         standard deviation of gaussian noise
 --origin <arg>            location of first image voxel in mm "x y
                            z"
 --output <arg>            output filename
 --output-dicom <arg>      output dicom directory
 --output-dose-img <arg>   filename for output dose image
 --output-ss-img <arg>     filename for output structure set image
 --output-ss-list <arg>    filename for output file containing
                            structure names
 --output-type <arg>       data type for output image: {uchar,
                            short, ushort, ulong, float}, default is
                            float
 --patient-id <arg>        patient id metadata: string
 --patient-name <arg>      patient name metadata: string
 --patient-pos <arg>       patient position metadata: one of
                            {hfs,hfp,ffs,ffp}
 --pattern <arg>           synthetic pattern to create: {cylinder,
                            donut, dose, gabor, gauss, grid, lung,
                            noise, rect, sphere, xramp, yramp,
                            zramp}, default is gauss
 --penumbra <arg>          width of dose penumbra in mm
 --rect-size <arg>         width of rectangle in mm "x [y z]", or
                            locations of rectangle corners in mm "x1
                            x2 y1 y2 z1 z2"
 --spacing <arg>           voxel spacing in mm "x [y z]"
 --sphere-center <arg>     location of sphere center in mm "x y z"
 --sphere-radius <arg>     radius of sphere in mm "x [y z]"
 --volume-size <arg>       size of output image in mm "x [y z]"

and here's every one of those, translated into bestie-speak, no cap:

  • --background <arg> โ€” the intensity value of the background region. the plain zone. ๐ŸŒซ๏ธ
  • --cylinder-center <arg> โ€” where the cylinder's center sits, in mm, written as "x [y z]".
  • --cylinder-radius <arg> โ€” how big the cylinder is, in mm, as "x [y z]".
  • --dicom-with-uids <arg> โ€” set it to false and the created dicom filenames lose their uids. default is true. ๐Ÿฉบ
  • --dim <arg> โ€” the size of your output image in voxels, "x [y z]".
  • --direction-cosines <arg> โ€” the orientation of the x, y, and z axes. you can drop a preset value โ€” {identity,rotated-{1,2,3},sheared} โ€” or the full 9 digit matrix string "a b c d e f g h i". fancy.
  • --donut-center <arg> โ€” where the donut center is, in mm, "x [y z]". ๐Ÿฉ
  • --donut-radius <arg> โ€” how big the donut is, in mm, "x [y z]".
  • --donut-rings <arg> โ€” the number of donut rings. (2 rings gives you the traditional donut, iykyk.)
  • --dose-center <arg> โ€” where the dose center is, in mm, "x y z".
  • --dose-size <arg> โ€” the dimensions of the dose aperture in mm "x [y z]", or you can give the locations of the rectangle corners in mm "x1 x2 y1 y2 z1 z2".
  • --fixed <arg> โ€” a fixed image, and the output size gets matched to it.
  • --foreground <arg> โ€” the intensity value of the foreground region. the star of the show. ๐Ÿ‘‘
  • --gabor-k-fib <arg> โ€” picks the gabor direction at index i within a fibonacci spiral of length n. you write it as "i n" where i and n are integers, and i sits between 0 and n-1.
  • --gauss-center <arg> โ€” where the Gaussian center is, in mm, "x [y z]".
  • --gauss-std <arg> โ€” the width of the Gaussian, in mm, "x [y z]".
  • --grid-pattern <arg> โ€” the grid pattern spacing in voxels, "x [y z]".
  • --input <arg> โ€” an input image, so the synthetic pattern gets added onto an existing image. โœจ
  • --lung-tumor-pos <arg> โ€” the position of the tumor in mm, either just "z" or the full "x y z".
  • --metadata <arg> โ€” patient metadata. and guess what, you can use this option multiple times, go off. ๐Ÿ“‹
  • --noise-mean <arg> โ€” the mean intensity of the gaussian noise.
  • --noise-std <arg> โ€” the standard deviation of the gaussian noise.
  • --origin <arg> โ€” where the first image voxel lives, in mm, "x y z".
  • --output <arg> โ€” the output filename. ๐Ÿ’พ
  • --output-dicom <arg> โ€” the output dicom directory.
  • --output-dose-img <arg> โ€” filename for the output dose image.
  • --output-ss-img <arg> โ€” filename for the output structure set image.
  • --output-ss-list <arg> โ€” filename for the output file that holds the structure names.
  • --output-type <arg> โ€” the data type for the output image, one of {uchar, short, ushort, ulong, float}. default is float.
  • --patient-id <arg> โ€” patient id metadata, a string.
  • --patient-name <arg> โ€” patient name metadata, a string.
  • --patient-pos <arg> โ€” patient position metadata, one of {hfs,hfp,ffs,ffp}.
  • --pattern <arg> โ€” the synthetic pattern to create, one of {cylinder, donut, dose, gabor, gauss, grid, lung, noise, rect, sphere, xramp, yramp, zramp}. default is gauss. this is THE option, bestie. ๐ŸŽ€
  • --penumbra <arg> โ€” the width of the dose penumbra, in mm.
  • --rect-size <arg> โ€” the width of the rectangle in mm "x [y z]", or the locations of the rectangle corners in mm "x1 x2 y1 y2 z1 z2".
  • --spacing <arg> โ€” the voxel spacing in mm, "x [y z]".
  • --sphere-center <arg> โ€” where the sphere center is, in mm, "x y z".
  • --sphere-radius <arg> โ€” the radius of the sphere in mm, "x [y z]".
  • --volume-size <arg> โ€” the size of the output image in mm, "x [y z]".

๐ŸŒธ Examples ๐ŸŒธ

Example one โ€” make a cubic water phantom 30 x 30 x 40 cm, with the zero position sitting at the center of the water surface. iconic.

plastimatch synth \
  --pattern rect \
  --output water_tank.mha \
  --rect-size "-150 150 0 400 -150 150" \
  --origin "-245.5 245.5 -49.5 449.5 -149.5 149.5" \
  --spacing "1 1 1" \
  --dim "500 500 300"

Example two โ€” lung phantoms with two different tumor positions, output straight to dicom. two for one, we love to see it. ๐Ÿซ

plastimatch synth \
  --pattern lung \
  --output-dicom lung_inhale \
  --lung-tumor-pos "0 0 10"
plastimatch synth \
  --pattern lung \
  --output-dicom lung_exhale \
  --lung-tumor-pos "0 0 -10"

๐Ÿฆ‹ PLASTIMATCH SYNTH-VF ๐Ÿฆ‹

synth-vf is the vector field cousin. it creates a synthetic vector field, and you pick the kind by specifying the appropriate option. ๐Ÿ’ซ

the lineup:

  • gauss โ€” a gaussian warp
  • radial โ€” a radial expansion or contraction
  • translation โ€” a uniform translation
  • zero โ€” a vector field that is zero everywhere

usage, verbatim, mwah:

Usage: plastimatch synth-vf [options]
Options:
 --dim <arg>             size of output image in voxels "x [y z]"
 --direction-cosines <arg>
                         oriention of x, y, and z axes; Specify
                          either preset value, {identity,
                          rotated-{1,2,3}, sheared}, or 9 digit
                          matrix string "a b c d e f g h i"
 --fixed <arg>           An input image used to set the size of the
                          output
 --gauss-center <arg>    location of center of gaussian warp "x [y
                          z]"
 --gauss-mag <arg>       displacment magnitude for gaussian warp in
                          mm "x [y z]"
 --gauss-std <arg>       width of gaussian std in mm "x [y z]"
 --origin <arg>          location of first image voxel in mm "x y
                          z"
 --output <arg>          output filename
 --radial-center <arg>   location of center of radial warp "x [y
                          z]"
 --radial-mag <arg>      displacement magnitude for radial warp in
                          mm "x [y z]"
 --spacing <arg>         voxel spacing in mm "x [y z]"
 --volume-size <arg>     size of output image in mm "x [y z]"
 --xf-gauss              gaussian warp
 --xf-radial             radial expansion (or contraction)
 --xf-trans <arg>        uniform translation in mm "x y z"
 --xf-zero               Null transform

one bullet per option, as promised:

  • --dim <arg> โ€” size of the output image in voxels, "x [y z]".
  • --direction-cosines <arg> โ€” orientation of the x, y, and z axes. give a preset {identity, rotated-{1,2,3}, sheared}, or the 9 digit matrix string "a b c d e f g h i".
  • --fixed <arg> โ€” an input image used to set the size of the output.
  • --gauss-center <arg> โ€” the location of the center of the gaussian warp, "x [y z]".
  • --gauss-mag <arg> โ€” the displacement magnitude for the gaussian warp, in mm, "x [y z]".
  • --gauss-std <arg> โ€” the width of the gaussian std, in mm, "x [y z]".
  • --origin <arg> โ€” location of the first image voxel, in mm, "x y z".
  • --output <arg> โ€” output filename. ๐Ÿ’พ
  • --radial-center <arg> โ€” the location of the center of the radial warp, "x [y z]".
  • --radial-mag <arg> โ€” the displacement magnitude for the radial warp, in mm, "x [y z]".
  • --spacing <arg> โ€” voxel spacing in mm, "x [y z]".
  • --volume-size <arg> โ€” size of the output image in mm, "x [y z]".
  • --xf-gauss โ€” gaussian warp. no argument, she just does it.
  • --xf-radial โ€” radial expansion (or contraction).
  • --xf-trans <arg> โ€” uniform translation in mm, "x y z".
  • --xf-zero โ€” Null transform. everything is zero, the void, the slumber party of vector fields. ๐Ÿ’€

๐ŸŽ€ PLASTIMATCH THRESHOLD ๐ŸŽ€

threshold is here to create a binary labelmap image from an input intensity image. it takes your greyscale vibes and turns them into yes/no. slay. โœจ

usage:

Usage: plastimatch threshold [options]
Options:
    --above <arg>    value above which output has value high
    --below <arg>    value below which output has value high
-h, --help           display this help message
    --input <arg>    input directory or filename
    --output <arg>   output image
    --range <arg>    a string that forms a list of threshold ranges of the
                      form "r1-lo,r1-hi,r2-lo,r2-hi,...", such that voxels
                      with intensities within any of the ranges
                      ([r1-lo,r1-hi], [r2-lo,r2-hi], ...) have output value
                      high
    --version        display the program version

and the rundown:

  • --above <arg> โ€” the value above which the output has value high. โฌ†๏ธ
  • --below <arg> โ€” the value below which the output has value high. โฌ‡๏ธ
  • -h, --help โ€” display this help message.
  • --input <arg> โ€” input directory or filename.
  • --output <arg> โ€” output image.
  • --range <arg> โ€” a string that forms a list of threshold ranges of the form "r1-lo,r1-hi,r2-lo,r2-hi,...", such that voxels with intensities within any of the ranges ([r1-lo,r1-hi], [r2-lo,r2-hi], ...) have output value high. multi-range queen. ๐Ÿ‘‘
  • --version โ€” display the program version.

๐ŸŒˆ Example ๐ŸŒˆ

this command makes a binary label image with value 1 when input intensities are between 100 and 200, and value 0 otherwise:

plastimatch threshold \
  --input input_image.nrrd \
  --output output_labe.nrrd \
  --range "100,200"

โญ PLASTIMATCH THUMBNAIL โญ

thumbnail generates a two-dimensional thumbnail image of an axial slice of the input volume. it's giving profile pic energy ngl. ๐Ÿ–ผ๏ธ

important deets: the output image is not required to correspond exactly to an integer slice number, and the location of the output image within the slice is always centered. centered. balanced. main character.

usage:

Usage: plastimatch thumbnail [options] input-file
Options:
  --input file
  --output file
  --thumbnail-dim size
  --thumbnail-spacing size
  --slice-loc location

the options, bestie:

  • --input file โ€” your input file.
  • --output file โ€” your output file.
  • --thumbnail-dim size โ€” the thumbnail dimension.
  • --thumbnail-spacing size โ€” the thumbnail spacing.
  • --slice-loc location โ€” where the slice sits.

๐Ÿ’œ Example ๐Ÿ’œ

we're making a two-dimensional image with resolution 10 x 10 pixels, at axial location 0, and of size 20 x 20 mm:

plastimatch thumbnail \
  --input in.mha --output out.mha \
  --thumbnail-dim 10 \
  --thumbnail-spacing 2 \
  --slice-loc 0

๐ŸŒธ PLASTIMATCH UNION ๐ŸŒธ

union creates a binary volume which is the logical union of two input images. and the rule is so simple it's lowkey beautiful: a voxel in the output gets value one if it's non-zero in either input image, or value zero if it's zero in both input images. that's it. that's the whole vibe. ๐Ÿซถ

usage:

Usage: plastimatch union [options] input_1 input_2
Options:
 -h, --help           display this help message
     --output <arg>   filename for output image
     --version        display the program version

the options:

  • -h, --help โ€” display this help message.
  • --output <arg> โ€” filename for the output image.
  • --version โ€” display the program version.

๐ŸŽ€ Example ๐ŸŽ€

this command creates a volume that is the union of two input images:

plastimatch union \
  --output itv.mha \
  phase_1.mha phase_2.mha

๐ŸŒ€ PLASTIMATCH WARP ๐ŸŒ€

okay so warp is literally just a lil nickname for convert ๐Ÿ’… like they're the same command wearing different outfits. so if you wanna see all the flags and options and everything, go read plastimatch convert, bestie, that's where the whole menu lives ๐Ÿซถ


โœจ Examples โœจ

so like, you got your B-spline coefficients from plastimatch register (they're chillin in bspline.txt), and now you wanna actually warp an image with them? bet:

plastimatch warp \
  --input infile.nrrd \
  --output-img outfile.nrrd \
  --xf bspline.txt

lowkey important: in that one right there, the geometry of your output file? it comes straight from the geometry info inside the B-spline coefficient file. like it decided for you. iconic behavior honestly ๐Ÿ‘‘

but bestie, you can resample to a whole different geometry if you want โ€” just use --fixed, or --origin, --dim, and --spacing:

plastimatch warp \
  --input infile.nrrd \
  --output-img outfile.nrrd \
  --xf bspline.txt \
  --fixed reference.nrrd

now. when you're warping a structure set image, where those integer bits mean "which structure am I part of"? yeah you cannot use linear interpolation there, that would be a whole mess ๐Ÿ˜ญ you need nearest neighbor:

plastimatch warp \
  --input structures-in.nrrd \
  --output-img structures-out.nrrd \
  --xf bspline.txt \
  --interpolation nn

okay so sometimes voxels that were sitting outside the geometry of your input image get warped into the geometry of your output image. rude, but it happens. by default those areas get "filled in" with an intensity of zero. but if you want a different number there, the --default-value option is your girl:

plastimatch warp \
  --input infile.nrrd \
  --output-img outfile.nrrd \
  --xf bspline.txt \
  --default-value -1000

and it's not just images and structures, bestie โ€” landmarks exported from 3D Slicer can get warped too ๐ŸŽ€

plastimatch warp \
  --input fixed_landmarks.fcsv \
  --output-pointset warped_landmarks.fcsv \
  --xf bspline.txt

okay and sometimes you just wanna apply a transform that's explicitly defined by a vector field instead of using B-spline coefficients. valid. the --xf option accepts vector field volumes too ๐ŸŒˆ so like, that previous example would become:

plastimatch warp \
  --input fixed_landmarks.fcsv \
  --output-pointset warped_landmarks.fcsv \
  --xf vf.mha

๐Ÿ”„ PLASTIMATCH XF-CONVERT ๐Ÿ”„

the xf-convert command converts between transform types, periodt โœจ and a transform can be either a B-spline transform or a vector field. also fun fact: there are two different kinds of B-spline transform formats โ€” the plastimatch native format, and the ITK format ๐Ÿ‘€ and like, it's not just switching transform types either, xf-convert can also change the grid-spacing of B-spline transforms. multitasking queen ๐Ÿ’…

the command line usage goes a lil something like this:

Usage: plastimatch xf-convert [options]
Options:
  --dim <arg>            Size of output image in voxels "x [y z]"
  --grid-spacing <arg>   B-spline grid spacing in mm "x [y z]"
  --input <arg>          Input xform filename (required)
  --nobulk               Omit bulk transform for itk_bspline
  --origin <arg>         Location of first image voxel in mm "x y z"
  --output <arg>         Output xform filename (required)
  --output-type <arg>    Type of xform to create (required), choose
                          from {bspline, itk_bspline, vf}
  --spacing <arg>        Voxel spacing in mm "x [y z]"

๐ŸŒธ Example ๐ŸŒธ

say we wanna convert a B-spline transform into a vector field. if that B-spline transform is in native-format, then the vector field geometry is defined by the values found in the transform header:

plastimatch xf-convert \
  --input bspline.txt \
  --output vf.mha \
  --output-type vf

and likewise, if we wanna flip it and convert a vector field into a set of B-spline coefficients with a control-point spacing of 30 mm in each direction:

plastimatch xf-convert \
  --input vf.mha \
  --output bspline.txt \
  --output-type bspline \
  --grid-spacing 30

๐Ÿ‘‘ AUTHOR ๐Ÿ‘‘

Plastimatch is a collaborative project ๐Ÿซถ for additional documentation, please visit http://plastimatch.org. for questions, comments, and bug reports, please visit http://groups.google.com/group/plastimatch. (they wanna hear from you fr fr ๐Ÿ’–)


Plastimatch development team (C) 2010-2024. you are free to use, modify, and distribute plastimatch according to a BSD-style license. please see LICENSE.TXT for details ๐Ÿ’…


and that's a wrap on the whole page bestie, we did it ๐ŸŽ‰ this was Plastimatch 1.10.0, dated Sep 16, 2024, and honestly? she ate. go warp something iconic ๐Ÿ’–โœจ๐Ÿฆ‹

๐Ÿ“ฆ where this page comes from