grains

grains — Grain detection and processing

Synopsis

#include <libprocess/gwyprocess.h>

void                gwy_data_field_grains_mark_curvature
                                                        (GwyDataField *data_field,
                                                         GwyDataField *grain_field,
                                                         gdouble threshval,
                                                         gboolean below);
void                gwy_data_field_grains_mark_watershed
                                                        (GwyDataField *data_field,
                                                         GwyDataField *grain_field,
                                                         gint locate_steps,
                                                         gint locate_thresh,
                                                         gdouble locate_dropsize,
                                                         gint wshed_steps,
                                                         gdouble wshed_dropsize,
                                                         gboolean prefilter,
                                                         gboolean below);
gboolean            gwy_data_field_grains_remove_grain  (GwyDataField *grain_field,
                                                         gint col,
                                                         gint row);
gboolean            gwy_data_field_grains_extract_grain (GwyDataField *grain_field,
                                                         gint col,
                                                         gint row);
void                gwy_data_field_grains_remove_by_number
                                                        (GwyDataField *grain_field,
                                                         gint number);
void                gwy_data_field_grains_remove_by_size
                                                        (GwyDataField *grain_field,
                                                         gint size);
void                gwy_data_field_grains_remove_by_height
                                                        (GwyDataField *data_field,
                                                         GwyDataField *grain_field,
                                                         gdouble threshval,
                                                         gboolean below);
void                gwy_data_field_grains_remove_touching_border
                                                        (GwyDataField *grain_field);
GwyComputationState * gwy_data_field_grains_watershed_init
                                                        (GwyDataField *data_field,
                                                         GwyDataField *grain_field,
                                                         gint locate_steps,
                                                         gint locate_thresh,
                                                         gdouble locate_dropsize,
                                                         gint wshed_steps,
                                                         gdouble wshed_dropsize,
                                                         gboolean prefilter,
                                                         gboolean below);
void                gwy_data_field_grains_watershed_iteration
                                                        (GwyComputationState *state);
void                gwy_data_field_grains_watershed_finalize
                                                        (GwyComputationState *state);
void                gwy_data_field_grains_mark_height   (GwyDataField *data_field,
                                                         GwyDataField *grain_field,
                                                         gdouble threshval,
                                                         gboolean below);
void                gwy_data_field_grains_mark_slope    (GwyDataField *data_field,
                                                         GwyDataField *grain_field,
                                                         gdouble threshval,
                                                         gboolean below);
gdouble             gwy_data_field_otsu_threshold       (GwyDataField *data_field);
void                gwy_data_field_grains_add           (GwyDataField *grain_field,
                                                         GwyDataField *add_field);
void                gwy_data_field_grains_intersect     (GwyDataField *grain_field,
                                                         GwyDataField *intersect_field);
gint                gwy_data_field_number_grains        (GwyDataField *mask_field,
                                                         gint *grains);
gint                gwy_data_field_number_grains_periodic
                                                        (GwyDataField *mask_field,
                                                         gint *grains);
gint *              gwy_data_field_get_grain_bounding_boxes
                                                        (GwyDataField *mask_field,
                                                         gint ngrains,
                                                         const gint *grains,
                                                         gint *bboxes);
GwyDataLine *       gwy_data_field_grains_get_distribution
                                                        (GwyDataField *data_field,
                                                         GwyDataField *grain_field,
                                                         GwyDataLine *distribution,
                                                         gint ngrains,
                                                         const gint *grains,
                                                         GwyGrainQuantity quantity,
                                                         gint nstats);
gdouble *           gwy_data_field_grains_get_values    (GwyDataField *data_field,
                                                         gdouble *values,
                                                         gint ngrains,
                                                         const gint *grains,
                                                         GwyGrainQuantity quantity);
gdouble **          gwy_data_field_grains_get_quantities
                                                        (GwyDataField *data_field,
                                                         gdouble **values,
                                                         const GwyGrainQuantity *quantities,
                                                         guint nquantities,
                                                         guint ngrains,
                                                         const gint *grains);
gboolean            gwy_grain_quantity_needs_same_units (GwyGrainQuantity quantity);
GwySIUnit *         gwy_grain_quantity_get_units        (GwyGrainQuantity quantity,
                                                         GwySIUnit *siunitxy,
                                                         GwySIUnit *siunitz,
                                                         GwySIUnit *result);
