| Title: | Cell Segmentation for Histology with Human-in-the-Loop Training |
|---|---|
| Description: | Cell segmentation for histology and multiplexed tissue imaging. Provides classical segmentation methods (adaptive thresholding, watershed, Voronoi propagation), wrappers through 'reticulate' for the deep learning models 'Cellpose' (Stringer et al. (2021) <doi:10.1038/s41592-020-01018-x>), 'StarDist' (Schmidt et al. (2018) <doi:10.1007/978-3-030-00934-2_30>) and 'Mesmer' (Greenwald et al. (2022) <doi:10.1038/s41587-021-01094-0>), and a human-in-the-loop iterative refinement workflow. A 'shiny' application lets researchers annotate, correct, train, evaluate and download custom segmentation models without leaving R. Versioned declarative segmentation protocols, a neutral interchange format (JSON manifests, integer label TIFF, GeoJSON, measurement tables with SHA-256 inventories), training dataset manifests with grouped splits, and readable 'QuPath' script templates with a 'StarDist' parameter adapter support reproducible exchange with 'QuPath' and partner packages. |
| Authors: | R. Heller [aut, cre, cph] (ORCID: <https://orcid.org/0000-0001-8006-9742>) |
| Maintainer: | R. Heller <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.2.0 |
| Built: | 2026-11-03 18:19:56 UTC |
| Source: | https://github.com/CTTIR/segmantR |
Constructor for the sg_image S3 class, which represents a
multi-channel image with associated metadata.
new_sg_image( pixels, channels = NULL, resolution = NULL, metadata = list(), id = NULL, plane = NULL, origin = NULL, bands = NULL, value_semantics = "unknown", source_digest = NULL, transform_digest = NULL, provenance = list() )new_sg_image( pixels, channels = NULL, resolution = NULL, metadata = list(), id = NULL, plane = NULL, origin = NULL, bands = NULL, value_semantics = "unknown", source_digest = NULL, transform_digest = NULL, provenance = list() )
pixels |
Numeric array of dimensions H x W (grayscale) or H x W x C (multi-channel). |
channels |
Character vector of channel names. If |
resolution |
Named list with |
metadata |
Named list of additional image metadata. |
id |
Optional stable image identifier (string). Absolute file paths must not be used as identity. |
plane |
Optional list with zero-based |
origin |
Optional list with |
bands |
Optional data frame describing channels/bands with columns
|
value_semantics |
What pixel values represent: one of |
source_digest |
Optional |
transform_digest |
Optional digest of transformations applied to the source. |
provenance |
Named list of provenance records. |
The pixel array order is always [y, x, channel]: the first array row
is the top image row. All arguments after metadata are optional
interchange fields added in segmantR 0.2.0; objects created by older
code simply lack them and are treated with the documented defaults.
An object of class sg_image.
pixels <- matrix(runif(100), nrow = 10, ncol = 10) img <- new_sg_image(pixels) print(img) # With interchange metadata img2 <- new_sg_image(pixels, channels = "DAPI", resolution = list(x_um = 0.5, y_um = 0.5), id = "slide-001", value_semantics = "intensity")pixels <- matrix(runif(100), nrow = 10, ncol = 10) img <- new_sg_image(pixels) print(img) # With interchange metadata img2 <- new_sg_image(pixels, channels = "DAPI", resolution = list(x_um = 0.5, y_um = 0.5), id = "slide-001", value_semantics = "intensity")
Constructor for the sg_mask S3 class, which stores an integer label
matrix where 0 represents background and positive integers represent
individual cell IDs.
new_sg_mask( labels, image_id = NULL, model_info = NULL, mask_type = c("instance", "labelled", "binary"), legend = NULL, plane = NULL, origin = NULL, status = c("draft", "staged", "reviewed"), provenance = list(), id = NULL )new_sg_mask( labels, image_id = NULL, model_info = NULL, mask_type = c("instance", "labelled", "binary"), legend = NULL, plane = NULL, origin = NULL, status = c("draft", "staged", "reviewed"), provenance = list(), id = NULL )
labels |
Integer matrix of cell labels. 0 = background, positive values = cell IDs (gaps are allowed). Values must be finite whole numbers from 0 to 2147483647; larger uint32 IDs are unsupported and rejected before integer conversion. |
image_id |
Optional character string identifying the source image. |
model_info |
Optional named list of model metadata. |
mask_type |
One of |
legend |
Optional data frame with one row per positive label and
columns |
plane |
Optional plane list (see |
origin |
Optional origin list (see |
status |
Review status: |
provenance |
Named list of provenance records. |
id |
Optional mask identifier. |
Masks follow the segmantR mask contract: integer values, 0 is the
background, positive integers are object instances (mask_type = "instance", the default and historic meaning), class codes
("labelled") or foreground ("binary", values 0/1 only). All arguments
after model_info are optional interchange fields.
An object of class sg_mask.
labels <- matrix(c(0L, 0L, 1L, 1L, 0L, 2L, 2L, 0L, 0L), nrow = 3) mask <- new_sg_mask(labels) print(mask)labels <- matrix(c(0L, 0L, 1L, 1L, 0L, 2L, 2L, 0L, 0L), nrow = 3) mask <- new_sg_mask(labels) print(mask)
Constructor for the sg_trained_model S3 class, representing a trained
segmentation model with associated metadata.
new_sg_trained_model( model_path, backend = c("cellpose", "stardist"), base_model, training_metrics, model_card = list(), runtime = NULL, dataset_manifest = NULL, license = NULL, representation = "unknown" )new_sg_trained_model( model_path, backend = c("cellpose", "stardist"), base_model, training_metrics, model_card = list(), runtime = NULL, dataset_manifest = NULL, license = NULL, representation = "unknown" )
model_path |
Character. Path to the trained model weights. |
backend |
Character. Segmentation backend: |
base_model |
Character. Name of the base model that was fine-tuned. |
training_metrics |
Named list of training metrics (e.g., loss curve, number of epochs). |
model_card |
Named list of model card metadata (description, author,
intended use, etc.). The versioned card written by |
runtime |
Optional runtime description (list) recorded at training time; never a copy of a Python environment. |
dataset_manifest |
Optional |
license |
Optional list with |
representation |
Weight representation: |
An object of class sg_trained_model.
# a dedicated directory with a stand-in weight file weights <- file.path(tempfile("model"), "cellpose_weights") dir.create(dirname(weights)) writeBin(as.raw(1:16), weights) mdl <- new_sg_trained_model( model_path = weights, backend = "cellpose", base_model = "cyto3", training_metrics = list(n_epochs = 100L, final_loss = 0.05) ) print(mdl)# a dedicated directory with a stand-in weight file weights <- file.path(tempfile("model"), "cellpose_weights") dir.create(dirname(weights)) writeBin(as.raw(1:16), weights) mdl <- new_sg_trained_model( model_path = weights, backend = "cellpose", base_model = "cyto3", training_metrics = list(n_epochs = 100L, final_loss = 0.05) ) print(mdl)
Orchestrates a human-in-the-loop (HITL) active learning workflow: segment, review, correct, retrain, repeat.
sg_active_learning_loop( image, model = "cellpose", n_rounds = 5L, patches_per_round = 10L, patch_size = 256L, initial_model = "cyto3" )sg_active_learning_loop( image, model = "cellpose", n_rounds = 5L, patches_per_round = 10L, patch_size = 256L, initial_model = "cyto3" )
image |
An |
model |
Character. Segmentation backend to use. Currently only
|
n_rounds |
Integer. Number of active learning rounds. Default |
patches_per_round |
Integer. Patches sampled per round. Default |
patch_size |
Integer. Patch size in pixels. Default |
initial_model |
Character. Initial model name. Default |
An sg_hitl_result S3 object with elements $rounds (list of
per-round results), $final_model (trained model path or object),
and $metrics (training metrics across rounds).
## Not run: # Requires Python with Cellpose and an interactive review session img <- sg_example_image("fluorescence_nuclei") result <- sg_active_learning_loop(img, n_rounds = 3L, patches_per_round = 2L, patch_size = 32L) ## End(Not run)## Not run: # Requires Python with Cellpose and an interactive review session img <- sg_example_image("fluorescence_nuclei") result <- sg_active_learning_loop(img, n_rounds = 3L, patches_per_round = 2L, patch_size = 32L) ## End(Not run)
Returns a shiny.appobj built from package code, with explicit input
objects instead of global options. The app offers image/channel/band
selection, a protocol picker with a parameter form generated from the
protocol registry, mask overlay, backend status for optional DNN
protocols, a staged/reviewed workflow with explicit overwrite
confirmation, and export of a neutral interchange bundle. There is no
code entry of any kind.
sg_app(input = NULL, state = NULL, control = "off", ...)sg_app(input = NULL, state = NULL, control = "off", ...)
input |
|
state |
Optional list with initial |
control |
|
... |
Options: |
A shiny.appobj.
sg_run_app(), sg_control_capabilities()
app <- sg_app(list(image = sg_example_image("fluorescence_nuclei"))) class(app) if (interactive()) { shiny::runApp(app) }app <- sg_app(list(image = sg_example_image("fluorescence_nuclei"))) class(app) if (interactive()) { shiny::runApp(app) }
Takes a list of correction operations (split, merge, delete, add) and applies them to produce a corrected mask.
sg_apply_corrections(mask, corrections)sg_apply_corrections(mask, corrections)
mask |
An |
corrections |
A list of correction operations. Each element is a list
with at least an |
Each correction in the list must contain:
action = "delete"Remove cell. Requires $cell_id.
action = "merge"Merge cells. Requires $cell_ids (integer vector).
action = "split"Split a cell. Requires $cell_id and
$seed_points (matrix with columns row, col).
action = "add"Add a new cell. Requires $pixels (matrix of
row/col coordinates).
A corrected sg_mask object.
labels <- matrix(0L, nrow = 20, ncol = 20) labels[3:8, 3:8] <- 1L labels[12:18, 12:18] <- 2L mask <- new_sg_mask(labels) corrected <- sg_apply_corrections(mask, list( list(action = "delete", cell_id = 2L) )) print(corrected)labels <- matrix(0L, nrow = 20, ncol = 20) labels[3:8, 3:8] <- 1L labels[12:18, 12:18] <- 2L mask <- new_sg_mask(labels) corrected <- sg_apply_corrections(mask, list( list(action = "delete", cell_id = 2L) )) print(corrected)
The canvas uses local array pixel coordinates (top-left origin, x right,
y down). Drawing emits Shiny inputs suffixed _created, _edited, and
_erased. Use sg_canvas_correct() to stage changes to a mask.
sg_canvas( image, mask = NULL, channel = 1L, tool = "pan", width = NULL, height = 600, elementId = NULL )sg_canvas( image, mask = NULL, channel = 1L, tool = "pan", width = NULL, height = 600, elementId = NULL )
image |
An |
mask |
Optional |
channel |
One-based display channel. |
tool |
Drawing tool. |
width, height
|
Widget dimensions. |
elementId |
Optional widget id. |
An HTML widget.
img <- new_sg_image(matrix(seq_len(72), 8, 9), id = "slide") msk <- new_sg_mask(matrix(0L, 8, 9), image_id = "slide") widget <- sg_canvas(img, msk, tool = "polygon") class(widget) if (interactive()) widgetimg <- new_sg_image(matrix(seq_len(72), 8, 9), id = "slide") msk <- new_sg_mask(matrix(0L, 8, 9), image_id = "slide") widget <- sg_canvas(img, msk, tool = "polygon") class(widget) if (interactive()) widget
Geometry is in local array pixels. Changes retain image binding and are staged for explicit review. Overlapping cells are rejected.
sg_canvas_correct( mask, geometry = NULL, action = "add", cell_id = NULL, expected_revision )sg_canvas_correct( mask, geometry = NULL, action = "add", cell_id = NULL, expected_revision )
mask |
An |
geometry |
GeoJSON Polygon or MultiPolygon, required for add/edit. |
action |
One of |
cell_id |
Existing integer label for edit/erase. |
expected_revision |
Revision shown when the edit began. |
A staged sg_mask.
msk <- new_sg_mask(matrix(0L, 8, 9)) box <- list(type = "Polygon", coordinates = list(list(c(1, 1), c(4, 1), c(4, 4), c(1, 4), c(1, 1)))) added <- sg_canvas_correct(msk, box, expected_revision = sg_mask_revision(msk)) sum(added$labels > 0) added$review$statusmsk <- new_sg_mask(matrix(0L, 8, 9)) box <- list(type = "Polygon", coordinates = list(list(c(1, 1), c(4, 1), c(4, 4), c(1, 4), c(1, 1)))) added <- sg_canvas_correct(msk, box, expected_revision = sg_mask_revision(msk)) sum(added$labels > 0) added$review$status
Applies the postprocess.label-cleanup.v1 rules to an sg_mask in a
fixed order: handling of disconnected label parts, hole filling,
separation of touching objects, border removal, area filtering and
relabelling. The legend (object ids, classes) follows the labels.
sg_cleanup_labels( mask, min_area = 0L, max_area = NULL, min_area_um2 = NULL, max_area_um2 = NULL, fill_holes = FALSE, connectivity = 4L, border = c("keep", "remove"), touching = c("keep", "separate"), disconnected = c("keep", "split", "keep_largest"), relabel = c("value", "raster", "none"), pixel_size = NULL )sg_cleanup_labels( mask, min_area = 0L, max_area = NULL, min_area_um2 = NULL, max_area_um2 = NULL, fill_holes = FALSE, connectivity = 4L, border = c("keep", "remove"), touching = c("keep", "separate"), disconnected = c("keep", "split", "keep_largest"), relabel = c("value", "raster", "none"), pixel_size = NULL )
mask |
An |
min_area |
Minimum object area in pixels (full-resolution pixels for downsampled masks are not assumed; areas are array pixels). |
max_area |
Maximum object area in pixels, or |
min_area_um2, max_area_um2
|
Area limits in square micrometres;
require |
fill_holes |
Logical; fill background holes enclosed by one label. |
connectivity |
|
border |
|
touching |
|
disconnected |
|
relabel |
|
pixel_size |
Optional list with |
A new sg_mask. Masks derived from staged or reviewed masks are
staged.
labels <- matrix(0L, 12, 12) labels[2:4, 2:4] <- 1L labels[7:11, 7:11] <- 2L labels[9, 9] <- 0L out <- sg_cleanup_labels(new_sg_mask(labels), min_area = 10L, fill_holes = TRUE) out$n_cellslabels <- matrix(0L, 12, 12) labels[2:4, 2:4] <- 1L labels[7:11, 7:11] <- 2L labels[9, 9] <- 0L out <- sg_cleanup_labels(new_sg_mask(labels), min_area = 10L, fill_holes = TRUE) out$n_cells
The local control service lets a partner (qupflowR, hyperannotatR) drive a running segmantR app through typed commands. It is planned and not implemented; this function reports the planned contract so partners can check for it without guessing. It never starts a server.
sg_control_capabilities()sg_control_capabilities()
A list with schema, status ("planned"), implemented
(FALSE), default ("off"), planned_commands and
security_requirements.
sg_control_capabilities()$statussg_control_capabilities()$status
Samples informative image patches for manual annotation or correction. Patches are selected on a grid or, when an initial mask is provided, prioritised by segmentation uncertainty.
sg_create_annotation_task( image, initial_mask = NULL, region = NULL, n_patches = 20L, patch_size = 256L )sg_create_annotation_task( image, initial_mask = NULL, region = NULL, n_patches = 20L, patch_size = 256L )
image |
An |
initial_mask |
Optional |
region |
Optional numeric vector |
n_patches |
Integer. Number of patches to sample. Default |
patch_size |
Integer. Size of each square patch in pixels.
Default |
An sg_annotation_task S3 object (a list with elements patches,
image_id, n_patches, patch_size, and created).
pixels <- matrix(runif(100 * 100), nrow = 100, ncol = 100) img <- new_sg_image(pixels) task <- sg_create_annotation_task(img, n_patches = 4L, patch_size = 32L) print(task)pixels <- matrix(runif(100 * 100), nrow = 100, ncol = 100) img <- new_sg_image(pixels) task <- sg_create_annotation_task(img, n_patches = 4L, patch_size = 32L) print(task)
Builds a tile-level dataset manifest from image/mask pairs without
writing pixels. Tiles are laid out on a regular grid (tile_size,
overlap), splits are assigned per group (subject_id, sample_id
or slide_id) with a fixed seed so tiles of one origin never land in
different splits, and every tile records its bounds, plane, object list
(label, object id, class) and exclusion reason.
sg_dataset_manifest( pairs, tile_size = 256L, overlap = 0L, group_by = c("subject_id", "sample_id", "slide_id"), split = c(train = 0.7, validation = 0.15, test = 0.15), seed = 1L, mask_type = c("instance", "labelled", "binary"), min_objects = 1L, partial_tiles = c("exclude", "keep"), require_reviewed = FALSE, normalization = list(method = "none"), backend = NULL )sg_dataset_manifest( pairs, tile_size = 256L, overlap = 0L, group_by = c("subject_id", "sample_id", "slide_id"), split = c(train = 0.7, validation = 0.15, test = 0.15), seed = 1L, mask_type = c("instance", "labelled", "binary"), min_objects = 1L, partial_tiles = c("exclude", "keep"), require_reviewed = FALSE, normalization = list(method = "none"), backend = NULL )
pairs |
A list of training pairs. Each element is a list with
|
tile_size |
Tile edge length in pixels. |
overlap |
Overlap between neighbouring tiles in pixels. |
group_by |
Grouping key used for the split. |
split |
Named proportions for |
seed |
Integer seed of the group permutation (the global RNG state is restored afterwards). |
mask_type |
Required mask type. |
min_objects |
Tiles with fewer objects are excluded ( |
partial_tiles |
|
require_reviewed |
Logical; exclude tiles from masks that are not
reviewed ( |
normalization |
List with |
backend |
Optional target backend name recorded in the manifest. |
Masks must satisfy the requested mask_type: integer, background 0, and
for "instance" one connected part per label. A foreground/background
mask with several objects under one label is rejected
(NOT_INSTANCE_MASK) instead of being accepted silently.
An sg_dataset_manifest list conforming to
dataset-manifest.schema.json.
img <- sg_example_image("fluorescence_nuclei") # The synthetic example mask contains overlapping ellipses; split them # into separate instances first. msk <- sg_cleanup_labels(sg_example_mask("fluorescence_nuclei"), disconnected = "split") pairs <- list( list(image = img, mask = msk, subject_id = "A"), list(image = img, mask = msk, subject_id = "B") ) man <- sg_dataset_manifest(pairs, tile_size = 32L, min_objects = 0L, split = c(train = 0.5, validation = 0.5, test = 0)) table(vapply(man$tiles, function(t) t$split, ""))img <- sg_example_image("fluorescence_nuclei") # The synthetic example mask contains overlapping ellipses; split them # into separate instances first. msk <- sg_cleanup_labels(sg_example_mask("fluorescence_nuclei"), disconnected = "split") pairs <- list( list(image = img, mask = msk, subject_id = "A"), list(image = img, mask = msk, subject_id = "B") ) man <- sg_dataset_manifest(pairs, tile_size = 32L, min_objects = 0L, split = c(train = 0.5, validation = 0.5, test = 0)) table(vapply(man$tiles, function(t) t$split, ""))
Sets the black and full-colour levels of each channel from the signal
around reference cells, so that called-negative cells stay dark and
called-positive cells reach full colour: for every channel up to n
negative and n positive cells are drawn, a statistic of the
(2 * half + 1)-pixel square patch around each cell is taken ("mean" or
a percentile given as a probability), and the levels are the black
quantile of the negative and the white quantile of the positive cell
values.
sg_display_levels( path, channels, cells, positive, negative, x = "x", y = "y", label = "label", pixel_size = 1, half = 7, statistic = 0.9, black = 0.5, white = 0.5, n = 300, seed = 0 )sg_display_levels( path, channels, cells, positive, negative, x = "x", y = "y", label = "label", pixel_size = 1, half = 7, statistic = 0.9, black = 0.5, white = 0.5, n = 300, seed = 0 )
path |
Path to the image file. |
channels |
Channel names. |
cells |
Data frame of cells with positions and labels. |
positive, negative
|
Named lists: channel name to the labels of the positive and negative reference cells. |
x, y, label
|
Column names in |
pixel_size |
Physical size of one pixel. |
half |
Patch half-width in pixels. |
statistic |
|
black, white
|
Quantiles across negative and positive cells. |
n |
Maximum number of reference cells per set. |
seed |
Random seed for the draws (the global RNG state is restored). |
Arguments that vary by channel (half, statistic, black, white)
accept a single value or a named list/vector by channel name, with an
optional .default entry.
A data frame with columns channel, lo, hi, n_negative and
n_positive.
sg_slide_display_ranges(), sg_display_range()
f <- tempfile(fileext = ".tif") plane <- matrix(10, 40, 40) plane[21:40, ] <- 200 invisible(tiff::writeTIFF(plane / 255, f, bits.per.sample = 8L)) cells <- data.frame(x = c(5, 15, 25, 35), y = c(5, 10, 30, 35), label = c("neg", "neg", "pos", "pos")) sg_display_levels(f, "ch1", cells, positive = list(ch1 = "pos"), negative = list(ch1 = "neg"), half = 2)f <- tempfile(fileext = ".tif") plane <- matrix(10, 40, 40) plane[21:40, ] <- 200 invisible(tiff::writeTIFF(plane / 255, f, bits.per.sample = 8L)) cells <- data.frame(x = c(5, 15, 25, 35), y = c(5, 10, 30, 35), label = c("neg", "neg", "pos", "pos")) sg_display_levels(f, "ch1", cells, positive = list(ch1 = "pos"), negative = list(ch1 = "neg"), half = 2)
Percentile-based display (black and white) levels for a set of pixel
values, as used to scale fluorescence channels for viewing: lo is the
lower percentile (or a given value), hi the larger of the upper
percentile, an optional floor and lo + min_span. Percentiles use linear
interpolation between order statistics (stats::quantile(type = 7)).
sg_display_range( x, probs = c(0.01, 0.997), lo = NULL, hi_floor = NULL, min_span = 1 )sg_display_range( x, probs = c(0.01, 0.997), lo = NULL, hi_floor = NULL, min_span = 1 )
x |
Numeric pixel values (any shape). |
probs |
Lower and upper probabilities; either may be |
lo |
Optional fixed lower level (replaces the lower percentile). |
hi_floor |
Optional value the upper level must at least reach. |
min_span |
Minimum distance between the two levels. |
Named numeric c(lo = , hi = ).
sg_slide_display_ranges(), sg_display_levels()
sg_display_range(c(0, 1, 2, 3, 100)) sg_display_range(1:10, probs = c(NA, 0.995), lo = 2, hi_floor = 20)sg_display_range(c(0, 1, 2, 3, 100)) sg_display_range(1:10, probs = c(NA, 0.995), lo = 2, hi_floor = 20)
Read and validate an ENVI header without reading pixel data
sg_envi_info(path, data_file = NULL)sg_envi_info(path, data_file = NULL)
path |
Path to the |
data_file |
Optional explicit data file path. |
A list of class sg_envi_info with samples, lines, bands,
interleave, byte_order, data_type, dtype, header_offset,
wavelength_nm, fwhm_nm, band_names, nodata, scale_factor,
gain, offset, wavelength_units, data_bytes_expected,
data_bytes_present and header_digest. Paths are not stored.
d <- tempfile("envi") dir.create(d) hdr <- file.path(d, "cube.hdr") writeLines(c("ENVI", "samples = 2", "lines = 2", "bands = 2", "header offset = 0", "data type = 12", "interleave = bsq", "byte order = 0", "wavelength = {500, 600}"), hdr) writeBin(1:8, file.path(d, "cube"), size = 2L, endian = "little") sg_envi_info(hdr)$wavelength_nmd <- tempfile("envi") dir.create(d) hdr <- file.path(d, "cube.hdr") writeLines(c("ENVI", "samples = 2", "lines = 2", "bands = 2", "header offset = 0", "data type = 12", "interleave = bsq", "byte order = 0", "wavelength = {500, 600}"), hdr) writeBin(1:8, file.path(d, "cube"), size = 2L, endian = "little") sg_envi_info(hdr)$wavelength_nm
Computes standard instance segmentation metrics by comparing a predicted mask against a ground truth mask.
sg_evaluate_segmentation( predicted, ground_truth, metrics = c("dice", "jaccard", "aji", "panoptic_quality", "ap50", "ap75", "f1_detection") )sg_evaluate_segmentation( predicted, ground_truth, metrics = c("dice", "jaccard", "aji", "panoptic_quality", "ap50", "ap75", "f1_detection") )
predicted |
An |
ground_truth |
An |
metrics |
Character vector of metrics to compute. One or more of
|
Instances are matched one-to-one at an intersection-over-union
(IoU) threshold. "ap50" and "ap75" are the instance-segmentation
average precision used by Cellpose and StarDist at IoU 0.5 and 0.75,
; "f1_detection" is the F1 score of the
matches at IoU 0.5, .
An sg_eval S3 object (a tibble with columns metric and value)
with a custom print method.
pred_labels <- matrix(0L, nrow = 20, ncol = 20) pred_labels[3:8, 3:8] <- 1L pred_labels[12:18, 12:18] <- 2L gt_labels <- matrix(0L, nrow = 20, ncol = 20) gt_labels[3:9, 3:9] <- 1L gt_labels[12:17, 12:17] <- 2L pred <- new_sg_mask(pred_labels) gt <- new_sg_mask(gt_labels) result <- sg_evaluate_segmentation(pred, gt) print(result)pred_labels <- matrix(0L, nrow = 20, ncol = 20) pred_labels[3:8, 3:8] <- 1L pred_labels[12:18, 12:18] <- 2L gt_labels <- matrix(0L, nrow = 20, ncol = 20) gt_labels[3:9, 3:9] <- 1L gt_labels[12:17, 12:17] <- 2L pred <- new_sg_mask(pred_labels) gt <- new_sg_mask(gt_labels) result <- sg_evaluate_segmentation(pred, gt) print(result)
Returns an sg_image containing synthetic image data for testing
and demonstrations. The data are drawn with a fixed seed, so they are
the same in every session, and the caller's random number stream is
left unchanged.
sg_example_image(type = c("he_breast", "fluorescence_nuclei", "multiplex_4ch"))sg_example_image(type = c("he_breast", "fluorescence_nuclei", "multiplex_4ch"))
type |
Character, the example to generate:
|
An sg_image object.
sg_example_mask() for the matching label masks.
img <- sg_example_image("he_breast") print(img)img <- sg_example_image("he_breast") print(img)
Returns an sg_mask matching the corresponding example image. Like
sg_example_image(), it leaves the caller's random number stream
unchanged.
sg_example_mask(type = c("he_breast", "fluorescence_nuclei", "multiplex_4ch"))sg_example_mask(type = c("he_breast", "fluorescence_nuclei", "multiplex_4ch"))
type |
Character, one of |
An sg_mask object whose labels are 0 for background and
positive integers for the cells of the example image of the same type.
mask <- sg_example_mask("he_breast") print(mask)mask <- sg_example_mask("he_breast") print(mask)
Writes a bundle directory containing a manifest, the requested
representations and an integrity.json inventory with SHA-256 hashes and
relative paths. All representations describe the same envelope: the
integer mask TIFF holds exact labels, the GeoJSON holds exact pixel-edge
polygons in image coordinates with the same object ids, and the
measurements table uses the canonical long format (value_state
distinguishes missing, NaN and infinite values). RDS is an optional
R-native optimisation and never the only representation.
sg_export_interchange( x, destination, formats = c("manifest", "mask_tiff", "geojson", "measurements"), ..., image = NULL, object_type = c("detection", "annotation", "cell"), overwrite = FALSE )sg_export_interchange( x, destination, formats = c("manifest", "mask_tiff", "geojson", "measurements"), ..., image = NULL, object_type = c("detection", "annotation", "cell"), overwrite = FALSE )
x |
An |
destination |
Directory to create. It must not exist or be empty;
with |
formats |
Any of |
... |
Reserved; must be empty. |
image |
Optional |
object_type |
QuPath object type for GeoJSON features
( |
overwrite |
Logical; replace an existing segmantR bundle. |
An sg_interchange_bundle (invisibly) with path, manifest
and bundle_digest.
m <- sg_example_mask("fluorescence_nuclei") img <- sg_example_image("fluorescence_nuclei") out <- sg_export_interchange(m, tempfile("bundle"), image = img) list.files(out$path) out$bundle_digestm <- sg_example_mask("fluorescence_nuclei") img <- sg_example_image("fluorescence_nuclei") out <- sg_export_interchange(m, tempfile("bundle"), image = img) list.files(out$path) out$bundle_digest
Writes a segmentation mask to disk in one of several formats.
sg_export_mask( mask, path, format = c("tiff", "png", "geojson", "qupath", "csv") )sg_export_mask( mask, path, format = c("tiff", "png", "geojson", "qupath", "csv") )
mask |
An |
path |
Character. Output file path. |
format |
Character. Export format: |
The output file path, returned invisibly.
labels <- matrix(0L, nrow = 10, ncol = 10) labels[3:8, 3:8] <- 1L mask <- new_sg_mask(labels) tmp <- tempfile(fileext = ".csv") sg_export_mask(mask, tmp, format = "csv")labels <- matrix(0L, nrow = 10, ncol = 10) labels[3:8, 3:8] <- 1L mask <- new_sg_mask(labels) tmp <- tempfile(fileext = ".csv") sg_export_mask(mask, tmp, format = "csv")
Writes a QuPath program directory: a declarative run.json (schema
segmantR-qupath-run-v1), the readable Groovy templates, the resources
they bind (a neutral interchange bundle or a hashed model copy), a
run_export.json for the way back, checksums.sha256 and a README.md
with the interactive and command-line invocations. segmantR never starts
QuPath, Java or Groovy itself.
sg_export_qupath( x, destination, ..., image = NULL, image_name = NULL, model = NULL, region_policy = c("whole_image", "selected_annotations", "all_annotations"), save_policy = c("none", "project"), object_type = c("detection", "annotation", "cell"), require_calibration = TRUE, min_qupath_version = "0.5.0", allow_unsupported = FALSE, overwrite = FALSE )sg_export_qupath( x, destination, ..., image = NULL, image_name = NULL, model = NULL, region_policy = c("whole_image", "selected_annotations", "all_annotations"), save_policy = c("none", "project"), object_type = c("detection", "annotation", "cell"), require_calibration = TRUE, min_qupath_version = "0.5.0", allow_unsupported = FALSE, overwrite = FALSE )
x |
An |
destination |
Output directory (must not exist or be empty). |
... |
Protocol parameter overrides for the |
image |
|
image_name |
Name of the image in the QuPath project (checked by
the templates); |
model |
StarDist model file/directory or |
region_policy |
|
save_policy |
|
object_type |
QuPath object type for imported or exported objects. |
require_calibration |
Logical; templates refuse uncalibrated images. |
min_qupath_version |
Minimum QuPath version written to |
allow_unsupported |
Logical; allow non-default parameters that the QuPath extension cannot honour (they are still listed). |
overwrite |
Logical; replace an existing program directory created by segmantR. |
For an sg_mask, sg_run or list with a mask, the task is import:
the mask is exported with sg_export_interchange() into bundle/
(integer TIFF, exact GeoJSON with object ids, legend, measurements) and
segmantR_import.groovy adds the objects to the open image after
checking size, calibration, plane, SHA-256 and id collisions.
For a StarDist protocol ("stardist.2d.v1" or an sg_protocol), the
task is stardist: parameters are mapped with
sg_stardist_parameter_map() (unsupported non-default options are
errors unless allow_unsupported = TRUE, and are always listed in
run.json), the model is copied into models/ and its digest is
recorded for verification by the template.
An sg_qupath_program (invisibly) with path, task, run
(parsed run.json) and commands (headless command lines).
m <- sg_example_mask("fluorescence_nuclei") img <- sg_example_image("fluorescence_nuclei") prog <- sg_export_qupath(m, tempfile("qupath"), image = img, require_calibration = FALSE) prog$commands[["import"]]m <- sg_example_mask("fluorescence_nuclei") img <- sg_example_image("fluorescence_nuclei") prog <- sg_export_qupath(m, tempfile("qupath"), image = img, require_calibration = FALSE) prog$commands[["import"]]
Computes intensity, morphology, texture, and location features for each segmented cell. Returns a tibble with one row per cell.
sg_extract_features( image, mask, features = c("intensity", "morphology", "texture", "location"), channels = NULL )sg_extract_features( image, mask, features = c("intensity", "morphology", "texture", "location"), channels = NULL )
image |
An |
mask |
An |
features |
Character vector of feature groups to compute. One or more
of |
channels |
Integer or character vector selecting which image channels
to use for intensity and texture features. |
Morphology features: perimeter is the number of boundary
pixels; circularity is , capped at 1 because the
boundary-pixel count underestimates the perimeter of round objects;
eccentricity comes from the eigenvalues of the pixel-coordinate
covariance (0 for a disc, 1 for a line of pixels); solidity is the
area divided by the area of the convex hull of the pixel squares.
Circularity, eccentricity and solidity are NA for single-pixel cells.
A tibble with one row per cell and a cell_id column, plus columns
for each requested feature.
pixels <- array(runif(20 * 20 * 2), dim = c(20, 20, 2)) img <- new_sg_image(pixels, channels = c("DAPI", "CD3")) labels <- matrix(0L, nrow = 20, ncol = 20) labels[3:8, 3:8] <- 1L labels[12:18, 12:18] <- 2L mask <- new_sg_mask(labels) feats <- sg_extract_features(img, mask, features = c("intensity", "morphology")) print(feats)pixels <- array(runif(20 * 20 * 2), dim = c(20, 20, 2)) img <- new_sg_image(pixels, channels = c("DAPI", "CD3")) labels <- matrix(0L, nrow = 20, ncol = 20) labels[3:8, 3:8] <- 1L labels[12:18, 12:18] <- 2L mask <- new_sg_mask(labels) feats <- sg_extract_features(img, mask, features = c("intensity", "morphology")) print(feats)
Removes cells from a segmentation mask that fall outside specified morphological thresholds. Useful for quality control after initial segmentation.
sg_filter_cells( mask, min_area = 50L, max_area = 5000L, min_circularity = 0.3, max_eccentricity = 0.95, border_cells = c("keep", "remove", "flag") )sg_filter_cells( mask, min_area = 50L, max_area = 5000L, min_circularity = 0.3, max_eccentricity = 0.95, border_cells = c("keep", "remove", "flag") )
mask |
An |
min_area |
Integer. Minimum cell area in pixels. Default |
max_area |
Integer. Maximum cell area in pixels. Default |
min_circularity |
Numeric in [0, 1]. Minimum circularity
(4 * pi * area / perimeter^2). Default |
max_eccentricity |
Numeric in [0, 1]. Maximum eccentricity.
Default |
border_cells |
Character. How to handle cells touching the image
border: |
A filtered sg_mask object. When border_cells = "flag", the
returned mask has an additional border_cell_ids element.
labels <- matrix(0L, nrow = 20, ncol = 20) labels[3:8, 3:8] <- 1L labels[12:18, 12:18] <- 2L mask <- new_sg_mask(labels) filtered <- sg_filter_cells(mask, min_area = 10L, max_area = 100L) print(filtered)labels <- matrix(0L, nrow = 20, ncol = 20) labels[3:8, 3:8] <- 1L labels[12:18, 12:18] <- 2L mask <- new_sg_mask(labels) filtered <- sg_filter_cells(mask, min_area = 10L, max_area = 100L) print(filtered)
Computes SHA-256 digests and sizes for every regular file below root
(except the inventory files themselves), using bundle-relative
forward-slash paths. The integrity.json form is identical to the
qupflowR workflow-bundle rule: {"format_version": "1.0", "files": [{"path", "size_bytes", "sha256"}]} sorted by path, and the bundle digest
is the SHA-256 of its canonical JSON (keys sorted, no whitespace).
checksums.sha256 uses the sha256sum text format.
sg_hash_assets( root, files = NULL, write = c("none", "integrity", "sha256sum", "both"), verify = FALSE )sg_hash_assets( root, files = NULL, write = c("none", "integrity", "sha256sum", "both"), verify = FALSE )
root |
Bundle directory. |
files |
Optional character vector of relative paths to inventory (default: all regular files). |
write |
Which inventory files to write: |
verify |
Logical; if |
Symbolic links, absolute or parent-relative paths and special files are rejected. Absolute paths are never written.
An sg_asset_inventory list with files (tibble), integrity
(list) and bundle_digest ("sha256:<hex>"), invisibly when writing.
d <- tempfile("bundle") dir.create(d) writeLines("a", file.path(d, "a.txt")) inv <- sg_hash_assets(d, write = "integrity") inv$bundle_digest sg_hash_assets(d, verify = TRUE)$bundle_digest == inv$bundle_digestd <- tempfile("bundle") dir.create(d) writeLines("a", file.path(d, "a.txt")) inv <- sg_hash_assets(d, write = "integrity") inv$bundle_digest sg_hash_assets(d, verify = TRUE)$bundle_digest == inv$bundle_digest
Reads the directory structure of a (Q)PTIFF, OME-TIFF or plain multi-page
TIFF through GDAL and returns one row per full-resolution channel plane.
Channel names come from the per-plane image description (<Biomarker>,
then <Name>, as written by PhenoCycler/Vectra QPTIFF files), from the
Channel Name attributes of OME-XML on the first plane, or default to
ch1, ch2, .... Reduced-resolution pages (overviews, thumbnails, label
and macro images) are left out: a plane belongs to the channel set when it
has one band and the size of the first plane.
sg_image_channels(path)sg_image_channels(path)
path |
Path to the image file. |
A data frame with columns channel (1-based channel number),
name, directory (1-based TIFF directory), width, height,
block_width, block_height, datatype and dsn (the GDAL dataset
name of the plane).
sg_read_window(), sg_read_field()
f <- tempfile(fileext = ".tif") planes <- list(matrix(1:100, 10, 10), matrix(101:200, 10, 10)) invisible(tiff::writeTIFF(lapply(planes, function(p) p / 255), f, bits.per.sample = 8L)) sg_image_channels(f)[, c("channel", "name", "width", "height")]f <- tempfile(fileext = ".tif") planes <- list(matrix(1:100, 10, 10), matrix(101:200, 10, 10)) invisible(tiff::writeTIFF(lapply(planes, function(p) p / 255), f, bits.per.sample = 8L)) sg_image_channels(f)[, c("channel", "name", "width", "height")]
Reads a segmantR interchange bundle or a single GeoJSON, integer TIFF,
measurement CSV or RDS file, verifies it and returns a report with the
imported objects. Imported masks are always staged; they never replace
reviewed data (see sg_replace_mask()).
sg_import_interchange( path, format = "auto", expected_digest = NULL, ..., shape_yx = NULL, image = NULL, origin = NULL, trust_rds = FALSE, error = TRUE )sg_import_interchange( path, format = "auto", expected_digest = NULL, ..., shape_yx = NULL, image = NULL, origin = NULL, trust_rds = FALSE, error = TRUE )
path |
A bundle directory, its |
format |
|
expected_digest |
Optional bundle digest ( |
... |
Reserved; must be empty. |
shape_yx |
Image shape needed to rasterise a standalone GeoJSON. |
image |
Optional |
origin |
Optional origin list for standalone GeoJSON. |
trust_rds |
Logical; RDS files are only deserialised when |
error |
Logical; if |
Bundle checks: inventory (missing, extra, duplicate, resized or modified
files, unsafe paths, symbolic links), optional expected_digest, schema
family and major version, JSON Schema, asset hashes, TIFF dtype, shape and
orientation, background code, label legend completeness, plane
consistency, content digest and revision, GeoJSON object ids and exact
geometry agreement with the TIFF, and measurement object ids.
An sg_import_report list with ok, format, checks
(tibble), mask (staged sg_mask or NULL), image, measurements,
features (parsed GeoJSON features), manifest, bundle_digest,
conversions and error.
m <- sg_example_mask("fluorescence_nuclei") b <- sg_export_interchange(m, tempfile("bundle")) rep <- sg_import_interchange(b$path, expected_digest = b$bundle_digest) rep$ok sg_mask_status(rep$mask)$statusm <- sg_example_mask("fluorescence_nuclei") b <- sg_export_interchange(m, tempfile("bundle")) rep <- sg_import_interchange(b$path, expected_digest = b$bundle_digest) rep$ok sg_mask_status(rep$mask)$status
Reads the output of the segmantR QuPath templates (a directory with a
qupath-export manifest and integrity.json), a QuPath program
directory containing such an output (out/ or qupath_export/), or a
plain QuPath GeoJSON export. All checks of sg_import_interchange() run
(inventory, schema, dtype, shape/orientation, legend, content digest and
revision); in addition the QuPath GeoJSON is rasterised and compared with
the QuPath label TIFF, object ids are matched through the legend, the
run id and image binding can be checked, and measurements are imported
in the canonical long format (namespace = "stored"). The mask is
staged.
sg_import_qupath(path, ..., image = NULL, expected_run_id = NULL, error = TRUE)sg_import_qupath(path, ..., image = NULL, expected_run_id = NULL, error = TRUE)
path |
Export directory, program directory or GeoJSON file. |
... |
Reserved; must be empty. |
image |
Optional |
expected_run_id |
Optional run id ( |
error |
Logical; signal failures instead of reporting them. |
An sg_import_report with an extra qupath element (QuPath and
extension versions, template version, run id, GeoJSON/TIFF agreement).
# a plain QuPath GeoJSON export, rasterised onto the image grid cells <- sg_roi_layer_add(sg_roi_layer("cells"), sg_roi_rect(2, 2, 8, 8, label = "cell")) cells <- sg_roi_layer_add(cells, sg_roi_rect(10, 10, 15, 16, label = "cell")) p <- tempfile(fileext = ".geojson") sg_roi_write_qupath(sg_roi_project(sg_roi_frame(c(20, 20)), cells), p) rep <- sg_import_qupath(p, image = new_sg_image(matrix(0, 20, 20))) rep$mask$n_cells# a plain QuPath GeoJSON export, rasterised onto the image grid cells <- sg_roi_layer_add(sg_roi_layer("cells"), sg_roi_rect(2, 2, 8, 8, label = "cell")) cells <- sg_roi_layer_add(cells, sg_roi_rect(10, 10, 15, 16, label = "cell")) p <- tempfile(fileext = ".geojson") sg_roi_write_qupath(sg_roi_project(sg_roi_frame(c(20, 20)), cells), p) rep <- sg_import_qupath(p, image = new_sg_image(matrix(0, 20, 20))) rep$mask$n_cells
Describes what this installation of segmantR can exchange: schema and
API versions, interoperability profiles with their status
("supported", "planned" or "unavailable"), file formats, protocols,
optional backends and limits. Optional Python backends are only probed
when check_backends = TRUE; QuPath is detected from installation files
without starting it.
sg_interchange_capabilities(check_backends = FALSE)sg_interchange_capabilities(check_backends = FALSE)
check_backends |
Logical; probe optional Python backends
through reticulate. Python is initialised only when one has been
selected (see the section "Selecting Python" in |
Profiles: I0 neutral files (manifest, integer TIFF masks, GeoJSON,
measurements, integrity inventory); I1 versioned protocols and run
envelopes; models model bundles with runtime and checksums;
qupath_programs Groovy templates and run.json; stardist_qupath the
StarDist extension adapter; control the local control service
(segmantR-control-v1); partner_qupflowR and partner_hyperannotatR the
partner contracts, which stay planned until a real consumer and QuPath
evidence exist.
An sg_capabilities list conforming to
capabilities.schema.json, with a digest over its content.
caps <- sg_interchange_capabilities() caps$profiles$I0$status caps$schemacaps <- sg_interchange_capabilities() caps$profiles$I0$status caps$schema
Describes an image, mask or segmentation run with the shared coordinate
convention, plane, pixel size, legend, review state, protocol reference,
runtime and asset inventory. The result conforms to
inst/schema/segmantR-interchange-v1/manifest.schema.json.
sg_interchange_manifest( x, ..., image = NULL, assets = list(), conversions = list(), kind = NULL )sg_interchange_manifest( x, ..., image = NULL, assets = list(), conversions = list(), kind = NULL )
x |
An |
... |
Reserved; must be empty. |
image |
Optional |
assets |
Asset records ( |
conversions |
Conversion records ( |
kind |
Optional manifest kind override. |
An sg_manifest list.
m <- sg_example_mask("fluorescence_nuclei") man <- sg_interchange_manifest(m) man$mask$label_count man$coordinate_convention$y_axism <- sg_example_mask("fluorescence_nuclei") man <- sg_interchange_manifest(m) man$mask$label_count man$coordinate_convention$y_axis
Reads a .segmantR archive created by sg_package_model() and
returns an sg_trained_model object.
sg_load_model(path, expected_digest = NULL, allow_legacy = TRUE)sg_load_model(path, expected_digest = NULL, allow_legacy = TRUE)
path |
Character. Path to the |
expected_digest |
Optional |
allow_legacy |
Logical; accept archives without checksums. |
Before extracting, entry names are checked (no absolute paths, parent
segments, backslashes or drive letters; entry count and total size
limits). After extraction, symbolic links are rejected, checksums.sha256
is verified (missing, extra or modified files are errors), the model card
schema and major version and the backend are checked. Archives written by
segmantR 0.1.0 have no checksums; they load with integrity = "unverified" unless allow_legacy = FALSE.
An sg_trained_model object.
# a dedicated directory with a stand-in weight file weights <- file.path(tempfile("model"), "cellpose_weights") dir.create(dirname(weights)) writeBin(as.raw(1:16), weights) mdl <- new_sg_trained_model(weights, backend = "cellpose", base_model = "cyto3", training_metrics = list(n_epochs = 50L)) archive <- sg_package_model(mdl, tempfile(fileext = ".segmantR")) model <- sg_load_model(archive) model$integrity# a dedicated directory with a stand-in weight file weights <- file.path(tempfile("model"), "cellpose_weights") dir.create(dirname(weights)) writeBin(as.raw(1:16), weights) mdl <- new_sg_trained_model(weights, backend = "cellpose", base_model = "cyto3", training_metrics = list(n_epochs = 50L)) archive <- sg_package_model(mdl, tempfile(fileext = ".segmantR")) model <- sg_load_model(archive) model$integrity
Returns the stored legend or, when none is stored, a deterministic legend
with one row per positive label. Generated object ids are UUID-shaped
strings derived from the image binding, the label content and the label
value, so the same mask always yields the same ids. Use
sg_mask_legend(mask, materialise = TRUE) to store the legend in the mask
so ids stay stable through later edits.
sg_mask_legend(mask, materialise = FALSE)sg_mask_legend(mask, materialise = FALSE)
mask |
An |
materialise |
Logical; if |
A tibble with columns label, object_id, class, name, or
the updated mask when materialise = TRUE.
labels <- matrix(0L, 6, 6) labels[2:3, 2:3] <- 1L labels[5:6, 5:6] <- 2L sg_mask_legend(new_sg_mask(labels, image_id = "img-1"))labels <- matrix(0L, 6, 6) labels[2:3, 2:3] <- 1L labels[5:6, 5:6] <- 2L sg_mask_legend(new_sg_mask(labels, image_id = "img-1"))
sg_stage_mask() marks a mask as a staged candidate (for example an
imported prediction). sg_review_mask() records that a human reviewed
the current content. sg_replace_mask() replaces a mask by a candidate
while protecting reviewed data: replacing a reviewed mask requires both
expected_revision equal to its current revision and overwrite = TRUE.
Replacing with identical content is a no-op that keeps the current
status.
sg_stage_mask(mask, source = NULL, parent = NULL) sg_review_mask(mask, reviewer = NULL, note = NULL, expected_revision = NULL) sg_replace_mask( current, replacement, expected_revision = NULL, overwrite = FALSE )sg_stage_mask(mask, source = NULL, parent = NULL) sg_review_mask(mask, reviewer = NULL, note = NULL, expected_revision = NULL) sg_replace_mask( current, replacement, expected_revision = NULL, overwrite = FALSE )
mask, current
|
An |
source |
Optional short description of where the candidate came
from (e.g. |
parent |
Optional |
reviewer |
Optional reviewer name or identifier. |
note |
Optional free-text note stored in the review history (never evaluated). |
expected_revision |
Revision the caller believes is current. Required to review a staged mask or to replace a reviewed one. |
replacement |
The candidate |
overwrite |
Logical; explicit decision to replace a reviewed mask. |
The updated sg_mask.
m <- new_sg_mask(matrix(c(0L, 1L, 1L, 0L), 2)) staged <- sg_stage_mask(m, source = "example") rev <- sg_mask_revision(staged) reviewed <- sg_review_mask(staged, reviewer = "me", expected_revision = rev) sg_mask_status(reviewed)$status candidate <- new_sg_mask(matrix(c(1L, 1L, 1L, 0L), 2)) try(sg_replace_mask(reviewed, candidate)) replaced <- sg_replace_mask(reviewed, candidate, expected_revision = rev, overwrite = TRUE) sg_mask_status(replaced)$statusm <- new_sg_mask(matrix(c(0L, 1L, 1L, 0L), 2)) staged <- sg_stage_mask(m, source = "example") rev <- sg_mask_revision(staged) reviewed <- sg_review_mask(staged, reviewer = "me", expected_revision = rev) sg_mask_status(reviewed)$status candidate <- new_sg_mask(matrix(c(1L, 1L, 1L, 0L), 2)) try(sg_replace_mask(reviewed, candidate)) replaced <- sg_replace_mask(reviewed, candidate, expected_revision = rev, overwrite = TRUE) sg_mask_status(replaced)$status
A "sha256:<hex>" digest over the label array (dimensions and row-major
little-endian int32 values), the mask type and the effective legend.
Identical content always yields the same revision, so repeated imports of
the same prediction are idempotent.
sg_mask_revision(mask)sg_mask_revision(mask)
mask |
An |
Character scalar.
m <- new_sg_mask(matrix(c(0L, 1L, 1L, 0L), 2)) sg_mask_revision(m)m <- new_sg_mask(matrix(c(0L, 1L, 1L, 0L), 2)) sg_mask_revision(m)
Review state of a mask
sg_mask_status(mask)sg_mask_status(mask)
mask |
An |
A list with status, revision (current content revision),
reviewed_revision, parent_revision and consistent (FALSE when a
reviewed mask was modified after review).
sg_mask_status(new_sg_mask(matrix(0L, 3, 3)))sg_mask_status(new_sg_mask(matrix(0L, 3, 3)))
Extracts cell boundaries from a label mask and returns them as polygon
geometries. If the sf package is available, returns an sf data
frame; otherwise returns a tibble of boundary coordinates.
sg_mask_to_polygons(mask, simplify = TRUE, tolerance = 1)sg_mask_to_polygons(mask, simplify = TRUE, tolerance = 1)
mask |
An |
simplify |
Logical. Simplify polygon geometries? Default |
tolerance |
Numeric. Simplification tolerance in pixels when
|
An sf data frame with one row per cell (columns cell_id and
geometry) when sf is available, or a tibble with columns
cell_id, row, col listing boundary coordinates.
labels <- matrix(0L, nrow = 20, ncol = 20) labels[3:8, 3:8] <- 1L labels[12:18, 12:18] <- 2L mask <- new_sg_mask(labels) polys <- sg_mask_to_polygons(mask, simplify = FALSE) head(polys)labels <- matrix(0L, nrow = 20, ncol = 20) labels[3:8, 3:8] <- 1L labels[12:18, 12:18] <- 2L mask <- new_sg_mask(labels) polys <- sg_mask_to_polygons(mask, simplify = FALSE) head(polys)
Combines a nuclear segmentation mask with a cell body segmentation mask to produce paired nuclear-cell assignments.
sg_merge_masks(nuclear_mask, cell_mask, method = c("assign", "expand"))sg_merge_masks(nuclear_mask, cell_mask, method = c("assign", "expand"))
nuclear_mask |
An |
cell_mask |
An |
method |
Character. |
A list with elements $nuclear and $cell, both sg_mask objects
with matched cell IDs.
nuc_labels <- matrix(0L, nrow = 20, ncol = 20) nuc_labels[5:7, 5:7] <- 1L nuc_labels[14:16, 14:16] <- 2L cell_labels <- matrix(0L, nrow = 20, ncol = 20) cell_labels[3:9, 3:9] <- 1L cell_labels[12:18, 12:18] <- 2L nuc_mask <- new_sg_mask(nuc_labels) cell_mask <- new_sg_mask(cell_labels) merged <- sg_merge_masks(nuc_mask, cell_mask) print(merged$nuclear)nuc_labels <- matrix(0L, nrow = 20, ncol = 20) nuc_labels[5:7, 5:7] <- 1L nuc_labels[14:16, 14:16] <- 2L cell_labels <- matrix(0L, nrow = 20, ncol = 20) cell_labels[3:9, 3:9] <- 1L cell_labels[12:18, 12:18] <- 2L nuc_mask <- new_sg_mask(nuc_labels) cell_mask <- new_sg_mask(cell_labels) merged <- sg_merge_masks(nuc_mask, cell_mask) print(merged$nuclear)
Prints a human-readable model card for a trained segmentation model and returns the card contents as a tibble.
sg_model_card(trained_model)sg_model_card(trained_model)
trained_model |
An |
A tibble with columns field and value representing the model
card contents, returned invisibly.
# a dedicated directory with a stand-in weight file weights <- file.path(tempfile("model"), "cellpose_weights") dir.create(dirname(weights)) writeBin(as.raw(1:16), weights) mdl <- new_sg_trained_model( model_path = weights, backend = "cellpose", base_model = "cyto3", training_metrics = list(n_epochs = 100L), model_card = list(author = "Test User", tissue = "lung") ) sg_model_card(mdl)# a dedicated directory with a stand-in weight file weights <- file.path(tempfile("model"), "cellpose_weights") dir.create(dirname(weights)) writeBin(as.raw(1:16), weights) mdl <- new_sg_trained_model( model_path = weights, backend = "cellpose", base_model = "cyto3", training_metrics = list(n_epochs = 100L), model_card = list(author = "Test User", tissue = "lung") ) sg_model_card(mdl)
Creates a .segmantR archive (ZIP format) containing model weights,
a model_card.json, and optionally training data.
sg_package_model( trained_model, output_path, name = NULL, description = NULL, include_training_data = FALSE, format = c("segmantR", "cellpose", "both"), embed_weights = TRUE, license = NULL, overwrite = TRUE )sg_package_model( trained_model, output_path, name = NULL, description = NULL, include_training_data = FALSE, format = c("segmantR", "cellpose", "both"), embed_weights = TRUE, license = NULL, overwrite = TRUE )
trained_model |
An |
output_path |
Character. Path for the output archive file. |
name |
Character or |
description |
Character or |
include_training_data |
Logical. Include training data in the archive?
Default |
format |
Character. Archive format: |
embed_weights |
Logical; copy weights into the archive (default) or record them as a hashed reference relative to the archive directory. |
license |
Optional license list ( |
overwrite |
Logical; replace an existing archive. |
The archive keeps relative paths and contains a versioned
model_card.json (schema segmantR-model-card-v1, still carrying the
fields written by segmantR 0.1.0), runtime.json, dataset_manifest.json
when the model has one, license.json when a license is given, the
weights under weights/ (or a hashed relative reference when
embed_weights = FALSE) and checksums.sha256 covering every file.
Python environments are never copied into a bundle.
The output file path, returned invisibly.
# a dedicated directory with a stand-in weight file weights <- file.path(tempfile("model"), "cellpose_weights") dir.create(dirname(weights)) writeBin(as.raw(1:16), weights) mdl <- new_sg_trained_model( model_path = weights, backend = "cellpose", base_model = "cyto3", training_metrics = list(n_epochs = 50L) ) out <- sg_package_model(mdl, tempfile(fileext = ".segmantR"))# a dedicated directory with a stand-in weight file weights <- file.path(tempfile("model"), "cellpose_weights") dir.create(dirname(weights)) writeBin(as.raw(1:16), weights) mdl <- new_sg_trained_model( model_path = weights, backend = "cellpose", base_model = "cyto3", training_metrics = list(n_epochs = 50L) ) out <- sg_package_model(mdl, tempfile(fileext = ".segmantR"))
Shows two segmentation masks (and optionally the source image) next to each other using faceted panels.
sg_plot_comparison( mask_a, mask_b, image = NULL, labels = c("Method A", "Method B") )sg_plot_comparison( mask_a, mask_b, image = NULL, labels = c("Method A", "Method B") )
mask_a |
An |
mask_b |
An |
image |
An |
labels |
Character vector of length 2 giving panel titles
(default |
A ggplot2 object.
m1 <- new_sg_mask(matrix(c(0L, 1L, 1L, 0L), 2, 2)) m2 <- new_sg_mask(matrix(c(0L, 0L, 1L, 1L), 2, 2)) p <- sg_plot_comparison(m1, m2) pm1 <- new_sg_mask(matrix(c(0L, 1L, 1L, 0L), 2, 2)) m2 <- new_sg_mask(matrix(c(0L, 0L, 1L, 1L), 2, 2)) p <- sg_plot_comparison(m1, m2) p
Produces a scatter plot of two numeric cell features, with optional colour and faceting variables.
sg_plot_features( features, x = "area", y = "mean_intensity", color = NULL, facet = NULL )sg_plot_features( features, x = "area", y = "mean_intensity", color = NULL, facet = NULL )
features |
A data frame of cell features (e.g., from
|
x |
Character, column name for the x-axis (default |
y |
Character, column name for the y-axis
(default |
color |
Character column name for point colour, or |
facet |
Character column name for faceting, or |
A ggplot2 object.
feat <- data.frame( cell_id = 1:10, area = rpois(10, 200), mean_intensity = runif(10) ) p <- sg_plot_features(feat, x = "area", y = "mean_intensity") pfeat <- data.frame( cell_id = 1:10, area = rpois(10, 200), mean_intensity = runif(10) ) p <- sg_plot_features(feat, x = "area", y = "mean_intensity") p
Assigns colours to cell regions based on cell ID, area, circularity, or cluster membership.
sg_plot_mask( mask, color_by = c("id", "area", "circularity", "cluster"), features = NULL, palette = "viridis" )sg_plot_mask( mask, color_by = c("id", "area", "circularity", "cluster"), features = NULL, palette = "viridis" )
mask |
An |
color_by |
Character, one of |
features |
A data frame of cell features (required when |
palette |
Character, name of a viridis palette
(default |
A ggplot2 object.
labels <- matrix(c(0L, 1L, 1L, 2L, 2L, 0L, 3L, 3L, 0L), 3, 3) mask <- new_sg_mask(labels) p <- sg_plot_mask(mask) plabels <- matrix(c(0L, 1L, 1L, 2L, 2L, 0L, 3L, 3L, 0L), 3, 3) mask <- new_sg_mask(labels) p <- sg_plot_mask(mask) p
Displays a bar chart of segmentation evaluation metrics such as IoU, precision, recall, and F1.
sg_plot_metrics(eval_result)sg_plot_metrics(eval_result)
eval_result |
A data frame with columns |
A ggplot2 object.
res <- data.frame( metric = c("IoU", "Precision", "Recall", "F1"), value = c(0.82, 0.90, 0.85, 0.87) ) p <- sg_plot_metrics(res) pres <- data.frame( metric = c("IoU", "Precision", "Recall", "F1"), value = c(0.82, 0.90, 0.85, 0.87) ) p <- sg_plot_metrics(res) p
Renders a single image channel as a raster and overlays cell outlines from a segmentation mask.
sg_plot_overlay( image, mask = NULL, channel = 1L, outline_color = "#FF00FF", outline_width = 1, fill_alpha = 0, label_cells = FALSE, highlight = NULL )sg_plot_overlay( image, mask = NULL, channel = 1L, outline_color = "#FF00FF", outline_width = 1, fill_alpha = 0, label_cells = FALSE, highlight = NULL )
image |
An |
mask |
An |
channel |
Integer, which channel to display (default |
outline_color |
Character, colour for cell outlines
(default |
outline_width |
Numeric, width of the outline strokes (default |
fill_alpha |
Numeric in [0, 1], fill opacity for cell regions
(default |
label_cells |
Logical, whether to draw cell-ID labels at centroids
(default |
highlight |
Integer vector of cell IDs to highlight, or |
A ggplot2 object.
img <- new_sg_image(matrix(runif(400), 20, 20)) p <- sg_plot_overlay(img) pimg <- new_sg_image(matrix(runif(400), 20, 20)) p <- sg_plot_overlay(img) p
Backend-agnostic prediction facade. The model's backend selects the
protocol (stardist.2d.v1 or cellpose.2d.v1); the run goes through
sg_protocol_run() so parameters are validated and recorded, the
backend is checked at the point of use, and the resulting mask is
staged with the model digest in its provenance. Predictions never
overwrite reviewed masks; use sg_replace_mask() to adopt a reviewed
result explicitly.
sg_predict_model(model, image, ..., protocol = NULL, output = c("mask", "run"))sg_predict_model(model, image, ..., protocol = NULL, output = c("mask", "run"))
model |
An |
image |
An |
... |
Protocol parameters (see |
protocol |
Optional protocol id overriding the backend default. |
output |
|
A staged sg_mask or an sg_run.
mdl <- new_sg_trained_model(tempfile("model"), backend = "stardist", base_model = "none", training_metrics = list()) img <- sg_example_image("fluorescence_nuclei") run <- sg_predict_model(mdl, img, output = "run") # "unavailable" unless a Python with 'stardist' has been selected # (see sg_setup_python()) run$record$statusmdl <- new_sg_trained_model(tempfile("model"), backend = "stardist", base_model = "none", training_metrics = list()) img <- sg_example_image("fluorescence_nuclei") run <- sg_predict_model(mdl, img, output = "run") # "unavailable" unless a Python with 'stardist' has been selected # (see sg_setup_python()) run$record$status
Builds the dataset manifest with sg_dataset_manifest() and materialises
the included tiles: image tiles as float64 TIFF (exact values, [y, x, channel] pages) and mask tiles as unsigned integer TIFF with labels
renumbered 1..N per tile in raster order. Tile object lists map tile
labels to source object ids. With a destination, a directory with
dataset_manifest.json, tiles/<split>/images|masks/*.tif and
integrity.json is written; otherwise tiles are returned in memory.
sg_prepare_training_data(pairs, destination = NULL, ..., overwrite = FALSE)sg_prepare_training_data(pairs, destination = NULL, ..., overwrite = FALSE)
pairs |
A list of training pairs. Each element is a list with
|
destination |
Optional output directory (must not exist or be empty). |
... |
Further arguments for |
overwrite |
Logical; replace an existing prepared dataset. |
An sg_training_set with manifest, path (or NULL) and
tiles (in-memory list when destination is NULL).
img <- sg_example_image("fluorescence_nuclei") # The synthetic example mask contains overlapping ellipses; split them # into separate instances first. msk <- sg_cleanup_labels(sg_example_mask("fluorescence_nuclei"), disconnected = "split") ts <- sg_prepare_training_data( list(list(image = img, mask = msk, subject_id = "A")), tile_size = 32L, min_objects = 0L, split = c(train = 1, validation = 0, test = 0) ) length(ts$tiles)img <- sg_example_image("fluorescence_nuclei") # The synthetic example mask contains overlapping ellipses; split them # into separate instances first. msk <- sg_cleanup_labels(sg_example_mask("fluorescence_nuclei"), disconnected = "split") ts <- sg_prepare_training_data( list(list(image = img, mask = msk, subject_id = "A")), tile_size = 32L, min_objects = 0L, split = c(train = 1, validation = 0, test = 0) ) length(ts$tiles)
Applies a chain of preprocessing steps to an sg_image object,
including optional stain normalisation, denoising, and contrast
enhancement.
sg_preprocess( image, stain_normalize = c("none", "macenko", "reinhard", "vahadane"), denoise = FALSE, contrast = c("none", "clahe", "stretch"), target_resolution = NULL )sg_preprocess( image, stain_normalize = c("none", "macenko", "reinhard", "vahadane"), denoise = FALSE, contrast = c("none", "clahe", "stretch"), target_resolution = NULL )
image |
An |
stain_normalize |
Character string specifying the stain
normalisation method. One of |
denoise |
Logical; if |
contrast |
Character string specifying contrast enhancement.
One of |
target_resolution |
Finite positive numeric scalar or |
A new sg_image object with its history field updated to
record the preprocessing steps applied.
pixels <- matrix(runif(400), nrow = 20, ncol = 20) img <- new_sg_image(pixels) img2 <- sg_preprocess(img) img3 <- sg_preprocess(img, contrast = "stretch", denoise = TRUE)pixels <- matrix(runif(400), nrow = 20, ncol = 20) img <- new_sg_image(pixels) img2 <- sg_preprocess(img) img3 <- sg_preprocess(img, contrast = "stretch", denoise = TRUE)
Get a registered protocol
sg_protocol_get(id, version = NULL)sg_protocol_get(id, version = NULL)
id |
Protocol identifier, e.g. |
version |
Optional exact semantic version. |
An sg_protocol object (a validated named list).
p <- sg_protocol_get("threshold.otsu.v1") p$versionp <- sg_protocol_get("threshold.otsu.v1") p$version
List registered segmentation protocols
sg_protocol_list(check_available = FALSE)sg_protocol_list(check_available = FALSE)
check_available |
Logical; if |
A tibble with one row per protocol: id, version, title,
family, backend, delegate, requires_python, status
("core" or "optional"), available, qupath_mapping and digest.
sg_protocol_list()sg_protocol_list()
Validates the protocol, the parameters and the inputs, delegates to the
corresponding direct function (sg_segment_threshold(),
sg_segment_watershed(), sg_segment_propagate(), sg_cleanup_labels(),
sg_segment_stardist(), sg_segment_cellpose(), sg_segment_mesmer())
with an explicit, recorded argument mapping, and returns the mask or a
run envelope.
sg_protocol_run(image, protocol, ..., output = c("mask", "run"))sg_protocol_run(image, protocol, ..., output = c("mask", "run"))
image |
The primary input: an |
protocol |
Protocol id, |
... |
Parameter overrides (for example |
output |
|
Core protocols run without Python. Optional DNN protocols check their
backend first; when it is missing, output = "mask" signals an
sg_capability_error and output = "run" returns a run with
status = "unavailable". There is never a silent fallback to another
method. DNN predictions are returned as staged masks.
An sg_mask or an sg_run.
sg_protocol_list(), sg_protocol_schema(),
sg_protocol_validate(), sg_export_interchange()
img <- sg_example_image("fluorescence_nuclei") mask <- sg_protocol_run(img, "threshold.otsu.v1", min_area = 5L) run <- sg_protocol_run(img, "threshold.otsu.v1", min_area = 5L, output = "run") run$record$delegate$arguments identical(mask$labels, run$mask$labels)img <- sg_example_image("fluorescence_nuclei") mask <- sg_protocol_run(img, "threshold.otsu.v1", min_area = 5L) run <- sg_protocol_run(img, "threshold.otsu.v1", min_area = 5L, output = "run") run$record$delegate$arguments identical(mask$labels, run$mask$labels)
Protocol schema and parameter specifications
sg_protocol_schema(id = NULL)sg_protocol_schema(id = NULL)
id |
|
For id = NULL, the parsed JSON Schema. Otherwise a tibble with
name, type, default, nullable, minimum, maximum, enum,
unit, requires_calibration, maps_to and description.
names(sg_protocol_schema()$properties) sg_protocol_schema("threshold.otsu.v1")[, c("name", "default", "unit")]names(sg_protocol_schema()$properties) sg_protocol_schema("threshold.otsu.v1")[, c("name", "default", "unit")]
Checks the definition against segmantR-protocol-v1 (schema family and
major version, JSON Schema, parameter mapping completeness, defaults),
resolves parameters (unknown names and out-of-range values are errors),
and, when an image is given, checks the input contract: array order and
size, value semantics, channel/band selection and pixel calibration.
sg_protocol_validate(protocol, image = NULL, ..., error = TRUE)sg_protocol_validate(protocol, image = NULL, ..., error = TRUE)
protocol |
Protocol id, |
image |
Optional |
... |
Parameter overrides and additional inputs (for example
|
error |
Logical; if |
An sg_protocol_validation list with ok, protocol,
parameters, checks (tibble) and error (condition or NULL).
img <- sg_example_image("fluorescence_nuclei") v <- sg_protocol_validate("threshold.otsu.v1", img, min_area = 5L) v$ok bad <- sg_protocol_validate("threshold.otsu.v1", img, min_area = -1L, error = FALSE) bad$error$codeimg <- sg_example_image("fluorescence_nuclei") v <- sg_protocol_validate("threshold.otsu.v1", img, min_area = 5L) v$ok bad <- sg_protocol_validate("threshold.otsu.v1", img, min_area = -1L, error = FALSE) bad$error$code
Reads only the requested bands and pixel window by seeking in the data
file (BSQ, BIL or BIP; either byte order). Values are returned as stored:
gain, offset and reflectance scale factors are recorded but never applied,
and value_semantics is whatever the caller declares (default
"unknown"), so raw counts, reflectance, radiance, intensity and
absorbance are never mixed silently.
sg_read_envi( path, bands = NULL, window = NULL, value_semantics = "unknown", nodata_to_na = TRUE, source_digest = c("full", "header", "none"), data_file = NULL )sg_read_envi( path, bands = NULL, window = NULL, value_semantics = "unknown", nodata_to_na = TRUE, source_digest = c("full", "header", "none"), data_file = NULL )
path |
Path to the |
bands |
Optional 1-based band indices to read (default all). |
window |
Optional |
value_semantics |
Declared meaning of the stored values. |
nodata_to_na |
Replace the header |
source_digest |
|
data_file |
Optional explicit data file path. |
An sg_image with pixels [y, x, band], a band table,
origin set to the window offset, calibration_digest, and
metadata$read_accounting (bytes_read, bands_read).
d <- tempfile("envi") dir.create(d) writeLines(c("ENVI", "samples = 3", "lines = 2", "bands = 2", "data type = 12", "interleave = bip", "byte order = 0", "wavelength = {500, 600}"), file.path(d, "cube.hdr")) writeBin(1:12, file.path(d, "cube"), size = 2L, endian = "little") img <- sg_read_envi(file.path(d, "cube.hdr"), bands = 2, value_semantics = "raw") img$pixelsd <- tempfile("envi") dir.create(d) writeLines(c("ENVI", "samples = 3", "lines = 2", "bands = 2", "data type = 12", "interleave = bip", "byte order = 0", "wavelength = {500, 600}"), file.path(d, "cube.hdr")) writeBin(1:12, file.path(d, "cube"), size = 2L, endian = "little") img <- sg_read_envi(file.path(d, "cube.hdr"), bands = 2, value_semantics = "raw") img$pixels
Converts a centre in physical units (for example micrometres) to pixels
and reads a square window of round(size / pixel_size) pixels in each
requested channel. The top-left pixel is
round(centre / pixel_size) - n %/% 2, so a field is reproducible from
its centre, size and pixel size alone.
sg_read_field(path, channels, centre, size, pixel_size = 1, fill = 0)sg_read_field(path, channels, centre, size, pixel_size = 1, fill = 0)
path |
Path to the image file. |
channels |
Channel names or numbers. |
centre |
Numeric |
size |
Field width in physical units. |
pixel_size |
Physical size of one pixel. |
fill |
Value used outside the image. |
A list of class sg_field with channels (named list of
n x n matrices), x0, y0, n, pixel_size, centre, size and
extent (c(xmin, xmax, ymin, ymax) of the pixel edges in physical
units).
sg_read_fields(), sg_read_window()
f <- tempfile(fileext = ".tif") planes <- list(matrix(1:100, 10, 10), matrix(101:200, 10, 10)) invisible(tiff::writeTIFF(lapply(planes, function(p) p / 255), f, bits.per.sample = 8L)) fld <- sg_read_field(f, c("ch1", "ch2"), centre = c(2.5, 2.5), size = 2, pixel_size = 0.5) fld$channels$ch2f <- tempfile(fileext = ".tif") planes <- list(matrix(1:100, 10, 10), matrix(101:200, 10, 10)) invisible(tiff::writeTIFF(lapply(planes, function(p) p / 255), f, bits.per.sample = 8L)) fld <- sg_read_field(f, c("ch1", "ch2"), centre = c(2.5, 2.5), size = 2, pixel_size = 0.5) fld$channels$ch2
Reads one sg_read_field() per row of a table of centres. Each row names
its image through source, looked up in paths.
sg_read_fields( centres, paths, channels = character(0), size, pixel_size = 1, fill = 0, x = "x", y = "y", source = NULL, id = NULL, channel_columns = NULL, key_prefix = "" )sg_read_fields( centres, paths, channels = character(0), size, pixel_size = 1, fill = 0, x = "x", y = "y", source = NULL, id = NULL, channel_columns = NULL, key_prefix = "" )
centres |
Data frame with centre coordinates and the image key. |
paths |
Named character vector or list: image key to file path, or
a single path used for all rows when |
channels |
Channel names or numbers read for every field. |
size, pixel_size, fill
|
As in |
x, y, source
|
Column names of the centre coordinates and image key. |
id |
Optional column used to name the fields. |
channel_columns |
Optional columns of |
key_prefix |
Prefix added to the |
A named list of sg_field objects in row order; each carries the
table row (as a one-row data frame) in row.
f <- tempfile(fileext = ".tif") planes <- list(matrix(1:100, 10, 10), matrix(101:200, 10, 10)) invisible(tiff::writeTIFF(lapply(planes, function(p) p / 255), f, bits.per.sample = 8L)) cells <- data.frame(id = c("a", "b"), x = c(2.5, 4), y = c(2.5, 3)) fields <- sg_read_fields(cells, f, channels = c("ch1", "ch2"), size = 2, pixel_size = 0.5, id = "id") fields$b$channels$ch2f <- tempfile(fileext = ".tif") planes <- list(matrix(1:100, 10, 10), matrix(101:200, 10, 10)) invisible(tiff::writeTIFF(lapply(planes, function(p) p / 255), f, bits.per.sample = 8L)) cells <- data.frame(id = c("a", "b"), x = c(2.5, 4), y = c(2.5, 3)) fields <- sg_read_fields(cells, f, channels = c("ch1", "ch2"), size = 2, pixel_size = 0.5, id = "id") fields$b$channels$ch2
Reads TIFF, PNG, or JPEG image files and returns an sg_image object.
Dispatches to EBImage::readImage() when available, otherwise uses
imager::load.image(). The returned pixel array is always ordered
[y, x, channel], and the object records the SHA-256 digest of the file
in source_digest plus its base name (never the full path) in
metadata$source_name.
sg_read_image(path, ...)sg_read_image(path, ...)
path |
Character string, path to the image file. |
... |
Additional arguments passed to the underlying reader. |
An sg_image object.
f <- tempfile(fileext = ".tif") EBImage::writeImage(EBImage::Image(matrix(seq(0, 1, length.out = 200), 20, 10)), f) img <- sg_read_image(f) dim(img$pixels)f <- tempfile(fileext = ".tif") EBImage::writeImage(EBImage::Image(matrix(seq(0, 1, length.out = 200), 20, 10)), f) img <- sg_read_image(f) dim(img$pixels)
Reads height rows and width columns of one channel plane starting at
the 0-based pixel offset (x0, y0). Only the image blocks that cover the
window are decoded, so windows of very large whole-slide files are cheap.
Parts of the window outside the image are filled with fill, which makes
fields at the slide edge keep their nominal size.
sg_read_window(path, channel, x0, y0, width, height = width, fill = 0)sg_read_window(path, channel, x0, y0, width, height = width, fill = 0)
path |
Path to the image file. |
channel |
Channel number (as in |
x0, y0
|
0-based column and row of the top-left pixel; may be negative. |
width, height
|
Window size in pixels. |
fill |
Value used outside the image. |
A numeric matrix with height rows and width columns
([y, x]), with attributes x0, y0 and channel (the name).
sg_read_field(), sg_image_channels()
f <- tempfile(fileext = ".tif") plane <- matrix(0:11, nrow = 3, byrow = TRUE) invisible(tiff::writeTIFF(plane / 255, f, bits.per.sample = 8L)) sg_read_window(f, 1, x0 = 1, y0 = 0, width = 2, height = 2)f <- tempfile(fileext = ".tif") plane <- matrix(0:11, nrow = 3, byrow = TRUE) invisible(tiff::writeTIFF(plane / 255, f, bits.per.sample = 8L)) sg_read_window(f, 1, x0 = 1, y0 = 0, width = 2, height = 2)
ROI geometries use null-CRS image coordinates: top-left origin, x right, y down. Layers preserve drawing order and projects retain edit provenance. These classes are distinct from segmantR's instance-mask classes.
sg_roi_rect(), sg_roi_frame(), sg_roi_layer(), sg_roi_project(), sg_roi_mask()
Add a layer to a project
sg_roi_add_layer(project, layer, call = rlang::caller_env())sg_roi_add_layer(project, layer, call = rlang::caller_env())
project |
An sg_roi_project. |
layer |
An sg_roi_layer with a name not already used in the project. |
call |
The calling environment, for error reporting. |
A new sg_roi_project with the layer added. The input is unchanged.
Other projects:
sg_roi_add_roi(),
sg_roi_layers(),
sg_roi_project(),
sg_roi_remove_layer(),
sg_roi_remove_roi(),
sg_roi_rois(),
sg_roi_summary(),
sg_roi_validate()
proj <- sg_roi_project(sg_roi_frame(c(20, 20))) proj <- sg_roi_add_layer(proj, sg_roi_layer("tissue")) names(proj$layers)proj <- sg_roi_project(sg_roi_frame(c(20, 20))) proj <- sg_roi_add_layer(proj, sg_roi_layer("tissue")) names(proj$layers)
Add an ROI to a project layer
sg_roi_add_roi(project, layer, roi, call = rlang::caller_env())sg_roi_add_roi(project, layer, roi, call = rlang::caller_env())
project |
An sg_roi_project. |
layer |
Single string name of the target layer. |
roi |
An sg_roi. |
call |
The calling environment, for error reporting. |
A new sg_roi_project with the ROI added to the layer. A colliding ROI identifier is re-minted to keep identifiers unique across the project. The input is unchanged.
Other projects:
sg_roi_add_layer(),
sg_roi_layers(),
sg_roi_project(),
sg_roi_remove_layer(),
sg_roi_remove_roi(),
sg_roi_rois(),
sg_roi_summary(),
sg_roi_validate()
proj <- sg_roi_project(sg_roi_frame(c(20, 20)), sg_roi_layer("tissue")) proj <- sg_roi_add_roi(proj, "tissue", sg_roi_rect(2, 2, 8, 8, label = "tissue")) sg_roi_rois(proj)$area_pxproj <- sg_roi_project(sg_roi_frame(c(20, 20)), sg_roi_layer("tissue")) proj <- sg_roi_add_roi(proj, "tissue", sg_roi_rect(2, 2, 8, 8, label = "tissue")) sg_roi_rois(proj)$area_px
ROI area
sg_roi_area( roi, level = 0L, units = c("px", "physical"), call = rlang::caller_env() )sg_roi_area( roi, level = 0L, units = c("px", "physical"), call = rlang::caller_env() )
roi |
An sg_roi. |
level |
Integer pyramid level at which to express the area. Default |
units |
Either |
call |
The calling environment, for error reporting. |
A numeric scalar area, or NA_real_ for non-areal geometry (points,
lines).
Other rois:
sg_roi_bbox(),
sg_roi_centroid(),
sg_roi_circle(),
sg_roi_ellipse(),
sg_roi_freehand(),
sg_roi_from_geojson(),
sg_roi_from_sf(),
sg_roi_point(),
sg_roi_polygon(),
sg_roi_rect()
sg_roi_area(sg_roi_rect(0, 0, 10, 5, label = "a"))sg_roi_area(sg_roi_rect(0, 0, 10, 5, label = "a"))
ROI bounding box
sg_roi_bbox(roi, call = rlang::caller_env())sg_roi_bbox(roi, call = rlang::caller_env())
roi |
An sg_roi. |
call |
The calling environment, for error reporting. |
A numeric vector c(xmin, ymin, xmax, ymax) in the ROI's stored
coordinates.
Other rois:
sg_roi_area(),
sg_roi_centroid(),
sg_roi_circle(),
sg_roi_ellipse(),
sg_roi_freehand(),
sg_roi_from_geojson(),
sg_roi_from_sf(),
sg_roi_point(),
sg_roi_polygon(),
sg_roi_rect()
sg_roi_bbox(sg_roi_circle(50, 50, 10, label = "a"))sg_roi_bbox(sg_roi_circle(50, 50, 10, label = "a"))
Buffer an ROI
sg_roi_buffer(roi, dist, call = rlang::caller_env())sg_roi_buffer(roi, dist, call = rlang::caller_env())
roi |
An sg_roi. |
dist |
Numeric buffer distance in pixels (may be negative to erode). |
call |
The calling environment, for error reporting. |
An sg_roi with the buffered geometry.
Other geometry:
sg_roi_check_containment(),
sg_roi_check_geometry(),
sg_roi_clamp(),
sg_roi_contains(),
sg_roi_distance(),
sg_roi_fix_geometry(),
sg_roi_flip_y(),
sg_roi_overlaps(),
sg_roi_rescale(),
sg_roi_ring(),
sg_roi_rois_overlap(),
sg_roi_setops,
sg_roi_simplify(),
sg_roi_snap(),
sg_roi_transform()
sg_roi_buffer(sg_roi_point(10, 10, label = "a"), dist = 5)sg_roi_buffer(sg_roi_point(10, 10, label = "a"), dist = 5)
ROI centroid
sg_roi_centroid(roi, call = rlang::caller_env())sg_roi_centroid(roi, call = rlang::caller_env())
roi |
An sg_roi. |
call |
The calling environment, for error reporting. |
A numeric vector c(x, y) in the ROI's stored coordinates (at its
own level).
Other rois:
sg_roi_area(),
sg_roi_bbox(),
sg_roi_circle(),
sg_roi_ellipse(),
sg_roi_freehand(),
sg_roi_from_geojson(),
sg_roi_from_sf(),
sg_roi_point(),
sg_roi_polygon(),
sg_roi_rect()
sg_roi_centroid(sg_roi_rect(0, 0, 10, 10, label = "a"))sg_roi_centroid(sg_roi_rect(0, 0, 10, 10, label = "a"))
Report ROIs in a constrained layer that fall outside their container region.
A layer declares the constraint through its metadata, e.g.
sg_roi_layer("state", within = list(layer = "anatomy", label = "wound")); then
every ROI in state must be spatially covered by the union of the anatomy
layer's wound ROIs. This enforces the annotation rule that a class is
painted only inside its region of interest. The report mirrors the shape of
sg_roi_check_geometry().
sg_roi_check_containment(project, tol = 0, call = rlang::caller_env())sg_roi_check_containment(project, tol = 0, call = rlang::caller_env())
project |
An sg_roi_project. |
tol |
Non-negative slack, in level-0 pixels, by which the container is
grown before testing, to tolerate sub-pixel tracing overhang. Default |
call |
The calling environment, for error reporting. |
A tibble::tibble with columns roi_id, layer, issue,
severity ("warning" for an ROI outside its container, "error" for a
missing/empty container), and fixable (always FALSE). A 0-row tibble
when every constrained ROI is contained, or when no layer declares a
within constraint.
sg_roi_check_geometry(), sg_roi_validate()
Other geometry:
sg_roi_buffer(),
sg_roi_check_geometry(),
sg_roi_clamp(),
sg_roi_contains(),
sg_roi_distance(),
sg_roi_fix_geometry(),
sg_roi_flip_y(),
sg_roi_overlaps(),
sg_roi_rescale(),
sg_roi_ring(),
sg_roi_rois_overlap(),
sg_roi_setops,
sg_roi_simplify(),
sg_roi_snap(),
sg_roi_transform()
anatomy <- sg_roi_layer_add(sg_roi_layer("anatomy", labels = "wound"), sg_roi_rect(2, 2, 8, 8, label = "wound")) state <- sg_roi_layer("state", labels = "injury", within = list(layer = "anatomy", label = "wound")) state <- sg_roi_layer_add(state, sg_roi_rect(0, 0, 4, 4, label = "injury")) sg_roi_check_containment(sg_roi_project(sg_roi_frame(c(100, 100)), list(anatomy, state)))anatomy <- sg_roi_layer_add(sg_roi_layer("anatomy", labels = "wound"), sg_roi_rect(2, 2, 8, 8, label = "wound")) state <- sg_roi_layer("state", labels = "injury", within = list(layer = "anatomy", label = "wound")) state <- sg_roi_layer_add(state, sg_roi_rect(0, 0, 4, 4, label = "injury")) sg_roi_check_containment(sg_roi_project(sg_roi_frame(c(100, 100)), list(anatomy, state)))
Check the geometry of every ROI in a project
sg_roi_check_geometry(project, call = rlang::caller_env())sg_roi_check_geometry(project, call = rlang::caller_env())
project |
An sg_roi_project. |
call |
The calling environment, for error reporting. |
A tibble::tibble with columns roi_id (character), issue
(character), severity (character, "error"/"warning"), and fixable
(logical). Detected issues: self-intersection, invalid geometry, zero area,
degenerate rings, out-of-bounds vertices, duplicate consecutive vertices,
ring orientation, and NA coordinates. A 0-row tibble when all geometry is
valid.
sg_roi_fix_geometry(), sg_roi_validate()
Other geometry:
sg_roi_buffer(),
sg_roi_check_containment(),
sg_roi_clamp(),
sg_roi_contains(),
sg_roi_distance(),
sg_roi_fix_geometry(),
sg_roi_flip_y(),
sg_roi_overlaps(),
sg_roi_rescale(),
sg_roi_ring(),
sg_roi_rois_overlap(),
sg_roi_setops,
sg_roi_simplify(),
sg_roi_snap(),
sg_roi_transform()
lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue")) proj <- sg_roi_project(sg_roi_frame(c(20, 20)), lyr) sg_roi_check_geometry(proj)lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue")) proj <- sg_roi_project(sg_roi_frame(c(20, 20)), lyr) sg_roi_check_geometry(proj)
The circle is approximated by a regular polygon of n_seg segments.
sg_roi_circle( x, y, r, label, level = 0L, n_seg = 64L, ..., call = rlang::caller_env() )sg_roi_circle( x, y, r, label, level = 0L, n_seg = 64L, ..., call = rlang::caller_env() )
x, y
|
Numeric centre coordinates in image pixels. |
r |
Positive numeric radius in pixels. |
label |
Single string class label. |
level |
Integer pyramid level the coordinates refer to. Default |
n_seg |
Integer number of polygon segments approximating the circle. |
... |
Additional named attributes stored on the ROI. The reserved names
|
call |
The calling environment, for error reporting. |
An sg_roi with POLYGON geometry and attributes$shape = "circle", so exports can flag the polygon as an approximation.
Other rois:
sg_roi_area(),
sg_roi_bbox(),
sg_roi_centroid(),
sg_roi_ellipse(),
sg_roi_freehand(),
sg_roi_from_geojson(),
sg_roi_from_sf(),
sg_roi_point(),
sg_roi_polygon(),
sg_roi_rect()
r <- sg_roi_circle(50, 50, r = 10, label = "nucleus")r <- sg_roi_circle(50, 50, r = 10, label = "nucleus")
Clip an ROI to image bounds
sg_roi_clamp(roi, dims, call = rlang::caller_env())sg_roi_clamp(roi, dims, call = rlang::caller_env())
roi |
An sg_roi. |
dims |
Integer |
call |
The calling environment, for error reporting. |
An sg_roi clipped to [0, width] x [0, height]. Warns if the
clip empties the geometry.
Other geometry:
sg_roi_buffer(),
sg_roi_check_containment(),
sg_roi_check_geometry(),
sg_roi_contains(),
sg_roi_distance(),
sg_roi_fix_geometry(),
sg_roi_flip_y(),
sg_roi_overlaps(),
sg_roi_rescale(),
sg_roi_ring(),
sg_roi_rois_overlap(),
sg_roi_setops,
sg_roi_simplify(),
sg_roi_snap(),
sg_roi_transform()
sg_roi_clamp(sg_roi_rect(-5, -5, 20, 20, label = "a"), dims = c(10, 10))sg_roi_clamp(sg_roi_rect(-5, -5, 20, 20, label = "a"), dims = c(10, 10))
Test whether points fall inside an ROI
sg_roi_contains(roi, x, y, call = rlang::caller_env())sg_roi_contains(roi, x, y, call = rlang::caller_env())
roi |
An sg_roi. |
x, y
|
Numeric coordinate vectors of equal length. |
call |
The calling environment, for error reporting. |
A logical vector of length length(x).
Other geometry:
sg_roi_buffer(),
sg_roi_check_containment(),
sg_roi_check_geometry(),
sg_roi_clamp(),
sg_roi_distance(),
sg_roi_fix_geometry(),
sg_roi_flip_y(),
sg_roi_overlaps(),
sg_roi_rescale(),
sg_roi_ring(),
sg_roi_rois_overlap(),
sg_roi_setops,
sg_roi_simplify(),
sg_roi_snap(),
sg_roi_transform()
sg_roi_contains(sg_roi_rect(0, 0, 10, 10, label = "a"), c(5, 20), c(5, 20))sg_roi_contains(sg_roi_rect(0, 0, 10, 10, label = "a"), c(5, 20), c(5, 20))
Return the pixel dimensions c(width, height) of an sg_roi_frame at a
given pyramid level.
sg_roi_dims(x, level = 0L, call = rlang::caller_env())sg_roi_dims(x, level = 0L, call = rlang::caller_env())
x |
An sg_roi_frame. |
level |
Integer pyramid level, |
call |
The calling environment, for error reporting. |
An integer vector of length 2, c(width, height).
sg_roi_dims(sg_roi_frame(c(100, 80)))sg_roi_dims(sg_roi_frame(c(100, 80)))
Distance between two ROIs
sg_roi_distance(roi1, roi2, call = rlang::caller_env())sg_roi_distance(roi1, roi2, call = rlang::caller_env())
roi1, roi2
|
sg_roi objects. |
call |
The calling environment, for error reporting. |
A numeric scalar distance in level-0 pixels.
Other geometry:
sg_roi_buffer(),
sg_roi_check_containment(),
sg_roi_check_geometry(),
sg_roi_clamp(),
sg_roi_contains(),
sg_roi_fix_geometry(),
sg_roi_flip_y(),
sg_roi_overlaps(),
sg_roi_rescale(),
sg_roi_ring(),
sg_roi_rois_overlap(),
sg_roi_setops,
sg_roi_simplify(),
sg_roi_snap(),
sg_roi_transform()
a <- sg_roi_rect(0, 0, 4, 4, label = "a") b <- sg_roi_rect(10, 0, 14, 4, label = "b") sg_roi_distance(a, b)a <- sg_roi_rect(0, 0, 4, 4, label = "a") b <- sg_roi_rect(10, 0, 14, 4, label = "b") sg_roi_distance(a, b)
Create an elliptical ROI
sg_roi_ellipse( x, y, rx, ry, rotation = 0, label, level = 0L, n_seg = 64L, ..., call = rlang::caller_env() )sg_roi_ellipse( x, y, rx, ry, rotation = 0, label, level = 0L, n_seg = 64L, ..., call = rlang::caller_env() )
x, y
|
Numeric centre coordinates in image pixels. |
rx, ry
|
Positive numeric semi-axis lengths in pixels. |
rotation |
Rotation of the major axis in degrees, clockwise in image
orientation. Default |
label |
Single string class label. |
level |
Integer pyramid level the coordinates refer to. Default |
n_seg |
Integer number of polygon segments approximating the ellipse. |
... |
Additional named attributes stored on the ROI. The reserved names
|
call |
The calling environment, for error reporting. |
An sg_roi with POLYGON geometry and attributes$shape = "ellipse", so exports can flag the polygon as an approximation.
Other rois:
sg_roi_area(),
sg_roi_bbox(),
sg_roi_centroid(),
sg_roi_circle(),
sg_roi_freehand(),
sg_roi_from_geojson(),
sg_roi_from_sf(),
sg_roi_point(),
sg_roi_polygon(),
sg_roi_rect()
r <- sg_roi_ellipse(50, 50, rx = 20, ry = 10, rotation = 30, label = "cell")r <- sg_roi_ellipse(50, 50, rx = 20, ry = 10, rotation = 30, label = "cell")
Apply sf::st_make_valid() to invalid ROIs (which also drops duplicate
consecutive vertices) and clamp out-of-bounds vertices into the image bounds,
reporting what changed.
sg_roi_fix_geometry(project, verbose = TRUE, call = rlang::caller_env())sg_roi_fix_geometry(project, verbose = TRUE, call = rlang::caller_env())
project |
An sg_roi_project. |
verbose |
Logical; whether to report repairs. Default |
call |
The calling environment, for error reporting. |
The sg_roi_project with repaired geometry. Repairs are reported via
cli::cli_inform() when verbose is TRUE. Issues that cannot be repaired
(zero area, degenerate, NA coordinates) are left in place and reported.
Other geometry:
sg_roi_buffer(),
sg_roi_check_containment(),
sg_roi_check_geometry(),
sg_roi_clamp(),
sg_roi_contains(),
sg_roi_distance(),
sg_roi_flip_y(),
sg_roi_overlaps(),
sg_roi_rescale(),
sg_roi_ring(),
sg_roi_rois_overlap(),
sg_roi_setops,
sg_roi_simplify(),
sg_roi_snap(),
sg_roi_transform()
# a rectangle reaching past the image edge is clamped into the image lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(-2, -2, 8, 8, label = "tissue")) proj <- sg_roi_project(sg_roi_frame(c(20, 20)), lyr) fixed <- sg_roi_fix_geometry(proj) sg_roi_rois(fixed)$area_px# a rectangle reaching past the image edge is clamped into the image lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(-2, -2, 8, 8, label = "tissue")) proj <- sg_roi_project(sg_roi_frame(c(20, 20)), lyr) fixed <- sg_roi_fix_geometry(proj) sg_roi_rois(fixed)$area_px
Convert between image orientation (top-left origin, y down) and GIS orientation (bottom-left origin, y up). Self-inverse.
sg_roi_flip_y(roi, height, call = rlang::caller_env())sg_roi_flip_y(roi, height, call = rlang::caller_env())
roi |
An sg_roi. |
height |
Numeric image height in pixels at the ROI's reference level. |
call |
The calling environment, for error reporting. |
An sg_roi with the y-axis flipped.
Other geometry:
sg_roi_buffer(),
sg_roi_check_containment(),
sg_roi_check_geometry(),
sg_roi_clamp(),
sg_roi_contains(),
sg_roi_distance(),
sg_roi_fix_geometry(),
sg_roi_overlaps(),
sg_roi_rescale(),
sg_roi_ring(),
sg_roi_rois_overlap(),
sg_roi_setops,
sg_roi_simplify(),
sg_roi_snap(),
sg_roi_transform()
sg_roi_flip_y(sg_roi_rect(0, 0, 10, 5, label = "a"), height = 100)sg_roi_flip_y(sg_roi_rect(0, 0, 10, 5, label = "a"), height = 100)
A metadata-only frame; no image reader, spectral backend, or pixel data is loaded. Coordinates have top-left origin, x right, y down. Pyramid dimensions are supplied explicitly, permitting anisotropic and non-power-of-two levels. Calibration is the physical size of a level-zero pixel along x and y.
sg_roi_frame( dims, level_dims = list(dims), pixel_size = c(1, 1), pixel_unit = "px", source = "" )sg_roi_frame( dims, level_dims = list(dims), pixel_size = c(1, 1), pixel_unit = "px", source = "" )
dims |
Integer-valued width and height at level zero. |
level_dims |
List of width/height vectors, starting with |
pixel_size |
Positive finite x/y pixel sizes at level zero. |
pixel_unit |
Unit of the calibration, e.g. |
source |
Image identifier or path, recorded without reading the file. |
A sg_roi_frame for sg_roi_project() and sg_roi_transform().
frame <- sg_roi_frame(c(100, 80), list(c(100, 80), c(30, 20)), c(0.5, 0.8), "um") sg_roi_dims(frame, 1)frame <- sg_roi_frame(c(100, 80), list(c(100, 80), c(30, 20)), c(0.5, 0.8), "um") sg_roi_dims(frame, 1)
A freehand trace is stored as a closed polygon, optionally simplified.
sg_roi_freehand( coords, label, level = 0L, simplify = 0, ..., call = rlang::caller_env() )sg_roi_freehand( coords, label, level = 0L, simplify = 0, ..., call = rlang::caller_env() )
coords |
Two-column numeric matrix of vertices in drawing order. |
label |
Single string class label. |
level |
Integer pyramid level the coordinates refer to. Default |
simplify |
Non-negative Douglas-Peucker tolerance ( |
... |
Additional named attributes stored on the ROI. The reserved names
|
call |
The calling environment, for error reporting. |
An sg_roi with POLYGON geometry.
Other rois:
sg_roi_area(),
sg_roi_bbox(),
sg_roi_centroid(),
sg_roi_circle(),
sg_roi_ellipse(),
sg_roi_from_geojson(),
sg_roi_from_sf(),
sg_roi_point(),
sg_roi_polygon(),
sg_roi_rect()
pts <- cbind(c(0, 5, 10, 5), c(0, 2, 0, -2)) r <- sg_roi_freehand(pts, label = "trace")pts <- cbind(c(0, 5, 10, 5), c(0, 2, 0, -2)) r <- sg_roi_freehand(pts, label = "trace")
Turn a single parsed GeoJSON feature (a list with geometry and optional
properties) into an sg_roi. Useful for consuming interactive drawing
output.
sg_roi_from_geojson( feature, label = NULL, level = 0L, source = "manual", call = rlang::caller_env() )sg_roi_from_geojson( feature, label = NULL, level = 0L, source = "manual", call = rlang::caller_env() )
feature |
A parsed GeoJSON feature: a list with a |
label |
Single string class label; taken from |
level |
Integer pyramid level. Default |
source |
Provenance source string. Default |
call |
The calling environment, for error reporting. |
An sg_roi.
Other io:
sg_roi_read_geojson(),
sg_roi_read_qupath(),
sg_roi_write_geojson(),
sg_roi_write_qupath()
Other rois:
sg_roi_area(),
sg_roi_bbox(),
sg_roi_centroid(),
sg_roi_circle(),
sg_roi_ellipse(),
sg_roi_freehand(),
sg_roi_from_sf(),
sg_roi_point(),
sg_roi_polygon(),
sg_roi_rect()
feat <- list(geometry = list(type = "Polygon", coordinates = list(list(c(0, 0), c(4, 0), c(4, 4), c(0, 4), c(0, 0))))) sg_roi_from_geojson(feat, label = "region")feat <- list(geometry = list(type = "Polygon", coordinates = list(list(c(0, 0), c(4, 0), c(4, 4), c(0, 4), c(0, 0))))) sg_roi_from_geojson(feat, label = "region")
Create an ROI from an existing sf geometry
sg_roi_from_sf(geometry, label, level = 0L, ..., call = rlang::caller_env())sg_roi_from_sf(geometry, label, level = 0L, ..., call = rlang::caller_env())
geometry |
An |
label |
Single string class label. |
level |
Integer pyramid level the coordinates refer to. Default |
... |
Additional named attributes stored on the ROI. The reserved names
|
call |
The calling environment, for error reporting. |
An sg_roi wrapping the supplied geometry.
Other rois:
sg_roi_area(),
sg_roi_bbox(),
sg_roi_centroid(),
sg_roi_circle(),
sg_roi_ellipse(),
sg_roi_freehand(),
sg_roi_from_geojson(),
sg_roi_point(),
sg_roi_polygon(),
sg_roi_rect()
g <- sf::st_point(c(3, 4)) r <- sg_roi_from_sf(g, label = "imported", source = "imported")g <- sf::st_point(c(3, 4)) r <- sg_roi_from_sf(g, label = "imported", source = "imported")
Create a layer
sg_roi_layer( name, labels = character(), style = sg_roi_style(), ..., call = rlang::caller_env() )sg_roi_layer( name, labels = character(), style = sg_roi_style(), ..., call = rlang::caller_env() )
name |
Single string layer name (unique within a project). |
labels |
Character vector; the controlled label vocabulary for the layer. |
style |
An |
... |
Additional named metadata stored on the layer. |
call |
The calling environment, for error reporting. |
An sg_roi_layer with no ROIs and a resolved colour mapping.
sg_roi_style(), sg_roi_layer_add()
Other layers:
sg_roi_layer_add(),
sg_roi_layer_n(),
sg_roi_layer_remove(),
sg_roi_layer_rois(),
sg_roi_style()
lyr <- sg_roi_layer("tumour", labels = c("tumour", "stroma")) sg_roi_layer_n(lyr)lyr <- sg_roi_layer("tumour", labels = c("tumour", "stroma")) sg_roi_layer_n(lyr)
Add an ROI to a layer
sg_roi_layer_add(layer, roi, call = rlang::caller_env())sg_roi_layer_add(layer, roi, call = rlang::caller_env())
layer |
An sg_roi_layer. |
roi |
An sg_roi. |
call |
The calling environment, for error reporting. |
A new sg_roi_layer with the ROI appended. The label vocabulary and colour mapping are extended if the ROI introduces a new label. A colliding ROI identifier is re-minted to preserve uniqueness. The input is unchanged.
Other layers:
sg_roi_layer(),
sg_roi_layer_n(),
sg_roi_layer_remove(),
sg_roi_layer_rois(),
sg_roi_style()
lyr <- sg_roi_layer("tumour", labels = "tumour") lyr <- sg_roi_layer_add(lyr, sg_roi_rect(0, 0, 10, 10, label = "tumour")) sg_roi_layer_n(lyr)lyr <- sg_roi_layer("tumour", labels = "tumour") lyr <- sg_roi_layer_add(lyr, sg_roi_rect(0, 0, 10, 10, label = "tumour")) sg_roi_layer_n(lyr)
Number of ROIs in a layer
sg_roi_layer_n(layer, call = rlang::caller_env())sg_roi_layer_n(layer, call = rlang::caller_env())
layer |
An sg_roi_layer. |
call |
The calling environment, for error reporting. |
An integer scalar.
Other layers:
sg_roi_layer(),
sg_roi_layer_add(),
sg_roi_layer_remove(),
sg_roi_layer_rois(),
sg_roi_style()
lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(0, 0, 4, 4, label = "tissue")) sg_roi_layer_n(lyr)lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(0, 0, 4, 4, label = "tissue")) sg_roi_layer_n(lyr)
Remove an ROI from a layer
sg_roi_layer_remove(layer, id, call = rlang::caller_env())sg_roi_layer_remove(layer, id, call = rlang::caller_env())
layer |
An sg_roi_layer. |
id |
Single string ROI identifier. |
call |
The calling environment, for error reporting. |
A new sg_roi_layer without the identified ROI. Warns if the ROI is not present and returns the layer unchanged.
Other layers:
sg_roi_layer(),
sg_roi_layer_add(),
sg_roi_layer_n(),
sg_roi_layer_rois(),
sg_roi_style()
lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(0, 0, 4, 4, label = "tissue", id = "r1")) sg_roi_layer_n(sg_roi_layer_remove(lyr, "r1"))lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(0, 0, 4, 4, label = "tissue", id = "r1")) sg_roi_layer_n(sg_roi_layer_remove(lyr, "r1"))
Layer ROI table
sg_roi_layer_rois(layer, image = NULL, call = rlang::caller_env())sg_roi_layer_rois(layer, image = NULL, call = rlang::caller_env())
layer |
An sg_roi_layer. |
image |
Optional sg_roi_frame for accurate level-0 coordinate transforms. |
call |
The calling environment, for error reporting. |
An ROI table (see sg_roi_rois() for the column contract). A 0-row table
with the same columns when the layer has no ROIs.
Other layers:
sg_roi_layer(),
sg_roi_layer_add(),
sg_roi_layer_n(),
sg_roi_layer_remove(),
sg_roi_style()
lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(0, 0, 4, 4, label = "tumour")) lyr <- sg_roi_layer_add(lyr, sg_roi_rect(5, 5, 8, 8, label = "stroma")) sg_roi_layer_rois(lyr)[, c("label", "area_px")]lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(0, 0, 4, 4, label = "tumour")) lyr <- sg_roi_layer_add(lyr, sg_roi_rect(5, 5, 8, 8, label = "stroma")) sg_roi_layer_rois(lyr)[, c("label", "area_px")]
Layer summary table
sg_roi_layers(project, call = rlang::caller_env())sg_roi_layers(project, call = rlang::caller_env())
project |
An sg_roi_project. |
call |
The calling environment, for error reporting. |
A tibble::tibble with one row per layer and the columns name
(character), n_rois (integer), labels (list of character), visible
(logical), locked (logical), and z (integer). A 0-row tibble with these
columns when the project has no layers.
Other projects:
sg_roi_add_layer(),
sg_roi_add_roi(),
sg_roi_project(),
sg_roi_remove_layer(),
sg_roi_remove_roi(),
sg_roi_rois(),
sg_roi_summary(),
sg_roi_validate()
proj <- sg_roi_project(sg_roi_frame(c(20, 20)), list(sg_roi_layer("tumour"), sg_roi_layer("stroma"))) sg_roi_layers(proj)proj <- sg_roi_project(sg_roi_frame(c(20, 20)), list(sg_roi_layer("tumour"), sg_roi_layer("stroma"))) sg_roi_layers(proj)
Produce a binary, labelled, or multi-class integer mask from annotations. This is the package's core output artefact.
sg_roi_mask( x, type = c("binary", "labelled", "multiclass"), layer = NULL, label = NULL, level = 0L, background = 0L, touches = FALSE, dims = NULL, values = NULL, overlap = c("last", "first", "max", "min", "error", "bitor"), engine = c("stars", "terra"), call = rlang::caller_env() )sg_roi_mask( x, type = c("binary", "labelled", "multiclass"), layer = NULL, label = NULL, level = 0L, background = 0L, touches = FALSE, dims = NULL, values = NULL, overlap = c("last", "first", "max", "min", "error", "bitor"), engine = c("stars", "terra"), call = rlang::caller_env() )
x |
An sg_roi, sg_roi_layer, or sg_roi_project. |
type |
|
layer |
Optional layer name(s) to restrict to (projects only). |
label |
Optional label(s) to restrict to. |
level |
Integer pyramid level at which to rasterise. Default |
background |
Integer background value. Default |
touches |
Logical; see the coverage contract. Default |
dims |
Optional |
values |
Optional named integer vector mapping labels to explicit class
codes (e.g. |
overlap |
How overlapping ROIs resolve: |
engine |
|
call |
The calling environment, for error reporting. |
Pixel-coverage contract. Pixel (i, j) covers the half-open square
[j-1, j) x [i-1, i) with (0, 0) at the top-left corner of the top-left
pixel; its centre is (j - 0.5, i - 0.5). With touches = FALSE (default) a
pixel is included when its centre lies inside the polygon; with
touches = TRUE a pixel is included if the polygon touches it at all. ROI
coordinates use the image convention (top-left origin, y down).
An sg_roi_mask: a matrix (logical for "binary", otherwise integer)
with attributes legend (a tibble with columns value, label, layer,
roi_id, n_px, colour), level, dims, type, and created. An
all-background mask of the correct dimensions is returned when there are no
ROIs.
sg_roi_mask_legend(), sg_roi_mask_stats()
Other masks:
sg_roi_mask_boundary(),
sg_roi_mask_derive(),
sg_roi_mask_legend(),
sg_roi_mask_preview(),
sg_roi_mask_stack(),
sg_roi_mask_stats()
lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue")) proj <- sg_roi_project(sg_roi_frame(c(20, 20)), lyr) m <- sg_roi_mask(proj, type = "multiclass") table(as.integer(m))lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue")) proj <- sg_roi_project(sg_roi_frame(c(20, 20)), lyr) m <- sg_roi_mask(proj, type = "multiclass") table(as.integer(m))
Object boundaries of a mask
sg_roi_mask_boundary(mask, width = 1L, call = rlang::caller_env())sg_roi_mask_boundary(mask, width = 1L, call = rlang::caller_env())
mask |
An |
width |
Integer boundary thickness in pixels. Default |
call |
The calling environment, for error reporting. |
A logical matrix marking boundary pixels (where a 4-neighbour has a different value).
Other masks:
sg_roi_mask(),
sg_roi_mask_derive(),
sg_roi_mask_legend(),
sg_roi_mask_preview(),
sg_roi_mask_stack(),
sg_roi_mask_stats()
lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue")) m <- sg_roi_mask(sg_roi_project(sg_roi_frame(c(10, 10)), lyr), "labelled") sg_roi_mask_boundary(m) * 1Llyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue")) m <- sg_roi_mask(sg_roi_project(sg_roi_frame(c(10, 10)), lyr), "labelled") sg_roi_mask_boundary(m) * 1L
Combine rasterised layer masks into the derived training mask
state WHERE anatomy == keep_label AND artefact == 0 AND state != background.
This is the cross-layer operation the four-layer HSI scheme relies on: it
keeps a state (class) label only where the anatomy layer marks the region of
interest, no artefact bit is set, and the state is actually labelled.
sg_roi_mask_derive( state, anatomy, artefact = NULL, keep_label = "wound", background = 0L, call = rlang::caller_env() )sg_roi_mask_derive( state, anatomy, artefact = NULL, keep_label = "wound", background = 0L, call = rlang::caller_env() )
state |
An |
anatomy |
An |
artefact |
Optional |
keep_label |
The anatomy label whose region is kept (e.g. |
background |
Integer background/unlabelled value. Default |
call |
The calling environment, for error reporting. |
An sg_roi_mask (multiclass) of the surviving state codes, with the
state legend restricted to those classes and pixel counts recomputed.
sg_roi_mask(), sg_roi_mask_stack()
Other masks:
sg_roi_mask(),
sg_roi_mask_boundary(),
sg_roi_mask_legend(),
sg_roi_mask_preview(),
sg_roi_mask_stack(),
sg_roi_mask_stats()
lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue")) proj <- sg_roi_project(sg_roi_frame(c(20, 20)), lyr) # A single-layer project derives trivially; the four-layer HSI workflow passes # separate anatomy/state/artefact masks. See the masks vignette. m <- sg_roi_mask(proj, "multiclass") sg_roi_mask_derive(m, m, keep_label = sg_roi_mask_legend(m)$label[1])lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue")) proj <- sg_roi_project(sg_roi_frame(c(20, 20)), lyr) # A single-layer project derives trivially; the four-layer HSI workflow passes # separate anatomy/state/artefact masks. See the masks vignette. m <- sg_roi_mask(proj, "multiclass") sg_roi_mask_derive(m, m, keep_label = sg_roi_mask_legend(m)$label[1])
Legend of a mask
sg_roi_mask_legend(mask, call = rlang::caller_env())sg_roi_mask_legend(mask, call = rlang::caller_env())
mask |
An |
call |
The calling environment, for error reporting. |
The mask's legend tibble::tibble (value, label, layer,
roi_id, n_px, colour).
Other masks:
sg_roi_mask(),
sg_roi_mask_boundary(),
sg_roi_mask_derive(),
sg_roi_mask_preview(),
sg_roi_mask_stack(),
sg_roi_mask_stats()
lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue")) proj <- sg_roi_project(sg_roi_frame(c(20, 20)), lyr) sg_roi_mask_legend(sg_roi_mask(proj, "labelled"))lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue")) proj <- sg_roi_project(sg_roi_frame(c(20, 20)), lyr) sg_roi_mask_legend(sg_roi_mask(proj, "labelled"))
Nearest-neighbour downsample only (interpolating a label mask would invent labels that do not exist).
sg_roi_mask_preview(mask, max_dim = 1024L, call = rlang::caller_env())sg_roi_mask_preview(mask, max_dim = 1024L, call = rlang::caller_env())
mask |
An |
max_dim |
Integer maximum dimension of the preview. Default |
call |
The calling environment, for error reporting. |
A downsampled sg_roi_mask with the legend pixel counts recomputed.
Other masks:
sg_roi_mask(),
sg_roi_mask_boundary(),
sg_roi_mask_derive(),
sg_roi_mask_legend(),
sg_roi_mask_stack(),
sg_roi_mask_stats()
lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(20, 20, 80, 80, label = "tissue")) m <- sg_roi_mask(sg_roi_project(sg_roi_frame(c(100, 100)), lyr), "labelled") dim(sg_roi_mask_preview(m, max_dim = 25))lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(20, 20, 80, 80, label = "tissue")) m <- sg_roi_mask(sg_roi_project(sg_roi_frame(c(100, 100)), lyr), "labelled") dim(sg_roi_mask_preview(m, max_dim = 25))
Stack per-layer masks into a 3D array
sg_roi_mask_stack( project, layers = NULL, level = 0L, call = rlang::caller_env() )sg_roi_mask_stack( project, layers = NULL, level = 0L, call = rlang::caller_env() )
project |
An sg_roi_project. |
layers |
Optional layer name(s) to include; all by default. |
level |
Integer pyramid level. Default |
call |
The calling environment, for error reporting. |
A 3D integer array [y, x, layer], one multi-class plane per layer;
the third dimension is named by layer.
Other masks:
sg_roi_mask(),
sg_roi_mask_boundary(),
sg_roi_mask_derive(),
sg_roi_mask_legend(),
sg_roi_mask_preview(),
sg_roi_mask_stats()
tumour <- sg_roi_layer_add(sg_roi_layer("tumour"), sg_roi_rect(2, 2, 8, 8, label = "tumour")) stroma <- sg_roi_layer_add(sg_roi_layer("stroma"), sg_roi_rect(10, 10, 18, 18, label = "stroma")) proj <- sg_roi_project(sg_roi_frame(c(20, 20)), list(tumour, stroma)) dim(sg_roi_mask_stack(proj))tumour <- sg_roi_layer_add(sg_roi_layer("tumour"), sg_roi_rect(2, 2, 8, 8, label = "tumour")) stroma <- sg_roi_layer_add(sg_roi_layer("stroma"), sg_roi_rect(10, 10, 18, 18, label = "stroma")) proj <- sg_roi_project(sg_roi_frame(c(20, 20)), list(tumour, stroma)) dim(sg_roi_mask_stack(proj))
Per-value statistics of a mask
sg_roi_mask_stats(mask, pixel_size = NULL, call = rlang::caller_env())sg_roi_mask_stats(mask, pixel_size = NULL, call = rlang::caller_env())
mask |
An |
pixel_size |
Optional numeric |
call |
The calling environment, for error reporting. |
A tibble::tibble with one row per mask value: value, label,
n_px, area_px, area_physical, frac_total, bounding box
(bbox_xmin, bbox_ymin, bbox_xmax, bbox_ymax), and centroid
(centroid_x, centroid_y). A 0-row tibble when the mask is empty.
Other masks:
sg_roi_mask(),
sg_roi_mask_boundary(),
sg_roi_mask_derive(),
sg_roi_mask_legend(),
sg_roi_mask_preview(),
sg_roi_mask_stack()
lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue")) proj <- sg_roi_project(sg_roi_frame(c(20, 20)), lyr) sg_roi_mask_stats(sg_roi_mask(proj, "labelled"))lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue")) proj <- sg_roi_project(sg_roi_frame(c(20, 20)), lyr) sg_roi_mask_stats(sg_roi_mask(proj, "labelled"))
Test whether two ROIs intersect
sg_roi_overlaps(roi1, roi2, call = rlang::caller_env())sg_roi_overlaps(roi1, roi2, call = rlang::caller_env())
roi1, roi2
|
sg_roi objects. |
call |
The calling environment, for error reporting. |
A logical scalar.
Other geometry:
sg_roi_buffer(),
sg_roi_check_containment(),
sg_roi_check_geometry(),
sg_roi_clamp(),
sg_roi_contains(),
sg_roi_distance(),
sg_roi_fix_geometry(),
sg_roi_flip_y(),
sg_roi_rescale(),
sg_roi_ring(),
sg_roi_rois_overlap(),
sg_roi_setops,
sg_roi_simplify(),
sg_roi_snap(),
sg_roi_transform()
a <- sg_roi_rect(0, 0, 4, 4, label = "a") sg_roi_overlaps(a, sg_roi_rect(2, 2, 6, 6, label = "b")) sg_roi_overlaps(a, sg_roi_rect(10, 0, 14, 4, label = "c"))a <- sg_roi_rect(0, 0, 4, 4, label = "a") sg_roi_overlaps(a, sg_roi_rect(2, 2, 6, 6, label = "b")) sg_roi_overlaps(a, sg_roi_rect(10, 0, 14, 4, label = "c"))
Create a point ROI
sg_roi_point(x, y, label, level = 0L, ..., call = rlang::caller_env())sg_roi_point(x, y, label, level = 0L, ..., call = rlang::caller_env())
x, y
|
Numeric coordinates of the point, in image pixels. |
label |
Single string class label. |
level |
Integer pyramid level the coordinates refer to. Default |
... |
Additional named attributes stored on the ROI. The reserved names
|
call |
The calling environment, for error reporting. |
An sg_roi with POINT geometry.
sg_roi_rect(), sg_roi_polygon()
Other rois:
sg_roi_area(),
sg_roi_bbox(),
sg_roi_centroid(),
sg_roi_circle(),
sg_roi_ellipse(),
sg_roi_freehand(),
sg_roi_from_geojson(),
sg_roi_from_sf(),
sg_roi_polygon(),
sg_roi_rect()
r <- sg_roi_point(10, 20, label = "cell") sg_roi_centroid(r)r <- sg_roi_point(10, 20, label = "cell") sg_roi_centroid(r)
Create a polygon ROI
sg_roi_polygon( coords, label, level = 0L, hole = NULL, ..., call = rlang::caller_env() )sg_roi_polygon( coords, label, level = 0L, hole = NULL, ..., call = rlang::caller_env() )
coords |
Either a two-column numeric matrix of exterior-ring vertices, or a list of such matrices where the first is the exterior ring and any others are holes. Rings are closed automatically. |
label |
Single string class label. |
level |
Integer pyramid level the coordinates refer to. Default |
hole |
Optional list of two-column matrices giving additional holes,
combined with any holes supplied via |
... |
Additional named attributes stored on the ROI. The reserved names
|
call |
The calling environment, for error reporting. |
An sg_roi with POLYGON geometry.
Other rois:
sg_roi_area(),
sg_roi_bbox(),
sg_roi_centroid(),
sg_roi_circle(),
sg_roi_ellipse(),
sg_roi_freehand(),
sg_roi_from_geojson(),
sg_roi_from_sf(),
sg_roi_point(),
sg_roi_rect()
sq <- matrix(c(0, 0, 10, 0, 10, 10, 0, 10), ncol = 2, byrow = TRUE) r <- sg_roi_polygon(sq, label = "region")sq <- matrix(c(0, 0, 10, 0, 10, 10, 0, 10), ncol = 2, byrow = TRUE) r <- sg_roi_polygon(sq, label = "region")
Create an annotation project
sg_roi_project(image, layers = list(), ..., call = rlang::caller_env())sg_roi_project(image, layers = list(), ..., call = rlang::caller_env())
image |
An sg_roi_frame the annotations refer to. |
layers |
An sg_roi_layer, a list of them, or an empty list (default). |
... |
Additional named project metadata (e.g. |
call |
The calling environment, for error reporting. |
An sg_roi_project bundling the image, layers, metadata, and
provenance (creation time, segmantR version, R version, author, and an
edit log).
sg_roi_add_layer(), sg_roi_add_roi(), sg_roi_rois(), sg_roi_mask()
Other projects:
sg_roi_add_layer(),
sg_roi_add_roi(),
sg_roi_layers(),
sg_roi_remove_layer(),
sg_roi_remove_roi(),
sg_roi_rois(),
sg_roi_summary(),
sg_roi_validate()
sg_roi_project(sg_roi_frame(c(100, 100)), sg_roi_layer("tissue"))sg_roi_project(sg_roi_frame(c(100, 100)), sg_roi_layer("tissue"))
Read ROIs from a GeoJSON file
sg_roi_read_geojson( path, layer_name = NULL, level = 0L, flip_y = FALSE, height = NULL, call = rlang::caller_env() )sg_roi_read_geojson( path, layer_name = NULL, level = 0L, flip_y = FALSE, height = NULL, call = rlang::caller_env() )
path |
Path to a GeoJSON file. |
layer_name |
Layer name for the imported ROIs; taken from the features'
|
level |
Integer level to record when a feature has no |
flip_y |
Logical; invert the y-axis on read. Default |
height |
Image height in pixels, required when |
call |
The calling environment, for error reporting. |
A named list of sg_roi_layer objects (one per distinct layer
property), or a single sg_roi_layer when layer_name is supplied.
Other io:
sg_roi_from_geojson(),
sg_roi_read_qupath(),
sg_roi_write_geojson(),
sg_roi_write_qupath()
lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue")) p <- tempfile(fileext = ".geojson") sg_roi_write_geojson(sg_roi_project(sg_roi_frame(c(20, 20)), lyr), p) layers <- sg_roi_read_geojson(p) sg_roi_layer_rois(layers$tissue)[, c("label", "area_px")]lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue")) p <- tempfile(fileext = ".geojson") sg_roi_write_geojson(sg_roi_project(sg_roi_frame(c(20, 20)), lyr), p) layers <- sg_roi_read_geojson(p) sg_roi_layer_rois(layers$tissue)[, c("label", "area_px")]
Reads QuPath 0.4+ exports (a FeatureCollection or a bare feature array) and
the legacy annotatR 0.1 dialect. classification.name (or the joined
names of a derived class, e.g. "Tumor: Positive") becomes the ROI label,
the classification colour the layer style colour, and features without a
classification are labelled "unclassified". Everything else QuPath carries
is kept, never invented, under each ROI's attributes$qupath: the object
id and type, name, measurements (with explicit value_state), the image
plane (zero-based c, z, t; c = NA for all channels), metadata, a
nucleus geometry, and roi_native = "ellipse" with
geometry_fidelity = "approximated" for polygonised ellipses. An segmantR id
stored in metadata.annotatr_roi_id is restored as the ROI id.
sg_roi_read_qupath( path, layer_name = "qupath", level = 0L, call = rlang::caller_env() )sg_roi_read_qupath( path, layer_name = "qupath", level = 0L, call = rlang::caller_env() )
path |
Path to a QuPath GeoJSON file. |
layer_name |
Layer name for the imported ROIs. Default |
level |
Integer level to record on the ROIs. Default |
call |
The calling environment, for error reporting. |
An sg_roi_layer.
Other io:
sg_roi_from_geojson(),
sg_roi_read_geojson(),
sg_roi_write_geojson(),
sg_roi_write_qupath()
lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue")) p <- tempfile(fileext = ".geojson") sg_roi_write_qupath(sg_roi_project(sg_roi_frame(c(20, 20)), lyr), p) sg_roi_layer_n(sg_roi_read_qupath(p))lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue")) p <- tempfile(fileext = ".geojson") sg_roi_write_qupath(sg_roi_project(sg_roi_frame(c(20, 20)), lyr), p) sg_roi_layer_n(sg_roi_read_qupath(p))
Create a rectangular ROI
sg_roi_rect( xmin, ymin, xmax, ymax, label, level = 0L, ..., call = rlang::caller_env() )sg_roi_rect( xmin, ymin, xmax, ymax, label, level = 0L, ..., call = rlang::caller_env() )
xmin, ymin, xmax, ymax
|
Numeric bounds in image pixels. |
label |
Single string class label. |
level |
Integer pyramid level the coordinates refer to. Default |
... |
Additional named attributes stored on the ROI. The reserved names
|
call |
The calling environment, for error reporting. |
An sg_roi with POLYGON geometry (an axis-aligned rectangle).
Other rois:
sg_roi_area(),
sg_roi_bbox(),
sg_roi_centroid(),
sg_roi_circle(),
sg_roi_ellipse(),
sg_roi_freehand(),
sg_roi_from_geojson(),
sg_roi_from_sf(),
sg_roi_point(),
sg_roi_polygon()
r <- sg_roi_rect(0, 0, 10, 5, label = "tissue") sg_roi_bbox(r)r <- sg_roi_rect(0, 0, 10, 5, label = "tissue") sg_roi_bbox(r)
Remove a layer from a project
sg_roi_remove_layer(project, name, call = rlang::caller_env())sg_roi_remove_layer(project, name, call = rlang::caller_env())
project |
An sg_roi_project. |
name |
Single string layer name. |
call |
The calling environment, for error reporting. |
A new sg_roi_project without the named layer. The input is unchanged.
Other projects:
sg_roi_add_layer(),
sg_roi_add_roi(),
sg_roi_layers(),
sg_roi_project(),
sg_roi_remove_roi(),
sg_roi_rois(),
sg_roi_summary(),
sg_roi_validate()
proj <- sg_roi_project(sg_roi_frame(c(20, 20)), list(sg_roi_layer("tumour"), sg_roi_layer("stroma"))) names(sg_roi_remove_layer(proj, "stroma")$layers)proj <- sg_roi_project(sg_roi_frame(c(20, 20)), list(sg_roi_layer("tumour"), sg_roi_layer("stroma"))) names(sg_roi_remove_layer(proj, "stroma")$layers)
Remove an ROI from a project
sg_roi_remove_roi(project, id, call = rlang::caller_env())sg_roi_remove_roi(project, id, call = rlang::caller_env())
project |
An sg_roi_project. |
id |
Single string ROI identifier. |
call |
The calling environment, for error reporting. |
A new sg_roi_project without the identified ROI. Warns and returns the project unchanged if the identifier is not found.
Other projects:
sg_roi_add_layer(),
sg_roi_add_roi(),
sg_roi_layers(),
sg_roi_project(),
sg_roi_remove_layer(),
sg_roi_rois(),
sg_roi_summary(),
sg_roi_validate()
lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue", id = "r1")) proj <- sg_roi_project(sg_roi_frame(c(20, 20)), lyr) nrow(sg_roi_rois(sg_roi_remove_roi(proj, "r1")))lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue", id = "r1")) proj <- sg_roi_project(sg_roi_frame(c(20, 20)), lyr) nrow(sg_roi_rois(sg_roi_remove_roi(proj, "r1")))
Transform an ROI's coordinates from one pyramid level to another, assuming a
power-of-two pyramid. For an exact transform against a real image pyramid
(which need not be power-of-two), use sg_roi_transform() with the
sg_roi_frame.
sg_roi_rescale(roi, from_level, to_level, call = rlang::caller_env())sg_roi_rescale(roi, from_level, to_level, call = rlang::caller_env())
roi |
An sg_roi. |
from_level, to_level
|
Integer source and target pyramid levels. |
call |
The calling environment, for error reporting. |
An sg_roi with coordinates at to_level and its level field
set to to_level. The transform is exactly invertible.
sg_roi_transform()
Other geometry:
sg_roi_buffer(),
sg_roi_check_containment(),
sg_roi_check_geometry(),
sg_roi_clamp(),
sg_roi_contains(),
sg_roi_distance(),
sg_roi_fix_geometry(),
sg_roi_flip_y(),
sg_roi_overlaps(),
sg_roi_ring(),
sg_roi_rois_overlap(),
sg_roi_setops,
sg_roi_simplify(),
sg_roi_snap(),
sg_roi_transform()
r <- sg_roi_rect(0, 0, 100, 100, label = "a") r2 <- sg_roi_rescale(r, from_level = 0, to_level = 2) identical( sf::st_coordinates(sf::st_geometry(r)), sf::st_coordinates(sf::st_geometry(sg_roi_rescale(r2, 2, 0))) )r <- sg_roi_rect(0, 0, 100, 100, label = "a") r2 <- sg_roi_rescale(r, from_level = 0, to_level = 2) identical( sf::st_coordinates(sf::st_geometry(r)), sf::st_coordinates(sf::st_geometry(sg_roi_rescale(r2, 2, 0))) )
Build a band straddling an ROI's boundary – the natural shape for a
"penumbra" region along an injury or wound margin. The ring extends outer
units outside the boundary and inner units inside it, formed as the set
difference of the outward and inward buffers.
sg_roi_ring( roi, outer, inner = 0, label = roi$label, call = rlang::caller_env() )sg_roi_ring( roi, outer, inner = 0, label = roi$label, call = rlang::caller_env() )
roi |
An sg_roi. |
outer |
Non-negative outward width (dilation) of the ring. |
inner |
Non-negative inward width (erosion) of the ring. Default |
label |
Label for the derived ring ROI. Default the source ROI's label. |
call |
The calling environment, for error reporting. |
A derived sg_roi (an annulus) with source = "derived".
sg_roi_buffer(), sg_roi_difference()
Other geometry:
sg_roi_buffer(),
sg_roi_check_containment(),
sg_roi_check_geometry(),
sg_roi_clamp(),
sg_roi_contains(),
sg_roi_distance(),
sg_roi_fix_geometry(),
sg_roi_flip_y(),
sg_roi_overlaps(),
sg_roi_rescale(),
sg_roi_rois_overlap(),
sg_roi_setops,
sg_roi_simplify(),
sg_roi_snap(),
sg_roi_transform()
inj <- sg_roi_rect(10, 10, 20, 20, label = "injury") sg_roi_ring(inj, outer = 3, label = "penumbra")inj <- sg_roi_rect(10, 10, 20, 20, label = "injury") sg_roi_ring(inj, outer = 3, label = "penumbra")
Return a tidy table of ROIs, optionally filtered by layer and/or label.
sg_roi_rois(project, layer = NULL, label = NULL, call = rlang::caller_env())sg_roi_rois(project, layer = NULL, label = NULL, call = rlang::caller_env())
project |
An sg_roi_project. |
layer |
Optional single layer name to filter to. |
label |
Optional character vector of labels to filter to. |
call |
The calling environment, for error reporting. |
Coordinates in the geometry column, together with area_px and the
centroid, are expressed at pyramid level 0; the level column records the
level at which each ROI was originally defined.
A tibble::tibble with one row per ROI and, in this exact order, the columns:
roi_idUnique identifier (character).
layerLayer name (character).
labelClass label (character).
geom_typeGeometry type, e.g. "POLYGON" (character).
levelReference pyramid level (integer).
area_pxArea in level-0 pixels (double); NA for points/lines.
centroid_x,centroid_y
Centroid at level 0 (double).
n_verticesVertex count (integer).
created,modified
Timestamps (POSIXct).
authorAuthor (character).
sourceProvenance source (character).
geometryThe sf geometry column (sfc), at level 0.
Returns a 0-row tibble with these columns if no ROIs match.
sg_roi_layers(), sg_roi_mask()
Other projects:
sg_roi_add_layer(),
sg_roi_add_roi(),
sg_roi_layers(),
sg_roi_project(),
sg_roi_remove_layer(),
sg_roi_remove_roi(),
sg_roi_summary(),
sg_roi_validate()
lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue")) proj <- sg_roi_project(sg_roi_frame(c(20, 20)), lyr) sg_roi_rois(proj)lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue")) proj <- sg_roi_project(sg_roi_frame(c(20, 20)), lyr) sg_roi_rois(proj)
Pairwise ROI overlaps within a layer
sg_roi_rois_overlap(layer, call = rlang::caller_env())sg_roi_rois_overlap(layer, call = rlang::caller_env())
layer |
An sg_roi_layer. |
call |
The calling environment, for error reporting. |
A tibble::tibble with columns id_a, id_b (character),
overlap_px (double, level-0 pixels), and jaccard (double). A 0-row
tibble with these columns when no ROIs overlap.
Other geometry:
sg_roi_buffer(),
sg_roi_check_containment(),
sg_roi_check_geometry(),
sg_roi_clamp(),
sg_roi_contains(),
sg_roi_distance(),
sg_roi_fix_geometry(),
sg_roi_flip_y(),
sg_roi_overlaps(),
sg_roi_rescale(),
sg_roi_ring(),
sg_roi_setops,
sg_roi_simplify(),
sg_roi_snap(),
sg_roi_transform()
lyr <- sg_roi_layer_add(sg_roi_layer("cells"), sg_roi_rect(0, 0, 4, 4, label = "cell")) lyr <- sg_roi_layer_add(lyr, sg_roi_rect(2, 2, 6, 6, label = "cell")) sg_roi_rois_overlap(lyr)lyr <- sg_roi_layer_add(sg_roi_layer("cells"), sg_roi_rect(0, 0, 4, 4, label = "cell")) lyr <- sg_roi_layer_add(lyr, sg_roi_rect(2, 2, 6, 6, label = "cell")) sg_roi_rois_overlap(lyr)
Combine ROIs geometrically. Each accepts several sg_roi via ..., or a
single sg_roi_layer. Multi-part results are returned as one ROI with
MULTIPOLYGON geometry (the return type is always a single sg_roi).
sg_roi_union(..., call = rlang::caller_env()) sg_roi_intersect(..., call = rlang::caller_env()) sg_roi_difference(..., call = rlang::caller_env()) sg_roi_symdiff(..., call = rlang::caller_env())sg_roi_union(..., call = rlang::caller_env()) sg_roi_intersect(..., call = rlang::caller_env()) sg_roi_difference(..., call = rlang::caller_env()) sg_roi_symdiff(..., call = rlang::caller_env())
... |
Two or more sg_roi, or a single sg_roi_layer. |
call |
The calling environment, for error reporting. |
A single sg_roi with source = "derived".
Other geometry:
sg_roi_buffer(),
sg_roi_check_containment(),
sg_roi_check_geometry(),
sg_roi_clamp(),
sg_roi_contains(),
sg_roi_distance(),
sg_roi_fix_geometry(),
sg_roi_flip_y(),
sg_roi_overlaps(),
sg_roi_rescale(),
sg_roi_ring(),
sg_roi_rois_overlap(),
sg_roi_simplify(),
sg_roi_snap(),
sg_roi_transform()
a <- sg_roi_rect(0, 0, 6, 6, label = "x") b <- sg_roi_rect(4, 4, 10, 10, label = "x") sg_roi_area(sg_roi_intersect(a, b))a <- sg_roi_rect(0, 0, 6, 6, label = "x") b <- sg_roi_rect(4, 4, 10, 10, label = "x") sg_roi_area(sg_roi_intersect(a, b))
Simplify an ROI
sg_roi_simplify(roi, tolerance, call = rlang::caller_env())sg_roi_simplify(roi, tolerance, call = rlang::caller_env())
roi |
An sg_roi. |
tolerance |
Non-negative Douglas-Peucker tolerance ( |
call |
The calling environment, for error reporting. |
An sg_roi with simplified geometry.
Other geometry:
sg_roi_buffer(),
sg_roi_check_containment(),
sg_roi_check_geometry(),
sg_roi_clamp(),
sg_roi_contains(),
sg_roi_distance(),
sg_roi_fix_geometry(),
sg_roi_flip_y(),
sg_roi_overlaps(),
sg_roi_rescale(),
sg_roi_ring(),
sg_roi_rois_overlap(),
sg_roi_setops,
sg_roi_snap(),
sg_roi_transform()
sg_roi_simplify(sg_roi_circle(50, 50, 10, n_seg = 128, label = "a"), 1)sg_roi_simplify(sg_roi_circle(50, 50, 10, n_seg = 128, label = "a"), 1)
Snap ROI vertices to a grid
sg_roi_snap(roi, grid = 1, call = rlang::caller_env())sg_roi_snap(roi, grid = 1, call = rlang::caller_env())
roi |
An sg_roi. |
grid |
Positive numeric grid spacing in pixels. Default |
call |
The calling environment, for error reporting. |
An sg_roi with vertices rounded to the nearest grid multiple.
Other geometry:
sg_roi_buffer(),
sg_roi_check_containment(),
sg_roi_check_geometry(),
sg_roi_clamp(),
sg_roi_contains(),
sg_roi_distance(),
sg_roi_fix_geometry(),
sg_roi_flip_y(),
sg_roi_overlaps(),
sg_roi_rescale(),
sg_roi_ring(),
sg_roi_rois_overlap(),
sg_roi_setops,
sg_roi_simplify(),
sg_roi_transform()
sg_roi_snap(sg_roi_point(3.4, 5.6, label = "a"), grid = 1)sg_roi_snap(sg_roi_point(3.4, 5.6, label = "a"), grid = 1)
Construct a style specification for an sg_roi_layer.
sg_roi_style( colour = NULL, fill_alpha = 0.3, stroke_width = 2, visible = TRUE, locked = FALSE, z = 1L, call = rlang::caller_env() )sg_roi_style( colour = NULL, fill_alpha = 0.3, stroke_width = 2, visible = TRUE, locked = FALSE, z = 1L, call = rlang::caller_env() )
colour |
Either |
fill_alpha |
Fill opacity in |
stroke_width |
Stroke width in pixels. Default |
visible |
Logical; whether the layer is drawn. Default |
locked |
Logical; whether the layer is protected from edits. Default
|
z |
Integer draw order (higher is drawn later, on top). Affects mask
overlap resolution. Default |
call |
The calling environment, for error reporting. |
A named list of class annot_style.
Other layers:
sg_roi_layer(),
sg_roi_layer_add(),
sg_roi_layer_n(),
sg_roi_layer_remove(),
sg_roi_layer_rois()
sg_roi_style(fill_alpha = 0.5, z = 2)sg_roi_style(fill_alpha = 0.5, z = 2)
Summarise a project
sg_roi_summary(project, call = rlang::caller_env())sg_roi_summary(project, call = rlang::caller_env())
project |
An sg_roi_project. |
call |
The calling environment, for error reporting. |
An sg_roi_summary object: a list with n_layers, n_rois,
per-label ROI counts, and total area per label.
Other projects:
sg_roi_add_layer(),
sg_roi_add_roi(),
sg_roi_layers(),
sg_roi_project(),
sg_roi_remove_layer(),
sg_roi_remove_roi(),
sg_roi_rois(),
sg_roi_validate()
lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue")) proj <- sg_roi_project(sg_roi_frame(c(20, 20)), lyr) sg_roi_summary(proj)lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue")) proj <- sg_roi_project(sg_roi_frame(c(20, 20)), lyr) sg_roi_summary(proj)
Unlike sg_roi_rescale() (which assumes a power-of-two pyramid), this uses
the actual level dimensions of an sg_roi_frame, so it is exact for pyramids
with any downsampling ratio.
sg_roi_transform(roi, from_level, to_level, img, call = rlang::caller_env())sg_roi_transform(roi, from_level, to_level, img, call = rlang::caller_env())
roi |
An sg_roi. |
from_level, to_level
|
Integer source and target pyramid levels. |
img |
The sg_roi_frame whose pyramid defines the level dimensions. |
call |
The calling environment, for error reporting. |
An sg_roi with coordinates at to_level. Exactly invertible.
Other geometry:
sg_roi_buffer(),
sg_roi_check_containment(),
sg_roi_check_geometry(),
sg_roi_clamp(),
sg_roi_contains(),
sg_roi_distance(),
sg_roi_fix_geometry(),
sg_roi_flip_y(),
sg_roi_overlaps(),
sg_roi_rescale(),
sg_roi_ring(),
sg_roi_rois_overlap(),
sg_roi_setops,
sg_roi_simplify(),
sg_roi_snap()
img <- sg_roi_frame(c(100, 100), list(c(100, 100), c(50, 50), c(25, 25))) r <- sg_roi_rect(0, 0, 100, 100, label = "a") sg_roi_transform(r, from_level = 0, to_level = 2, img = img)img <- sg_roi_frame(c(100, 100), list(c(100, 100), c(50, 50), c(25, 25))) r <- sg_roi_rect(0, 0, 100, 100, label = "a") sg_roi_transform(r, from_level = 0, to_level = 2, img = img)
Check that layer names are unique, ROI identifiers are unique across the project, and all geometries are valid.
sg_roi_validate(project, call = rlang::caller_env())sg_roi_validate(project, call = rlang::caller_env())
project |
An sg_roi_project. |
call |
The calling environment, for error reporting. |
The project, invisibly, if valid; otherwise an error describing the violated invariant.
sg_roi_check_geometry()
Other projects:
sg_roi_add_layer(),
sg_roi_add_roi(),
sg_roi_layers(),
sg_roi_project(),
sg_roi_remove_layer(),
sg_roi_remove_roi(),
sg_roi_rois(),
sg_roi_summary()
lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue")) proj <- sg_roi_project(sg_roi_frame(c(20, 20)), lyr) sg_roi_validate(proj)lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue")) proj <- sg_roi_project(sg_roi_frame(c(20, 20)), lyr) sg_roi_validate(proj)
Write a project's ROIs to GeoJSON
sg_roi_write_geojson( project, path, layer = NULL, level = 0L, flip_y = FALSE, overwrite = FALSE, call = rlang::caller_env() )sg_roi_write_geojson( project, path, layer = NULL, level = 0L, flip_y = FALSE, overwrite = FALSE, call = rlang::caller_env() )
project |
An sg_roi_project. |
path |
Output file path. |
layer |
Optional layer filter. |
level |
Integer pyramid level for the coordinates. Default |
flip_y |
Logical; invert the y-axis (for GIS-oriented consumers). Default
|
overwrite |
Logical; overwrite an existing file. Default |
call |
The calling environment, for error reporting. |
The output path, invisibly.
sg_roi_read_geojson(), sg_roi_write_qupath()
Other io:
sg_roi_from_geojson(),
sg_roi_read_geojson(),
sg_roi_read_qupath(),
sg_roi_write_qupath()
lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue")) proj <- sg_roi_project(sg_roi_frame(c(20, 20)), lyr) p <- tempfile(fileext = ".geojson") sg_roi_write_geojson(proj, p)lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue")) proj <- sg_roi_project(sg_roi_frame(c(20, 20)), lyr) p <- tempfile(fileext = ".geojson") sg_roi_write_geojson(proj, p)
The default dialect = "qupath" writes what QuPath 0.4 and later read
natively (verified with QuPath 0.7.0): objectType, classification with
an [r, g, b] colour, isLocked for locked ROIs, a deterministic UUID per
ROI as the feature id (QuPath replaces non-UUID ids), and segmantR's own ROI
id, layer, source and level in properties.metadata. dialect = "legacy"
writes the annotatR 0.1 form (object_type, signed colorRGB), which QuPath
still reads with a deprecation warning.
sg_roi_write_qupath( project, path, layer = NULL, level = 0L, overwrite = FALSE, dialect = c("qupath", "legacy"), call = rlang::caller_env() )sg_roi_write_qupath( project, path, layer = NULL, level = 0L, overwrite = FALSE, dialect = c("qupath", "legacy"), call = rlang::caller_env() )
project |
An sg_roi_project. |
path |
Output file path. |
layer |
Optional layer filter. |
level |
Integer pyramid level for the coordinates. Default |
overwrite |
Logical; overwrite an existing file. Default |
dialect |
|
call |
The calling environment, for error reporting. |
QuPath keeps one colour per classification name, so identical labels with different layer colours collapse to the first colour QuPath sees.
The output path, invisibly.
sg_roi_read_qupath(), sg_roi_write_geojson()
Other io:
sg_roi_from_geojson(),
sg_roi_read_geojson(),
sg_roi_read_qupath(),
sg_roi_write_geojson()
lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue")) proj <- sg_roi_project(sg_roi_frame(c(20, 20)), lyr) p <- tempfile(fileext = ".geojson") sg_roi_write_qupath(proj, p)lyr <- sg_roi_layer_add(sg_roi_layer("tissue"), sg_roi_rect(2, 2, 8, 8, label = "tissue")) proj <- sg_roi_project(sg_roi_frame(c(20, 20)), lyr) p <- tempfile(fileext = ".geojson") sg_roi_write_qupath(proj, p)
Starts the interactive Shiny application for cell segmentation,
annotation, and model training. The app is built by sg_app() from
package code; inst/shiny/segmantR/app.R is a thin wrapper for
shiny::runApp() on the installed directory.
sg_run_app(image = NULL, mask = NULL, port = NULL, launch.browser = TRUE)sg_run_app(image = NULL, mask = NULL, port = NULL, launch.browser = TRUE)
image |
An |
mask |
An |
port |
Integer port number, or |
launch.browser |
Logical, whether to open the app in a browser
(default |
For compatibility with code that starts the bundled app directory
directly, the pre-loaded objects are also stored in the option
segmantR.app_env while the app runs; the previous value is restored
when it stops. sg_app() itself does not use options.
NULL, invisibly.
if (interactive()) { sg_run_app(image = sg_example_image("fluorescence_nuclei")) }if (interactive()) { sg_run_app(image = sg_example_image("fluorescence_nuclei")) }
Segments cells using the Cellpose deep learning model via
reticulate. Requires a working Python installation with
cellpose installed. Use sg_setup_python() to configure the
environment.
sg_segment_cellpose( image, model = c("cyto3", "cyto2", "nuclei", "tissuenet", "livecell", "custom"), channels = list(cytoplasm = 0L, nucleus = 1L), diameter = NULL, flow_threshold = 0.4, cellprob_threshold = 0, custom_model_path = NULL, batch_size = 8L, tile = TRUE )sg_segment_cellpose( image, model = c("cyto3", "cyto2", "nuclei", "tissuenet", "livecell", "custom"), channels = list(cytoplasm = 0L, nucleus = 1L), diameter = NULL, flow_threshold = 0.4, cellprob_threshold = 0, custom_model_path = NULL, batch_size = 8L, tile = TRUE )
image |
An |
model |
Character string specifying the Cellpose model.
One of |
channels |
A named list with elements |
diameter |
Numeric or |
flow_threshold |
Numeric; flow error threshold for mask
filtering. Default is |
cellprob_threshold |
Numeric; cell probability threshold.
Default is |
custom_model_path |
Character string or |
batch_size |
Integer; number of images to process in
parallel on the GPU. Default is |
tile |
Logical; if |
An sg_mask object with labelled cell regions.
pixels <- array(runif(300), dim = c(10, 10, 3)) img <- new_sg_image(pixels, channels = c("R", "G", "B")) ## Not run: # Requires Python with Cellpose (see sg_setup_python()) mask <- sg_segment_cellpose(img, model = "cyto3") ## End(Not run)pixels <- array(runif(300), dim = c(10, 10, 3)) img <- new_sg_image(pixels, channels = c("R", "G", "B")) ## Not run: # Requires Python with Cellpose (see sg_setup_python()) mask <- sg_segment_cellpose(img, model = "cyto3") ## End(Not run)
Segments cells using the Mesmer deep learning model from the
DeepCell library via reticulate. Mesmer is designed for
multiplexed tissue imaging and can segment both nuclear and
whole-cell compartments.
sg_segment_mesmer( image, compartment = c("whole-cell", "nuclear", "both"), image_mpp = NULL )sg_segment_mesmer( image, compartment = c("whole-cell", "nuclear", "both"), image_mpp = NULL )
image |
An |
compartment |
Character string specifying which compartment
to segment. One of |
image_mpp |
Numeric scalar or |
Requires a working Python installation with deepcell installed.
An sg_mask object (for "whole-cell" or "nuclear")
or a named list of two sg_mask objects (for "both").
pixels <- array(runif(200), dim = c(10, 10, 2)) img <- new_sg_image(pixels, channels = c("nuclear", "membrane")) ## Not run: # Requires Python with DeepCell mask <- sg_segment_mesmer(img, compartment = "whole-cell") ## End(Not run)pixels <- array(runif(200), dim = c(10, 10, 2)) img <- new_sg_image(pixels, channels = c("nuclear", "membrane")) ## Not run: # Requires Python with DeepCell mask <- sg_segment_mesmer(img, compartment = "whole-cell") ## End(Not run)
Expands nuclear seed regions outward using Voronoi-style
propagation, optionally constrained by a membrane signal.
When available, EBImage::propagate() is used for higher
performance; otherwise a pure-R fallback is used.
sg_segment_propagate( image, nuclear_mask, membrane_image = NULL, lambda = 0.01, expand_max = 20L, engine = c("auto", "voronoi_r", "ebimage") )sg_segment_propagate( image, nuclear_mask, membrane_image = NULL, lambda = 0.01, expand_max = 20L, engine = c("auto", "voronoi_r", "ebimage") )
image |
An |
nuclear_mask |
An |
membrane_image |
An |
lambda |
Numeric weight for the membrane penalty in the cost
function. Higher values make propagation stop more readily at
membranes. Default is |
expand_max |
Integer; maximum number of propagation
iterations. Default is |
engine |
|
An sg_mask object with expanded cell labels.
set.seed(42) pixels <- matrix(runif(400), nrow = 20, ncol = 20) img <- new_sg_image(pixels) seeds <- matrix(0L, nrow = 20, ncol = 20) seeds[5, 5] <- 1L seeds[15, 15] <- 2L nuc_mask <- new_sg_mask(seeds) result <- sg_segment_propagate(img, nuclear_mask = nuc_mask) print(result)set.seed(42) pixels <- matrix(runif(400), nrow = 20, ncol = 20) img <- new_sg_image(pixels) seeds <- matrix(0L, nrow = 20, ncol = 20) seeds[5, 5] <- 1L seeds[15, 15] <- 2L nuc_mask <- new_sg_mask(seeds) result <- sg_segment_propagate(img, nuclear_mask = nuc_mask) print(result)
Segments cells (typically nuclei) using the StarDist deep learning
model via reticulate. Requires a working Python installation
with stardist and tensorflow installed. Use
sg_setup_python() to configure the environment.
sg_segment_stardist( image, model = c("2D_versatile_fluo", "2D_versatile_he", "2D_paper_dsb2018", "custom"), channel = 1L, prob_thresh = 0.5, nms_thresh = 0.4, scale = NULL, custom_model_path = NULL, n_tiles = NULL )sg_segment_stardist( image, model = c("2D_versatile_fluo", "2D_versatile_he", "2D_paper_dsb2018", "custom"), channel = 1L, prob_thresh = 0.5, nms_thresh = 0.4, scale = NULL, custom_model_path = NULL, n_tiles = NULL )
image |
An |
model |
Character string specifying the StarDist model.
One of |
channel |
Integer index of the image channel to segment.
Default is |
prob_thresh |
Numeric; object probability threshold.
Objects with probability below this value are discarded.
Default is |
nms_thresh |
Numeric; non-maximum suppression overlap
threshold. Overlapping detections above this threshold are
merged. Default is |
scale |
Numeric vector of length 1 or 2, or |
custom_model_path |
Character string or |
n_tiles |
Integer vector of length 2 or |
An sg_mask object with labelled cell regions.
pixels <- matrix(runif(400), nrow = 20, ncol = 20) img <- new_sg_image(pixels) ## Not run: # Requires Python with StarDist (see sg_setup_python()) mask <- sg_segment_stardist(img, model = "2D_versatile_fluo") ## End(Not run)pixels <- matrix(runif(400), nrow = 20, ncol = 20) img <- new_sg_image(pixels) ## Not run: # Requires Python with StarDist (see sg_setup_python()) mask <- sg_segment_stardist(img, model = "2D_versatile_fluo") ## End(Not run)
Segments cells in an sg_image by applying a global or local
intensity threshold, followed by morphological cleanup and
connected-component labelling with size filtering.
sg_segment_threshold( image, channel = 1L, method = c("otsu", "adaptive", "triangle"), block_size = 51L, offset = 0.05, morphology = list(open = 5L, fill_holes = TRUE), min_area = 50L, max_area = 5000L )sg_segment_threshold( image, channel = 1L, method = c("otsu", "adaptive", "triangle"), block_size = 51L, offset = 0.05, morphology = list(open = 5L, fill_holes = TRUE), min_area = 50L, max_area = 5000L )
image |
An |
channel |
Integer index of the image channel to threshold.
Default is |
method |
Character string specifying the thresholding method.
One of |
block_size |
Integer block size for adaptive thresholding.
Must be a positive odd integer. Only used when
|
offset |
Numeric offset subtracted from the local mean in
adaptive thresholding. Default is |
morphology |
A named list controlling morphological cleanup:
|
min_area |
Integer; minimum object area in pixels. Objects
smaller than this are removed. Default is |
max_area |
Integer; maximum object area in pixels. Objects
larger than this are removed. Default is |
Pixels that are NA, such as nodata values of a raster, count as
background.
An sg_mask object with labelled cell regions.
set.seed(42) pixels <- matrix(runif(400), nrow = 20, ncol = 20) img <- new_sg_image(pixels) mask <- sg_segment_threshold(img, method = "otsu") print(mask)set.seed(42) pixels <- matrix(runif(400), nrow = 20, ncol = 20) img <- new_sg_image(pixels) mask <- sg_segment_threshold(img, method = "otsu") print(mask)
Segments cells using a marker-controlled watershed algorithm.
Seeds (markers) are detected automatically via distance-transform
peaks or h-minima inside the Otsu foreground of channel. The
watershed then floods from these seeds, level by level along the
surface, so that object boundaries follow its ridges; pixels outside
the foreground are never flooded (only expand_pixels grows objects
beyond it).
sg_segment_watershed( image, channel = 1L, seed_method = c("h_minima", "distance", "markers"), h = 0.05, min_distance = 10L, expand_method = c("voronoi", "dilation"), expand_pixels = 3L, membrane_channel = NULL )sg_segment_watershed( image, channel = 1L, seed_method = c("h_minima", "distance", "markers"), h = 0.05, min_distance = 10L, expand_method = c("voronoi", "dilation"), expand_pixels = 3L, membrane_channel = NULL )
image |
An |
channel |
Integer index of the image channel used for
segmentation. Default is |
seed_method |
Character string specifying how seeds are
generated. One of |
h |
Numeric; height parameter for h-minima or distance
threshold fraction for seed detection. Default is |
min_distance |
Integer; minimum pixel distance between seeds.
Default is |
expand_method |
Character string specifying how seed regions
are expanded. One of |
expand_pixels |
Integer; number of pixels to expand beyond
the initial watershed regions. Default is |
membrane_channel |
Integer or |
An sg_mask object with labelled cell regions.
set.seed(42) pixels <- matrix(runif(400), nrow = 20, ncol = 20) img <- new_sg_image(pixels) mask <- sg_segment_watershed(img, seed_method = "distance", h = 0.3) print(mask)set.seed(42) pixels <- matrix(runif(400), nrow = 20, ncol = 20) img <- new_sg_image(pixels) mask <- sg_segment_watershed(img, seed_method = "distance", h = 0.3) print(mask)
Produces a single-channel sg_image from a channel index, a channel or
band name, a band wavelength, or one of the registered band operations
band_mean, ratio and normalized_difference. No free expressions are
accepted. The result records the source bands, wavelengths, operation,
value semantics and a transform digest so declarative protocol runs and
direct calls stay comparable.
sg_select_channel( image, channel = 1L, channel_name = NULL, wavelength_nm = NULL, wavelength_tolerance_nm = 5, band_operation = "none", band_a_nm = NULL, band_b_nm = NULL, band_min_nm = NULL, band_max_nm = NULL )sg_select_channel( image, channel = 1L, channel_name = NULL, wavelength_nm = NULL, wavelength_tolerance_nm = 5, band_operation = "none", band_a_nm = NULL, band_b_nm = NULL, band_min_nm = NULL, band_max_nm = NULL )
image |
An |
channel |
1-based channel index (used when no other selector is given). |
channel_name |
Channel or band name. |
wavelength_nm |
Band centre wavelength to select. |
wavelength_tolerance_nm |
Maximum distance to the nearest band centre. |
band_operation |
One of |
band_a_nm, band_b_nm
|
Wavelengths of bands a and b for |
band_min_nm, band_max_nm
|
Wavelength interval for |
Band operations require band wavelengths (see new_sg_image() bands
or sg_read_envi()) and refuse images whose value_semantics is
"unknown" for ratio and normalized_difference, because such ratios
are only interpretable for a declared value scale. Non-finite results
(division by zero) are replaced by the smallest finite result and counted
in provenance$band_selection$non_finite_replaced.
A single-channel sg_image.
cube <- array(runif(5 * 5 * 3), dim = c(5, 5, 3)) img <- new_sg_image(cube, channels = c("b450", "b550", "b650"), bands = data.frame(wavelength_nm = c(450, 550, 650)), value_semantics = "reflectance") sg_select_channel(img, wavelength_nm = 552)$channels nd <- sg_select_channel(img, band_operation = "normalized_difference", band_a_nm = 650, band_b_nm = 550) nd$provenance$band_selection$operationcube <- array(runif(5 * 5 * 3), dim = c(5, 5, 3)) img <- new_sg_image(cube, channels = c("b450", "b550", "b650"), bands = data.frame(wavelength_nm = c(450, 550, 650)), value_semantics = "reflectance") sg_select_channel(img, wavelength_nm = 552)$channels nd <- sg_select_channel(img, band_operation = "normalized_difference", band_a_nm = 650, band_b_nm = 550) nd$provenance$band_selection$operation
Creates and configures a Python virtual environment or conda environment with the requested deep learning segmentation backends (Cellpose, StarDist) installed.
sg_setup_python( envname = "segmantr", method = c("auto", "conda", "virtualenv"), backends = c("cellpose", "stardist"), gpu = TRUE )sg_setup_python( envname = "segmantr", method = c("auto", "conda", "virtualenv"), backends = c("cellpose", "stardist"), gpu = TRUE )
envname |
Character string naming the Python environment.
Default is |
method |
Character string specifying the environment type.
One of |
backends |
Character vector of backends to install.
Supported values are |
gpu |
Logical; if |
Invisibly returns TRUE on success.
segmantR never starts, downloads or installs Python by itself; without a
configured Python, recent versions of 'reticulate' would provision one
with 'uv'. The deep learning backends count as available only when
Python is already running in the session (for example after
reticulate::use_virtualenv("segmantr") and reticulate::py_config()),
when the environment variable RETICULATE_PYTHON or
RETICULATE_PYTHON_ENV names a Python, or when the option
segmantR.python is TRUE, which lets 'reticulate' find (or provision)
a Python on first use.
## Not run: sg_setup_python(backends = "cellpose") ## End(Not run)## Not run: sg_setup_python(backends = "cellpose") ## End(Not run)
Estimates fixed per-channel display ranges for a whole slide from a sample
of the image blocks (tiles) that contain cells: n_cells cell positions
are drawn, their storage blocks collected, n_tiles of these blocks drawn,
every step-th pixel in both directions taken, and sg_display_range()
applied per channel. Tiles follow the block grid of the file, so the
estimate reads few blocks even for very large scans.
sg_slide_display_ranges( path, channels, cells, x = "x", y = "y", pixel_size = 1, n_cells = 4000, n_tiles = 60, step = 3, probs = c(0.01, 0.997), min_span = 1, seed = 0, source = NULL )sg_slide_display_ranges( path, channels, cells, x = "x", y = "y", pixel_size = 1, n_cells = 4000, n_tiles = 60, step = 3, probs = c(0.01, 0.997), min_span = 1, seed = 0, source = NULL )
path |
Path to the image file. |
channels |
Channel names or numbers. |
cells |
Data frame of cell positions in physical units. |
x, y
|
Column names of the positions. |
pixel_size |
Physical size of one pixel. |
n_cells, n_tiles
|
Numbers of cells and tiles drawn. |
step |
Pixel subsampling step inside each tile. |
probs, min_span
|
Passed to |
seed |
Random seed for the draws (the global RNG state is restored). |
source |
Optional label stored in a |
A data frame with columns channel, lo, hi, tiles,
pixels and, with source, source.
f <- tempfile(fileext = ".tif") planes <- list(outer(1:64, 1:64, function(i, j) (i + j) %% 200), outer(1:64, 1:64, function(i, j) (i * j) %% 250)) invisible(tiff::writeTIFF(lapply(planes, function(p) p / 255), f, bits.per.sample = 8L)) cells <- data.frame(x = c(10, 30, 50, 60), y = c(12, 40, 55, 5)) sg_slide_display_ranges(f, c("ch1", "ch2"), cells, n_tiles = 2)f <- tempfile(fileext = ".tif") planes <- list(outer(1:64, 1:64, function(i, j) (i + j) %% 200), outer(1:64, 1:64, function(i, j) (i * j) %% 250)) invisible(tiff::writeTIFF(lapply(planes, function(p) p / 255), f, bits.per.sample = 8L)) cells <- data.frame(x = c(10, 30, 50, 60), y = c(12, 40, 55, 5)) sg_slide_display_ranges(f, c("ch1", "ch2"), cells, n_tiles = 2)
Applies colour deconvolution to an H&E-stained image to separate the haematoxylin and eosin channels.
sg_stain_deconvolve(image, method = c("macenko", "ruifrok"), stains = NULL)sg_stain_deconvolve(image, method = c("macenko", "ruifrok"), stains = NULL)
image |
An |
method |
Character string specifying the deconvolution method.
One of |
stains |
Optional 3x3 numeric matrix whose columns are the
stain vectors (optical density in R, G and B) for haematoxylin, eosin
and the residual channel, in that order. If |
A named list of sg_image objects, one per stain channel.
Typically hematoxylin and eosin, plus residual.
# Requires a colour image pixels <- array(runif(300), dim = c(10, 10, 3)) img <- new_sg_image(pixels, channels = c("R", "G", "B")) stains <- sg_stain_deconvolve(img) names(stains)# Requires a colour image pixels <- array(runif(300), dim = c(10, 10, 3)) img <- new_sg_image(pixels, channels = c("R", "G", "B")) stains <- sg_stain_deconvolve(img) names(stains)
Reports which StarDist options can be mapped for Python (reticulate) and
for the QuPath StarDist extension, for a detected or declared QuPath and
extension version. Detection reads installation files only (QuPath is
not started). Options are supported for extension versions at or above
the documented minimum, unknown for older versions and unavailable
when the extension is missing.
sg_stardist_capabilities( qupath_version = NULL, extension_version = NULL, check_python = FALSE )sg_stardist_capabilities( qupath_version = NULL, extension_version = NULL, check_python = FALSE )
qupath_version |
Optional QuPath version to evaluate (default: detected installation). |
extension_version |
Optional StarDist extension version (default: detected jar in the QuPath user directory). |
check_python |
Logical; probe the Python |
An sg_stardist_capabilities list with qupath, extension,
python, options (tibble) and parameters (tibble from
sg_stardist_parameter_map() for both targets).
caps <- sg_stardist_capabilities(qupath_version = "0.7.0", extension_version = "0.6.0") caps$options[, c("option", "status")]caps <- sg_stardist_capabilities(qupath_version = "0.7.0", extension_version = "0.6.0") caps$options[, c("option", "status")]
Hashes the model files and records representation, channels, pixel size,
normalisation, license and the runtimes that can load the representation
(.pb for QuPath/OpenCV, SavedModel for QuPath/TensorFlow, bioimage.io
for the extension's bioimage.io support, a Python model directory for
stardist).
sg_stardist_manifest( model, ..., name = NULL, channels = NULL, n_channels_in = NULL, pixel_size_um = NULL, normalization = NULL, license_id = NULL, source = NULL )sg_stardist_manifest( model, ..., name = NULL, channels = NULL, n_channels_in = NULL, pixel_size_um = NULL, normalization = NULL, license_id = NULL, source = NULL )
model |
Path to a |
... |
Reserved; must be empty. |
name |
Model name (default: file/directory name). |
channels |
Optional channel names the model expects. |
n_channels_in |
Optional number of input channels. |
pixel_size_um |
Optional pixel size the model was trained for. |
normalization |
Optional list (e.g. |
license_id |
Optional SPDX identifier. |
source |
Optional short provenance text (no URLs are fetched). |
An sg_stardist_manifest list conforming to
stardist-model.schema.json; digest follows the integrity inventory
rule and is what run.json and the Groovy template verify.
f <- tempfile(fileext = ".pb") writeBin(as.raw(1:10), f) sg_stardist_manifest(f, n_channels_in = 1L)$representationf <- tempfile(fileext = ".pb") writeBin(as.raw(1:10), f) sg_stardist_manifest(f, n_channels_in = 1L)$representation
Every declared parameter of the protocol appears in the result with the
target option, the target value and a status: mapped, approximated,
unsupported, not_applicable or runner (handled by segmantR before
delegation). Unknown parameters are errors; nothing is dropped silently.
sg_stardist_parameter_map( protocol = "stardist.2d.v1", target = c("python", "qupath"), ..., image = NULL )sg_stardist_parameter_map( protocol = "stardist.2d.v1", target = c("python", "qupath"), ..., image = NULL )
protocol |
Protocol id or |
target |
|
... |
Parameter overrides. |
image |
Optional |
A tibble with parameter, value, target, target_option,
target_value, status and note; attribute parameters holds the
resolved parameters.
sg_stardist_parameter_map("stardist.2d.v1", "qupath", prob_thresh = 0.6)sg_stardist_parameter_map("stardist.2d.v1", "qupath", prob_thresh = 0.6)
Trains (fine-tunes) a Cellpose segmentation model using corrected
image-mask pairs provided by the user. Requires a working Python
environment with Cellpose installed (see sg_setup_python()).
sg_train_cellpose( training_data, base_model = "cyto3", n_epochs = 100L, learning_rate = 0.1, save_path = NULL, verbose = TRUE )sg_train_cellpose( training_data, base_model = "cyto3", n_epochs = 100L, learning_rate = 0.1, save_path = NULL, verbose = TRUE )
training_data |
A list of training pairs. Each element must be a list
with |
base_model |
Character. Cellpose base model to fine-tune.
Default |
n_epochs |
Integer. Number of training epochs. Default |
learning_rate |
Numeric. Learning rate. Default |
save_path |
Character or |
verbose |
Logical. Print training progress? Default |
An sg_trained_model object.
## Not run: # Requires Python with Cellpose (see sg_setup_python()) pair <- list(image = sg_example_image("fluorescence_nuclei"), mask = sg_example_mask("fluorescence_nuclei")) trained <- sg_train_cellpose(list(pair), base_model = "cyto3", n_epochs = 10L) ## End(Not run)## Not run: # Requires Python with Cellpose (see sg_setup_python()) pair <- list(image = sg_example_image("fluorescence_nuclei"), mask = sg_example_mask("fluorescence_nuclei")) trained <- sg_train_cellpose(list(pair), base_model = "cyto3", n_epochs = 10L) ## End(Not run)
Trains a StarDist model on a prepared instance dataset. All data checks
run in R before Python is touched: the dataset must be an instance
dataset without split leakage, every training mask must be integer with
background 0 and one connected part per positive id, and the training
split must not be empty. Only then is the optional Python runtime
(stardist, tensorflow, csbdeep through reticulate) checked; when it
is missing an sg_capability_error with code CAPABILITY_UNAVAILABLE
and an installation hint is signalled.
sg_train_stardist( training_data, base_model = NULL, n_epochs = 100L, steps_per_epoch = 100L, learning_rate = 3e-04, n_rays = 32L, grid = c(2L, 2L), normalize = c(1, 99.8), save_path = NULL, name = "stardist_model", model_card = list(), seed = 1L, verbose = TRUE )sg_train_stardist( training_data, base_model = NULL, n_epochs = 100L, steps_per_epoch = 100L, learning_rate = 3e-04, n_rays = 32L, grid = c(2L, 2L), normalize = c(1, 99.8), save_path = NULL, name = "stardist_model", model_card = list(), seed = 1L, verbose = TRUE )
training_data |
An |
base_model |
Optional pretrained StarDist model name to fine-tune
(e.g. |
n_epochs, steps_per_epoch
|
Training length. |
learning_rate |
Adam learning rate. |
n_rays |
Number of radial directions. |
grid |
Subsampling grid (length 2). |
normalize |
Percentiles (length 2) for per-tile normalisation, recorded in the model card. |
save_path |
Directory for the trained model (default: a temporary directory). |
name |
Model name (directory name below |
model_card |
Model card fields (purpose, data_domain, limitations,
license, ...), see |
seed |
Integer seed passed to the Python random number generators. |
verbose |
Logical; print progress. |
An sg_trained_model with backend "stardist", the dataset
manifest, runtime description and evaluation metrics (validation split
thresholds when available).
img <- sg_example_image("fluorescence_nuclei") msk <- sg_cleanup_labels(sg_example_mask("fluorescence_nuclei"), disconnected = "split") ts <- sg_prepare_training_data( list(list(image = img, mask = msk, subject_id = "A"), list(image = img, mask = msk, subject_id = "B")), tile_size = 32L, split = c(train = 0.5, validation = 0.5, test = 0) ) # Requires Python stardist; otherwise a classified capability error: try(sg_train_stardist(ts, n_epochs = 1L))img <- sg_example_image("fluorescence_nuclei") msk <- sg_cleanup_labels(sg_example_mask("fluorescence_nuclei"), disconnected = "split") ts <- sg_prepare_training_data( list(list(image = img, mask = msk, subject_id = "A"), list(image = img, mask = msk, subject_id = "B")), tile_size = 32L, split = c(train = 0.5, validation = 0.5, test = 0) ) # Requires Python stardist; otherwise a classified capability error: try(sg_train_stardist(ts, n_epochs = 1L))
Validates a bundle or file on disk (all checks of
sg_import_interchange()) or an in-memory object: sg_manifest or list
(JSON Schema and version), sg_mask (label contract, legend
completeness, review consistency), sg_run (run schema) or
sg_protocol.
sg_validate_interchange(path_or_object, ...)sg_validate_interchange(path_or_object, ...)
path_or_object |
A path, |
... |
Passed to |
An sg_validation_report with ok, checks (tibble) and
error.
m <- sg_example_mask("fluorescence_nuclei") sg_validate_interchange(m)$ok bad <- m bad$labels[1, 1] <- -3L sg_validate_interchange(bad)$okm <- sg_example_mask("fluorescence_nuclei") sg_validate_interchange(m)$ok bad <- m bad$labels[1, 1] <- -3L sg_validate_interchange(bad)$ok
Checks schema conformance, split leakage (a group or source in more than one split), tile bounds, exclusion bookkeeping, instance/label contract of materialised mask tiles (integer dtype, background 0, unique connected instance ids, complete object lists), recorded tile digests, the dataset digest and, for directories, the integrity inventory.
sg_validate_training_manifest( x, mask_type = NULL, check_files = TRUE, error = TRUE )sg_validate_training_manifest( x, mask_type = NULL, check_files = TRUE, error = TRUE )
x |
An |
mask_type |
Optional mask type the consumer requires (e.g.
|
check_files |
Logical; read and check tile files of a directory. |
error |
Logical; signal the first failure instead of reporting it. |
An sg_validation_report with ok, checks and error.
img <- sg_example_image("fluorescence_nuclei") # The synthetic example mask contains overlapping ellipses; split them # into separate instances first. msk <- sg_cleanup_labels(sg_example_mask("fluorescence_nuclei"), disconnected = "split") man <- sg_dataset_manifest(list(list(image = img, mask = msk, subject_id = "A")), tile_size = 32L, min_objects = 0L, split = c(train = 1, validation = 0, test = 0)) sg_validate_training_manifest(man)$okimg <- sg_example_image("fluorescence_nuclei") # The synthetic example mask contains overlapping ellipses; split them # into separate instances first. msk <- sg_cleanup_labels(sg_example_mask("fluorescence_nuclei"), disconnected = "split") man <- sg_dataset_manifest(list(list(image = img, mask = msk, subject_id = "A")), tile_size = 32L, min_objects = 0L, split = c(train = 1, validation = 0, test = 0)) sg_validate_training_manifest(man)$ok
Shiny bindings for the cell canvas
sgCanvasOutput(outputId, width = "100%", height = "600px") renderSgCanvas(expr, env = parent.frame(), quoted = FALSE)sgCanvasOutput(outputId, width = "100%", height = "600px") renderSgCanvas(expr, env = parent.frame(), quoted = FALSE)
outputId |
Output id. |
width, height
|
Output dimensions. |
expr |
Expression returning |
env |
Evaluation environment. |
quoted |
Whether expr is quoted. |
A Shiny output element or render function.
if (interactive() && requireNamespace("htmlwidgets", quietly = TRUE) && requireNamespace("magick", quietly = TRUE)) { img <- new_sg_image(matrix(seq_len(72), 8, 9)) ui <- shiny::fluidPage(sgCanvasOutput("canvas")) server <- function(input, output, session) { output$canvas <- renderSgCanvas(sg_canvas(img)) } shiny::shinyApp(ui, server) }if (interactive() && requireNamespace("htmlwidgets", quietly = TRUE) && requireNamespace("magick", quietly = TRUE)) { img <- new_sg_image(matrix(seq_len(72), 8, 9)) ui <- shiny::fluidPage(sgCanvasOutput("canvas")) server <- function(input, output, session) { output$canvas <- renderSgCanvas(sg_canvas(img)) } shiny::shinyApp(ui, server) }