GNU Astronomy Utilities



6.2.4.13 Mathematical morphology operators

From Wikipedia: “Mathematical morphology (MM) is a theory and technique for the analysis and processing of geometrical structures, based on set theory, lattice theory, topology, and random functions. MM is most commonly applied to digital images”. In theory it extends a very large body of research and methods in image processing, but currently in Gnuastro it mainly applies to images that are binary (only have a value of 0 or 1). For example, you have applied the greater-than operator (gt, see Conditional operators) to select all pixels in your image that are larger than a value of 100. But they will all have a value of 1, and you want to separate the various groups of pixels that are connected (for example, peaks of stars in your image). With the connected-components operator, you can give each connected region of the output of gt a separate integer label.

erode

Erode the foreground pixels (with value 1) of the input dataset (second popped operand). The first popped operand is the connectivity (see description in connected-components). Erosion is simply a flipping of all foreground pixels (with value 1) to background (with value 0) that are “touching” background pixels. “Touching” is defined by the connectivity.

In effect, this operator “carves off” the outer borders of the foreground, making them thinner. This operator assumes a binary dataset (all pixels are 0 or 1). For example, imagine that you have an astronomical image with a mean/sky value of 0 units and a standard deviation (\(\sigma\)) of 100 units and many galaxies in it. With the first command below, you can apply a threshold of \(2\sigma\) on the image (by only keeping pixels that are greater than 200 using the gt operator). The output of thresholding the image is a binary image (each pixel is either smaller or equal to the threshold or larger than it). You can then erode the binary image with the second command below to remove very small false positives (one or two pixel peaks).

$ astarithmetic image.fits 100 gt -obinary.fits
$ astarithmetic binary.fits 2 erode -oout.fits

In fact, you can merge these operations into one command thanks to the reverse polish notation (see Reverse polish notation):

$ astarithmetic image.fits 100 gt 2 erode -oout.fits

To see the effect of connectivity, try this:

$ astarithmetic image.fits 100 gt 1 erode -oout-con-1.fits
dilate

Dilate the foreground pixels (with value 1) of the binary input dataset (second popped operand). The first popped operand is the connectivity (see description in connected-components). Dilation is simply a flipping of all background pixels (with value 0) to foreground (with value 1) that are “touching” foreground pixels. “Touching” is defined by the connectivity. In effect, this expands the outer borders of the foreground. This operator assumes a binary dataset (all pixels are 0 and 1). The usage is similar to erode, for example:

$ astarithmetic binary.fits 2 dilate -oout.fits
number-neighbors

Return a dataset of the same size as the second popped operand, but where each non-zero and non-blank input pixel is replaced with the number of its non-zero and non-blank neighbors. The first popped operand is the connectivity (see above) and must be a single-value of an integer type. The dataset is assumed to be binary (having an unsigned, 8-bit dataset).

For example with the command below, you can select all pixels above a value of 100 in your image with the “greater-than” or gt operator (see Conditional operators). Recall that the output of all conditional operators is a binary output (having a value of 0 or 1). In the same command, we will then find how many neighboring pixels of each pixel (that was originally above the threshold) are also above the threshold.

$ astarithmetic image.fits 100 gt 2 number-neighbors
connected-components

Find the connected components in the input dataset (second popped operand). The first popped is the connectivity used in the connected components algorithm. The second popped operand is the dataset where connected components are to be found. It is assumed to be a binary image (with values of 0 or 1). It must have an 8-bit unsigned integer type which is the format produced by conditional operators. This operator will return a labeled dataset where the non-zero pixels in the input will be labeled with a counter (starting from 1).

The connectivity is a number between 1 and the number of dimensions in the dataset (inclusive). 1 corresponds to the weakest (symmetric) connectivity between elements and the number of dimensions the strongest. For example, on a 2D image, a connectivity of 1 corresponds to 4-connected neighbors and 2 corresponds to 8-connected neighbors.

One example usage of this operator can be the identification of regions above a certain threshold, as in the command below. With this command, Arithmetic will first separate all pixels greater than 100 into a binary image (where pixels with a value of 1 are above that value). Afterwards, it will label all those that are connected.

$ astarithmetic in.fits 100 gt 2 connected-components

If your input dataset does not have a binary type, but you know all its values are 0 or 1, you can use the uint8 operator (below) to convert it to binary.

fill-holes

Flip background (0) pixels surrounded by foreground (1) in a binary dataset. This operator takes two operands (similar to connected-components): the second is the binary (0 or 1 valued) dataset to fill holes in and the first popped operand is the connectivity (to define a hole). Imagine that in your dataset there are some holes with zero value inside the objects with one value (for example, the output of the thresholding example of erode) and you want to fill the holes:

$ astarithmetic binary.fits 2 fill-holes
invert

Invert an unsigned integer dataset (will not work on other data types, see Numeric data types). This is the only operator that ignores blank values (which are set to be the maximum values in the unsigned integer types).

This is useful in cases where the target(s) has(have) been imaged in absorption as raw formats (which are unsigned integer types). With this option, the maximum value for the given type will be subtracted from each pixel value, thus “inverting” the image, so the target(s) can be treated as emission. This can be useful when the higher-level analysis methods/tools only work on emission (positive skew in the noise, not negative).

$ astarithmetic image.fits invert