void                gwy_data_field_area_grains_tgnd     (GwyDataField *data_field,
                                                         GwyDataLine *target_line,
                                                         gint col,
                                                         gint row,
                                                         gint width,
                                                         gint height,
                                                         gboolean below,
                                                         gint nstats);
void                gwy_data_field_area_grains_tgnd_range
                                                        (GwyDataField *data_field,
                                                         GwyDataLine *target_line,
                                                         gint col,
                                                         gint row,
                                                         gint width,
                                                         gint height,
                                                         gdouble min,
                                                         gdouble max,
                                                         gboolean below,
                                                         gint nstats);
void                gwy_data_field_grains_splash_water  (GwyDataField *data_field,
                                                         GwyDataField *minima,
                                                         gint locate_steps,
                                                         gdouble locate_dropsize);
void                gwy_data_field_grain_distance_transform
                                                        (GwyDataField *data_field);
gboolean            gwy_data_field_fill_voids           (GwyDataField *data_field,
                                                         gboolean nonsimple);
gint                gwy_data_field_waterpour            (GwyDataField *data_field,
                                                         GwyDataField *result,
                                                         gint *grains);
void                gwy_data_field_mark_extrema         (GwyDataField *dfield,
                                                         GwyDataField *extrema,
                                                         gboolean maxima);

Description

Details

gwy_data_field_grains_mark_curvature ()

void                gwy_data_field_grains_mark_curvature
                                                        (GwyDataField *data_field,
                                                         GwyDataField *grain_field,
                                                         gdouble threshval,
                                                         gboolean below);

Marks data that are above/below curvature threshold.

data_field :

Data to be used for marking.

grain_field :

Data field to store the resulting mask to.

threshval :

Relative curvature threshold, in percents.

below :

If TRUE, data below threshold are marked, otherwise data above threshold are marked.

gwy_data_field_grains_mark_watershed ()

void                gwy_data_field_grains_mark_watershed
                                                        (GwyDataField *data_field,
                                                         GwyDataField *grain_field,
                                                         gint locate_steps,
                                                         gint locate_thresh,
                                                         gdouble locate_dropsize,
                                                         gint wshed_steps,
                                                         gdouble wshed_dropsize,
                                                         gboolean prefilter,
                                                         gboolean below);

Performs watershed algorithm.

data_field :

Data to be used for marking.

grain_field :

Result of marking (mask).

locate_steps :

Locating algorithm steps.

locate_thresh :

Locating algorithm threshold.

locate_dropsize :

Locating drop size.

wshed_steps :

Watershed steps.

wshed_dropsize :

Watershed drop size.

prefilter :

Use prefiltering.

below :

If TRUE, valleys are marked, otherwise mountains are marked.

gwy_data_field_grains_remove_grain ()

gboolean            gwy_data_field_grains_remove_grain  (GwyDataField *grain_field,
                                                         gint col,
                                                         gint row);

Removes one grain at given position.

grain_field :

Field of marked grains (mask).

col :

Column inside a grain.

row :

Row inside a grain.

Returns :

TRUE if a grain was actually removed (i.e., (col,row) was inside a grain).

gwy_data_field_grains_extract_grain ()

gboolean            gwy_data_field_grains_extract_grain (GwyDataField *grain_field,
                                                         gint col,
                                                         gint row);

Removes all grains except that one at given position.

If there is no grain at (col, row), all grains are removed.

grain_field :

Field of marked grains (mask).

col :

Column inside a grain.

row :

Row inside a grain.

Returns :

TRUE if a grain remained (i.e., (col,row) was inside a grain).

gwy_data_field_grains_remove_by_number ()

void                gwy_data_field_grains_remove_by_number
                                                        (GwyDataField *grain_field,
                                                         gint number);

Removes grain identified by number.

grain_field :

Field of marked grains (mask).

number :

Grain number was filled by gwy_data_field_number_grains().

Since 2.35


gwy_data_field_grains_remove_by_size ()

void                gwy_data_field_grains_remove_by_size
                                                        (GwyDataField *grain_field,
                                                         gint size);

Removes all grains below specified area.

grain_field :

Field of marked grains (mask).

