## 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_size
                                                            (GwyDataField *grain_field,
                                                             gint size);
    void                gwy_data_field_grains_remove_by_height
                                                            (GwyDataField *data_field,
                                                             GwyDataField *grain_field,
                                                             gdouble threshval,
                                                             gboolean below);
    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);
    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_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);
    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_grains_splash_water  (GwyDataField *data_field,
                                                             GwyDataField *minima,
                                                             gint locate_steps,
                                                             gdouble locate_dropsize);

## 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_size ()

    void                gwy_data_field_grains_remove_by_size
                                                            (GwyDataField *grain_field,
                                                             gint size);

Removes all grain 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_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_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_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`.

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 do 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` : | An 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_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 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()`.

`data_field` : | A data field.
`target_line` : | A data line to store the distribution to. It will be resampled to 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_grains_splash_water ()

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

`data_field` : |
`minima` : |
`locate_steps` : |
`locate_dropsize` : |