size :

Grain area threshold, in square pixels.

gwy_data_field_grains_remove_by_height ()

void                gwy_data_field_grains_remove_by_height
                                                        (GwyDataField *data_field,
                                                         GwyDataField *grain_field,
                                                         gdouble threshval,
                                                         gboolean below);

Removes grains that are higher/lower than given threshold value.

data_field :

Data to be used for marking

grain_field :

Field of marked grains (mask)

threshval :

Relative height threshold, in percents.

below :

If TRUE, grains below threshold are removed, otherwise grains above threshold are removed.

gwy_data_field_grains_remove_touching_border ()

void                gwy_data_field_grains_remove_touching_border
                                                        (GwyDataField *grain_field);

Removes all grains that touch field borders.

grain_field :

Field of marked grains (mask).

Since 2.30


gwy_data_field_grains_watershed_init ()

GwyComputationState * gwy_data_field_grains_watershed_init
                                                        (GwyDataField *data_field,
                                                         GwyDataField *grain_field,
                                                         gint locate_steps,
                                                         gint locate_thresh,
                                                         gdouble locate_dropsize,
                                                         gint wshed_steps,
                                                         gdouble wshed_dropsize,
                                                         gboolean prefilter,
                                                         gboolean below);

Initializes the watershed algorithm.

This iterator reports its state as GwyWatershedStateType.

data_field :

Data to be used for marking.

grain_field :

Result of marking (mask).

locate_steps :

Locating algorithm steps.

locate_thresh :

Locating algorithm threshold.

locate_dropsize :

Locating drop size.

wshed_steps :

Watershed steps.

wshed_dropsize :

Watershed drop size.

prefilter :

Use prefiltering.

below :

If TRUE, valleys are marked, otherwise mountains are marked.

Returns :

A new watershed iterator.

gwy_data_field_grains_watershed_iteration ()

void                gwy_data_field_grains_watershed_iteration
                                                        (GwyComputationState *state);

Performs one iteration of the watershed algorithm.

Fields state and progress fraction of watershed state are updated (fraction is calculated for each phase individually). Once state becomes GWY_WATERSHED_STATE_FINISHED, the calculation is finised.

A watershed iterator can be created with gwy_data_field_grains_watershed_init(). When iteration ends, either by finishing or being aborted, gwy_data_field_grains_watershed_finalize() must be called to release allocated resources.

state :

Watershed iterator.

gwy_data_field_grains_watershed_finalize ()

void                gwy_data_field_grains_watershed_finalize
                                                        (GwyComputationState *state);

Destroys a watershed iterator, freeing all resources.

state :

Watershed iterator.

gwy_data_field_grains_mark_height ()

void                gwy_data_field_grains_mark_height   (GwyDataField *data_field,
                                                         GwyDataField *grain_field,
                                                         gdouble threshval,
                                                         gboolean below);

Marks data that are above/below height threshold.

data_field :

Data to be used for marking.

grain_field :

Data field to store the resulting mask to.

threshval :

Relative height threshold, in percents.

below :

If TRUE, data below threshold are marked, otherwise data above threshold are marked.

gwy_data_field_grains_mark_slope ()

void                gwy_data_field_grains_mark_slope    (GwyDataField *data_field,
                                                         GwyDataField *grain_field,
                                                         gdouble threshval,
                                                         gboolean below);

Marks data that are above/below slope threshold.

data_field :

Data to be used for marking.

grain_field :

Data field to store the resulting mask to.

threshval :

Relative slope threshold, in percents.

below :

If TRUE, data below threshold are marked, otherwise data above threshold are marked.

gwy_data_field_otsu_threshold ()

gdouble             gwy_data_field_otsu_threshold       (GwyDataField *data_field);

Finds Otsu's height threshold for a data field.

The Otsu's threshold is optimal in the sense that it minimises the inter-class variances of two classes of pixels: above and below theshold.

data_field :

A data field.

Since 2.37


gwy_data_field_grains_add ()

void                gwy_data_field_grains_add           (GwyDataField *grain_field,
                                                         GwyDataField *add_field);

Adds add_field grains to grain_field.

Note: This function is equivalent to gwy_data_field_max_of_fields(grain_field, grain_field, add_field); and it will be probably removed someday.

grain_field :

Field of marked grains (mask).

add_field :

Field of marked grains (mask) to be added.

gwy_data_field_grains_intersect ()

void                gwy_data_field_grains_intersect     (GwyDataField *grain_field,
                                                         GwyDataField *intersect_field);

Performs intersection betweet two grain fields, result is stored in grain_field.

Note: This function is equivalent to gwy_data_field_min_of_fields(grain_field, grain_field, intersect_field); and it will be probably removed someday.

grain_field :

field of marked grains (mask).

intersect_field :

Field of marked grains (mask).

gwy_data_field_number_grains ()

gint                gwy_data_field_number_grains        (GwyDataField *mask_field,
                                                         gint *grains);

Numbers grains in a mask data field.

mask_field :

Data field containing positive values in grains, nonpositive in free space.

grains :

Zero-filled array of integers of equal size to mask_field to put grain numbers to. Empty space will be left 0, pixels inside a grain will be set to grain number. Grains are numbered sequentially 1, 2, 3, ...

Returns :

The number of last grain (note they are numbered from 1).

gwy_data_field_number_grains_periodic ()

gint                gwy_data_field_number_grains_periodic
                                                        (GwyDataField *mask_field,
                                                         gint *grains);

Numbers grains in a periodic mask data field.

This function differs from gwy_data_field_number_grains() by the assumption of periodicity, i.e. grains can touch across the opposite field edges.

mask_field :

Data field containing positive values in grains, nonpositive in free space.

grains :

Zero-filled array of integers of equal size to mask_field to put grain numbers to. Empty space will be left 0, pixels inside a grain will be set to grain number. Grains are numbered sequentially 1, 2, 3, ...

Returns :

The number of last grain (note they are numbered from 1).

Since 2.38


gwy_data_field_get_grain_bounding_boxes ()

gint *              gwy_data_field_get_grain_bounding_boxes
                                                        (GwyDataField *mask_field,
                                                         gint ngrains,
                                                         const gint *grains,
                                                         gint *bboxes);

Find bounding boxes of all grains.

mask_field :

Data field containing positive values in grains, nonpositive in free space. However its contents is ignored as all grain information is taken from grains (its dimensions determine the dimensions of grains).

ngrains :

The number of grains as returned by gwy_data_field_number_grains().

grains :

Grain numbers filled with gwy_data_field_number_grains().

bboxes :

Array of size at least 4*(ngrains+1) to fill with grain bounding boxes (as usual zero does not correspond to any grain, grains start from 1). The bounding boxes are stored as quadruples of indices: (xmin, ymin, width, height). It can be NULL to allocate a new array.

Returns :

Either bboxes (if it was not NULL), or a newly allocated array of size 4(ngrains + 1).

Since 2.3


gwy_data_field_grains_get_distribution ()

GwyDataLine *       gwy_data_field_grains_get_distribution
                                                        (GwyDataField *data_field,
                                                         GwyDataField *grain_field,
                                                         GwyDataLine *distribution,
                                                         gint ngrains,
                                                         const gint *grains,
                                                         GwyGrainQuantity quantity,
                                                         gint nstats);

Computes distribution of requested grain characteristics.

Puts number of grains vs. grain value data into distribution, units, scales and offsets of distribution are updated accordingly.

data_field :

Data field used for marking. For some quantities its values are not used, but units and physical dimensions are always taken from it.

grain_field :

Data field (mask) of marked grains. Note if you pass non-NULL grains all grain information is taken from it and grain_field can be even NULL then.

distribution :

Data line to store grain distribution to.

ngrains :

The number of grains as returned by gwy_data_field_number_grains(). Ignored in grains is NULL.

grains :

Grain numbers filled with gwy_data_field_number_grains() if you have it, or NULL (the function then finds grain numbers itself which is not efficient for repeated use on the same grain field).

quantity :

The quantity to calculate.

nstats :

The number of samples to take on the distribution function. If nonpositive, a suitable resolution is determined automatically.

Returns :

A data line with the distribution: distribution itself if it was not NULL, otherwise a newly created GwyDataLine caller must destroy. If there are no grains, NULL is returned and distribution is not changed.

gwy_data_field_grains_get_values ()

gdouble *           gwy_data_field_grains_get_values    (GwyDataField *data_field,
                                                         gdouble *values,
                                                         gint ngrains,
                                                         const gint *grains,
                                                         GwyGrainQuantity quantity);

Calculates characteristics of grains.

This is a bit low-level function, see also gwy_data_field_grains_get_distribution().

The array values will be filled with the requested grain value for each individual grain (0th item of values which does not correspond to any grain will be overwritten with an arbitrary value and should be ignored).

The grain numbers serve as indices in values. Therefore as long as the same grains is used, the same position in values corresponds to the same particular grain. This enables one for instance to calculate grain sizes and grain heights and then correlate them.

data_field :

Data field used for marking. For some quantities its values are not used, but its dimensions determine the dimensions of grains.

values :

Array of size ngrains+1 to put grain values to. It can be NULL to allocate and return a new array.

ngrains :

The number of grains as returned by gwy_data_field_number_grains().

grains :

Grain numbers filled with gwy_data_field_number_grains().

quantity :

The quantity to calculate.

Returns :

values itself if it was not NULL, otherwise a newly allocated array that caller has to free.

gwy_data_field_grains_get_quantities ()

gdouble **          gwy_data_field_grains_get_quantities
                                                        (GwyDataField *data_field,
                                                         gdouble **values,
                                                         const GwyGrainQuantity *quantities,
                                                         guint nquantities,
                                                         guint ngrains,
                                                         const gint *grains);

Calculates multiple characteristics of grains simultaneously.

See gwy_data_field_grains_get_values() for some discussion. This function is more efficient if several grain quantities need to be calculated since gwy_data_field_grains_get_values() can do lot of repeated work in such case.

data_field :

Data field used for marking. For some quantities its values are not used, but its dimensions determine the dimensions of grains.

values :

Array of nquantities pointers to blocks of length ngrains+1 to put the calculated grain values to. Each block corresponds to one requested quantity. NULL can be passed to allocate and return a new array.

quantities :

Array of nquantities items that specify the requested GwyGrainQuantity to put to corresponding items in values. Quantities can repeat.

nquantities :

The number of requested different grain values.

ngrains :

The number of grains as returned by gwy_data_field_number_grains().

grains :

Grain numbers filled with gwy_data_field_number_grains().

Returns :

values itself if it was not NULL, otherwise a newly allocated array that caller has to free with g_free(), including the contained arrays.

Since 2.22


gwy_grain_quantity_needs_same_units ()

gboolean            gwy_grain_quantity_needs_same_units (GwyGrainQuantity quantity);

Tests whether a grain quantity is defined only when lateral and value units match.

quantity :

A grain quantity.

Returns :

TRUE if quantity is meaningless when lateral and value units differ, FALSE if it is always defined.

Since 2.7


gwy_grain_quantity_get_units ()

GwySIUnit *         gwy_grain_quantity_get_units        (GwyGrainQuantity quantity,
                                                         GwySIUnit *siunitxy,
                                                         GwySIUnit *siunitz,
                                                         GwySIUnit *result);

Calculates the units of a grain quantity.

quantity :

A grain quantity.

siunitxy :

Lateral SI unit of data.

siunitz :

Value SI unit of data.

result :

An SI unit to set to the units of quantity. It can be NULL, a new SI unit is created then and returned.

Returns :

When result is NULL, a newly creates SI unit that has to be dereferenced when no longer used later. Otherwise result itself is simply returned, its reference count is NOT increased.

Since 2.7


gwy_data_field_area_grains_tgnd ()

void                gwy_data_field_area_grains_tgnd     (GwyDataField *data_field,
                                                         GwyDataLine *target_line,
                                                         gint col,
                                                         gint row,
                                                         gint width,
                                                         gint height,
                                                         gboolean below,
                                                         gint nstats);

Calculates threshold grain number distribution.

This function is a simple gwy_data_field_area_grains_tgnd_range() that calculates the distribution in the full range.

data_field :

A data field.

target_line :

A data line to store the distribution to. It will be resampled to the requested width.

col :

Upper-left column coordinate.

row :

Upper-left row coordinate.

width :

Area width (number of columns).

height :

Area height (number of rows).

below :

If TRUE, valleys are marked, otherwise mountains are marked.

nstats :

The number of samples to take on the distribution function. If nonpositive, a suitable resolution is determined automatically.

gwy_data_field_area_grains_tgnd_range ()

void                gwy_data_field_area_grains_tgnd_range
                                                        (GwyDataField *data_field,
                                                         GwyDataLine *target_line,
                                                         gint col,
                                                         gint row,
                                                         gint width,
                                                         gint height,
                                                         gdouble min,
                                                         gdouble max,
                                                         gboolean below,
                                                         gint nstats);

Calculates threshold grain number distribution in given height range.

This is the number of grains for each of nstats equidistant height threshold levels. For large nstats this function is much faster than the equivalent number of gwy_data_field_grains_mark_height() calls.

data_field :

A data field.

target_line :

A data line to store the distribution to. It will be resampled to the requested width.

col :

Upper-left column coordinate.

row :

Upper-left row coordinate.

width :

Area width (number of columns).

height :

Area height (number of rows).

min :

Minimum threshold value.

max :

Maximum threshold value.

below :

If TRUE, valleys are marked, otherwise mountains are marked.

nstats :

The number of samples to take on the distribution function. If nonpositive, a suitable resolution is determined automatically.

gwy_data_field_grains_splash_water ()

void                gwy_data_field_grains_splash_water  (GwyDataField *data_field,
                                                         GwyDataField *minima,
                                                         gint locate_steps,
                                                         gdouble locate_dropsize);


gwy_data_field_grain_distance_transform ()

void                gwy_data_field_grain_distance_transform
                                                        (GwyDataField *data_field);

Performs Euclidean distance transform of a data field with grains.

Each non-zero value will be replaced with Euclidean distance to the grain boundary, measured in pixels.

data_field :

A data field with zeroes in empty space and nonzeroes in grains.

Since 2.36


gwy_data_field_fill_voids ()

gboolean            gwy_data_field_fill_voids           (GwyDataField *data_field,
                                                         gboolean nonsimple);

Fills voids in grains in a data field representing a mask.

Voids in grains are zero pixels in data_field from which no path exists through other zero pixels to the field boundary. The paths are considered in 8-connectivity because grains themselves are considered in 4-connectivity.

data_field :

A data field with zeroes in empty space and nonzeroes in grains.

nonsimple :

Pass TRUE to fill also voids that are not simple-connected (e.g. ring-like). This can result in grain merging if a small grain is contained within a void. Pass FALSE to fill only simple-connected grains.

Returns :

TRUE if any voids were filled at all, FALSE if no change was made.

Since 2.37


gwy_data_field_waterpour ()

gint                gwy_data_field_waterpour            (GwyDataField *data_field,
                                                         GwyDataField *result,
                                                         gint *grains);

Performs the classical Vincent watershed segmentation of a data field.

The segmentation always results in the entire field being masked with the exception of thin (8-connectivity) lines separating the segments (grains).

Compared to gwy_data_field_grains_mark_watershed(), this algorithm is very fast. However, when used alone, it typically results in a serious oversegmentation as each local minimum gives raise to a grain. Furthermore, the full segmentation means that also pixels which would be considered outside any grain in the topographical sense will be assigned to some catchment basin. Therefore, pre- or postprocessing is usually necessary, using the gradient image or a more sophisticated method.

The function does not assign pixels with value HUGE_VAL or larger to any segment. This can be used to pre-mark certain areas explicitly as boundaries.

Since the algorithm numbers the grains as a side effect, you can pass a grains array and get the grain numbers immediatelly, avoiding the relatively (although not drastically) expensive gwy_data_field_number_grains() call.

data_field :

A data field to segmentate.

result :

Data field that will be filled with the resulting mask. It will be resized to the dimensions of data_field and its properties set accordingly.

grains :

Optionally, an array with the same number of items as data_field. If non-NULL, it will be filled with grain numbers in the same manner as gwy_data_field_number_grains(). Pass NULL to ignore.

Returns :

The number of segments (grains) in the result, excluding the separators, i.e. the same convention as in gwy_data_field_number_grains() is used.

Since 2.37


gwy_data_field_mark_extrema ()

void                gwy_data_field_mark_extrema         (GwyDataField *dfield,
                                                         GwyDataField *extrema,
                                                         gboolean maxima);