| Title: | Superpixel Segmentation with the Simple Non-Iterative Clustering Algorithm |
|---|---|
| Description: | Implements the Simple Non-Iterative Clustering algorithm for superpixel segmentation of multi-band images, as introduced by Achanta and Susstrunk (2017) <doi:10.1109/CVPR.2017.520>. Supports both standard image arrays and geospatial raster objects, with a design that can be extended to other spatial data frameworks. The algorithm groups adjacent pixels into compact, coherent regions based on spectral similarity and spatial proximity. A high-performance implementation supports images with arbitrary spectral bands. |
| Authors: | Rolf Simoes [aut, cre] (ORCID: <https://orcid.org/0000-0003-0953-4132>), Felipe Souza [aut] (ORCID: <https://orcid.org/0000-0002-5826-1700>), Felipe Carlos [aut] (ORCID: <https://orcid.org/0000-0002-3334-4315>), Gilberto Camara [aut, rth] (ORCID: <https://orcid.org/0000-0002-3681-487X>) |
| Maintainer: | Rolf Simoes <[email protected]> |
| License: | GPL (>= 2) |
| Version: | 0.6.1 |
| Built: | 2026-05-13 06:11:17 UTC |
| Source: | https://github.com/rolfsimoes/snic |
These helpers make it easy to express an existing set of seed coordinates in a different coordinate system. Seeds are accepted when they already contain the target column pair and otherwise are projected using the provided raster.
as_seeds_rc(seeds, x) as_seeds_xy(seeds, x) as_seeds_wgs84(seeds, x)as_seeds_rc(seeds, x) as_seeds_xy(seeds, x) as_seeds_wgs84(seeds, x)
seeds |
A data frame, |
x |
A |
A data frame with the target coordinate columns and any additional
columns that were present in seeds.
as_seeds_rc()Ensures seeds are expressed in raster row /
column indices (r, c).
as_seeds_xy()Ensures seeds use the raster CRS in map units
(x, y).
as_seeds_wgs84()Ensures seeds are in geographic
coordinates (lat, lon) in EPSG:4326.
Only rasters with a defined coordinate reference system (CRS) can be transformed to WGS84 coordinates. If the input raster 'x' lacks a CRS, attempting to convert to WGS84 will result in an error.
if (requireNamespace("terra", quietly = TRUE) && terra_is_working()) { # Load a test Sentinel-2 band s2_file <- system.file( "demo-geotiff/S2_20LMR_B04_20220630.tif", package = "snic" ) s2_rast <- terra::rast(s2_file) # Create some test coordinates in pixel space seeds_rc <- data.frame(r = c(10, 20, 30), c = c(15, 25, 35)) # Convert to map coordinates (x,y) seeds_xy <- as_seeds_xy(seeds_rc, s2_rast) # Convert to geographic coordinates (lat,lon) seeds_wgs84 <- as_seeds_wgs84(seeds_rc, s2_rast) }if (requireNamespace("terra", quietly = TRUE) && terra_is_working()) { # Load a test Sentinel-2 band s2_file <- system.file( "demo-geotiff/S2_20LMR_B04_20220630.tif", package = "snic" ) s2_rast <- terra::rast(s2_file) # Create some test coordinates in pixel space seeds_rc <- data.frame(r = c(10, 20, 30), c = c(15, 25, 35)) # Convert to map coordinates (x,y) seeds_xy <- as_seeds_xy(seeds_rc, s2_rast) # Convert to geographic coordinates (lat,lon) seeds_wgs84 <- as_seeds_wgs84(seeds_rc, s2_rast) }
Segment an image into superpixels using the SNIC algorithm. This function wraps a C++ implementation operating on any number of spectral bands and uses 4-neighbor (von Neumann) connectivity.
snic(x, seeds, compactness = 0.5, ...)snic(x, seeds, compactness = 0.5, ...)
x |
Image data. For the |
seeds |
Initial seed coordinates. The required format depends on the
spatial status of
Seeds define the starting cluster centers. They are usually generated with
|
compactness |
Non-negative numeric value controlling the balance between feature similarity and spatial proximity (default = 0.5). Larger values produce more spatially compact superpixels. |
... |
Currently unused; reserved for future extensions. |
The algorithm performs clustering in a joint space that includes the image's
spectral dimensions and two spatial coordinates. Each seed initializes a
region, and pixels are assigned based on the SNIC distance metric combining
spectral similarity and spatial distance, weighted by compactness.
An object of class snic bundling the segmentation result together
with per-cluster summaries produced by the SNIC algorithm. The segmentation
result can be accessed using snic_get_seg. The per-cluster
summaries can be accessed using snic_get_means and
snic_get_centroids.
snic_grid for seed generation,
snic_grid_manual for interactive placement,
snic_plot for visualizing results.
# Example 1: Geospatial raster if (requireNamespace("terra", quietly = TRUE) && terra_is_working()) { path <- system.file("demo-geotiff", package = "snic", mustWork = TRUE) files <- file.path( path, c( "S2_20LMR_B02_20220630.tif", "S2_20LMR_B04_20220630.tif", "S2_20LMR_B08_20220630.tif", "S2_20LMR_B12_20220630.tif" ) ) # Downsample for speed (optional) s2 <- terra::aggregate(terra::rast(files), fact = 8) # Generate a regular grid of seeds (lat/lon because CRS is present) seeds <- snic_grid( s2, type = "rectangular", spacing = 10L, padding = 18L ) # Run segmentation seg <- snic(s2, seeds, compactness = 0.25) # Visualize RGB composite with seeds and segment boundaries snic_plot( s2, r = 4, g = 3, b = 1, stretch = "lin", seeds = seeds, seg = seg ) } # Example 2: In-memory image (JPEG) + Lab transform # Uses an example image shipped with the package (no terra needed) if (requireNamespace("jpeg", quietly = TRUE)) { img_path <- system.file( "demo-jpeg/clownfish.jpeg", package = "snic", mustWork = TRUE ) rgb <- jpeg::readJPEG(img_path) # h x w x 3 in [0, 1] # Convert sRGB -> CIE Lab for perceptual clustering dims <- dim(rgb) dim(rgb) <- c(dims[1] * dims[2], dims[3]) lab <- grDevices::convertColor( rgb, from = "sRGB", to = "Lab", scale.in = 1, scale.out = 1 / 255 ) dim(lab) <- dims dim(rgb) <- dims # Seeds in pixel coordinates for array inputs seeds_rc <- snic_grid(lab, type = "hexagonal", spacing = 20L) # Segment in Lab space and plot L channel with boundaries seg <- snic(lab, seeds_rc, compactness = 0.1) snic_plot( rgb, r = 1L, g = 2L, b = 3L, seg = seg, seg_plot_args = list( border = "black" ) ) }# Example 1: Geospatial raster if (requireNamespace("terra", quietly = TRUE) && terra_is_working()) { path <- system.file("demo-geotiff", package = "snic", mustWork = TRUE) files <- file.path( path, c( "S2_20LMR_B02_20220630.tif", "S2_20LMR_B04_20220630.tif", "S2_20LMR_B08_20220630.tif", "S2_20LMR_B12_20220630.tif" ) ) # Downsample for speed (optional) s2 <- terra::aggregate(terra::rast(files), fact = 8) # Generate a regular grid of seeds (lat/lon because CRS is present) seeds <- snic_grid( s2, type = "rectangular", spacing = 10L, padding = 18L ) # Run segmentation seg <- snic(s2, seeds, compactness = 0.25) # Visualize RGB composite with seeds and segment boundaries snic_plot( s2, r = 4, g = 3, b = 1, stretch = "lin", seeds = seeds, seg = seg ) } # Example 2: In-memory image (JPEG) + Lab transform # Uses an example image shipped with the package (no terra needed) if (requireNamespace("jpeg", quietly = TRUE)) { img_path <- system.file( "demo-jpeg/clownfish.jpeg", package = "snic", mustWork = TRUE ) rgb <- jpeg::readJPEG(img_path) # h x w x 3 in [0, 1] # Convert sRGB -> CIE Lab for perceptual clustering dims <- dim(rgb) dim(rgb) <- c(dims[1] * dims[2], dims[3]) lab <- grDevices::convertColor( rgb, from = "sRGB", to = "Lab", scale.in = 1, scale.out = 1 / 255 ) dim(lab) <- dims dim(rgb) <- dims # Seeds in pixel coordinates for array inputs seeds_rc <- snic_grid(lab, type = "hexagonal", spacing = 20L) # Segment in Lab space and plot L channel with boundaries seg <- snic(lab, seeds_rc, compactness = 0.1) snic_plot( rgb, r = 1L, g = 2L, b = 3L, seg = seg, seg_plot_args = list( border = "black" ) ) }
Generate an animated GIF illustrating how SNIC segmentation evolves as seeds are progressively added. This function runs a sequence of SNIC segmentations using incremental subsets of the provided seeds and compiles the results into an animation.
snic_animation( x, seeds, file_path, max_frames = 100L, delay = 10, progress = getOption("snic.progress", FALSE), ..., snic_args = list(compactness = 0.5), device_args = list(res = 96, bg = "white") )snic_animation( x, seeds, file_path, max_frames = 100L, delay = 10, progress = getOption("snic.progress", FALSE), ..., snic_args = list(compactness = 0.5), device_args = list(res = 96, bg = "white") )
x |
A |
seeds |
A two-column object specifying seed coordinates. If |
file_path |
Path where the resulting GIF is saved. The file must not already exist and the parent directory must be writable. |
max_frames |
Maximum number of frames to render. If there are more
seeds than |
delay |
Per-frame delay in centiseconds (1/100 s). Passed to
|
progress |
Logical scalar; if |
... |
Additional arguments forwarded to |
snic_args |
Named list of extra arguments passed to |
device_args |
Named list of arguments passed to
|
For each iteration, the function adds one seed to the current set and
re-runs snic. The segmentation and seed locations are drawn
using snic_plot, saved as PNGs, and then combined into an
animated GIF using the magick package. This is intended for
exploratory and didactic use to illustrate the influence of seed placement
and parameters such as compactness.
Invisibly, the file path of the generated GIF.
snic, snic_plot,
snic_grid, snic_grid_manual.
if (requireNamespace("terra", quietly = TRUE) && terra_is_working() && requireNamespace("magick", quietly = TRUE)) { tif_dir <- system.file("demo-geotiff", package = "snic", mustWork = TRUE) files <- file.path( tif_dir, c( "S2_20LMR_B02_20220630.tif", "S2_20LMR_B04_20220630.tif", "S2_20LMR_B08_20220630.tif", "S2_20LMR_B12_20220630.tif" ) ) s2 <- terra::aggregate(terra::rast(files), fact = 8) set.seed(42) seeds <- snic_grid(s2, type = "random", spacing = 10L, padding = 0L) gif_file <- snic_animation( s2, seeds = seeds, file_path = tempfile("snic-demo", fileext = ".gif"), max_frames = 20L, snic_args = list(compactness = 0.1), r = 4, g = 3, b = 1, device_args = list(height = 192, width = 256) ) gif_file }if (requireNamespace("terra", quietly = TRUE) && terra_is_working() && requireNamespace("magick", quietly = TRUE)) { tif_dir <- system.file("demo-geotiff", package = "snic", mustWork = TRUE) files <- file.path( tif_dir, c( "S2_20LMR_B02_20220630.tif", "S2_20LMR_B04_20220630.tif", "S2_20LMR_B08_20220630.tif", "S2_20LMR_B12_20220630.tif" ) ) s2 <- terra::aggregate(terra::rast(files), fact = 8) set.seed(42) seeds <- snic_grid(s2, type = "random", spacing = 10L, padding = 0L) gif_file <- snic_animation( s2, seeds = seeds, file_path = tempfile("snic-demo", fileext = ".gif"), max_frames = 20L, snic_args = list(compactness = 0.1), r = 4, g = 3, b = 1, device_args = list(height = 192, width = 256) ) gif_file }
Objects returned by snic inherit from the snic
S3 class. They are lightweight containers bundling the segmentation
result together with per-cluster summaries produced by the SNIC
algorithm. Internally, a snic object is a named list with
components:
segThe segmentation map in the native type of the input
(either a 3D integer array with dimensions
(height, width, 1) or a single-layer
SpatRaster—matching the input
given to snic()). Values are superpixel labels (positive integers);
NA marks pixels that were not assigned.
meansNumeric matrix with one row per superpixel and one
column per input band (column names preserved when available), giving the
mean feature value of each cluster. May be NULL if the backend
cannot retain these summaries.
centroidsNumeric matrix with columns r and c
giving the cluster centers in pixel coordinates (0-based indices used by
the SNIC core). May be NULL when centroids are unavailable.
The list carries class "snic" to enable the accessors and print
methods below; the segmentation labels index the corresponding rows of
means and centroids.
snic_get_means(x) snic_get_centroids(x) snic_get_seg(x) ## S3 method for class 'snic' snic_get_means(x) ## S3 method for class 'snic' snic_get_centroids(x) ## S3 method for class 'snic' snic_get_seg(x) ## S3 method for class 'snic' print(x, ...)snic_get_means(x) snic_get_centroids(x) snic_get_seg(x) ## S3 method for class 'snic' snic_get_means(x) ## S3 method for class 'snic' snic_get_centroids(x) ## S3 method for class 'snic' snic_get_seg(x) ## S3 method for class 'snic' print(x, ...)
x |
A |
... |
Additional arguments passed to or from methods. Currently unused, but included for compatibility with S3 method dispatch. |
snic_get_means(): Numeric matrix of per-cluster band means,
or NULL when not available.
snic_get_centroids(): Numeric matrix with columns
r and c giving cluster centers in pixel coordinates
(0-based), or NULL when not available.
snic_get_seg(): Segmentation map in the native type of the
input (array or SpatRaster) with integer labels and
possible NA for unassigned pixels.
print.snic(): Invisibly returns x after printing a
human-readable summary.
snic_get_seg: Retrieve the segmentation result.
snic_get_means: Retrieve per-cluster feature means.
snic_get_centroids: Retrieve per-cluster centroids.
snic_animation: Animate the segmentation process.
print: Print a summary of the segmentation result.
plot: Visualize the segmentation result.
Generate seed locations on an image following one of four spatial
arrangements used in SNIC (Simple Non-Iterative Clustering) segmentation:
rectangular, diamond, hexagonal, or random. Works for both numeric arrays
and SpatRaster objects.
snic_grid( x, type = c("rectangular", "diamond", "hexagonal", "random"), spacing, padding = spacing/2, ... ) snic_count_seeds(x, spacing, padding = spacing/2)snic_grid( x, type = c("rectangular", "diamond", "hexagonal", "random"), spacing, padding = spacing/2, ... ) snic_count_seeds(x, spacing, padding = spacing/2)
x |
Image data. For arrays, this must be numeric with dimensions
|
type |
Character string indicating the spatial pattern to generate.
One of |
spacing |
Numeric or integer. Either one value (applied to both axes)
or two values |
padding |
Numeric or integer. Distance from image borders within which
no seeds are placed. May be of length 1 or 2. Defaults to
|
... |
Currently unused; reserved for future extensions. |
The spacing parameter controls seed density. Padding shifts the
seed grid inward so that seeds are not placed directly on image borders.
The spatial arrangements are:
rectangular: regular grid aligned with rows and columns.
diamond: alternating row offsets, forming a diamond layout.
hexagonal: alternating offsets approximating a hexagonal
tiling.
random: uniform random placement with similar expected
density.
The helper snic_count_seeds estimates how many seeds would be
generated for a rectangular lattice with the given spacing and padding,
without computing coordinates. For type = "diamond" or
"hexagonal", the actual number of seeds will be up to roughly
twice this estimate (minus boundary effects). For "random", the
estimate corresponds to the expected density.
If x has a coordinate reference system, the returned data frame
includes geographic coordinates (lat, lon) in EPSG:4326.
A data frame containing:
r, c when x has no CRS.
lat, lon when x has a CRS, expressed in
EPSG:4326.
snic_count_seeds for estimating seed counts.
# Example 1: Geospatial raster if (requireNamespace("terra", quietly = TRUE) && terra_is_working()) { # Load example multi-band image (Sentinel-2 subset) and downsample tiff_dir <- system.file("demo-geotiff", package = "snic", mustWork = TRUE ) files <- file.path(tiff_dir, c( "S2_20LMR_B02_20220630.tif", "S2_20LMR_B04_20220630.tif", "S2_20LMR_B08_20220630.tif", "S2_20LMR_B12_20220630.tif" )) s2 <- terra::aggregate(terra::rast(files), fact = 8) # Compare grid types visually using snic_plot for immediate feedback types <- c("rectangular", "diamond", "hexagonal", "random") op <- par(mfrow = c(2, 2), mar = c(2, 2, 2, 2)) for (tp in types) { seeds <- snic_grid(s2, type = tp, spacing = 12L, padding = 18L) snic_plot( s2, r = 4, g = 3, b = 1, stretch = "lin", seeds = seeds, main = paste("Grid:", tp) ) } par(mfrow = c(1, 1)) # Estimate seed counts for planning snic_count_seeds(s2, spacing = 12L, padding = 18L) par(op) } # Example 2: In-memory image (JPEG) if (requireNamespace("jpeg", quietly = TRUE)) { img_path <- system.file( "demo-jpeg/clownfish.jpeg", package = "snic", mustWork = TRUE ) rgb <- jpeg::readJPEG(img_path) # Compare grid types visually using snic_plot for immediate feedback types <- c("rectangular", "diamond", "hexagonal", "random") op <- par(mfrow = c(2, 2), mar = c(2, 2, 2, 2)) for (tp in types) { seeds <- snic_grid(rgb, type = tp, spacing = 12L, padding = 18L) snic_plot( rgb, r = 1, g = 2, b = 3, seeds = seeds, main = paste("Grid:", tp) ) } par(mfrow = c(1, 1)) par(op) }# Example 1: Geospatial raster if (requireNamespace("terra", quietly = TRUE) && terra_is_working()) { # Load example multi-band image (Sentinel-2 subset) and downsample tiff_dir <- system.file("demo-geotiff", package = "snic", mustWork = TRUE ) files <- file.path(tiff_dir, c( "S2_20LMR_B02_20220630.tif", "S2_20LMR_B04_20220630.tif", "S2_20LMR_B08_20220630.tif", "S2_20LMR_B12_20220630.tif" )) s2 <- terra::aggregate(terra::rast(files), fact = 8) # Compare grid types visually using snic_plot for immediate feedback types <- c("rectangular", "diamond", "hexagonal", "random") op <- par(mfrow = c(2, 2), mar = c(2, 2, 2, 2)) for (tp in types) { seeds <- snic_grid(s2, type = tp, spacing = 12L, padding = 18L) snic_plot( s2, r = 4, g = 3, b = 1, stretch = "lin", seeds = seeds, main = paste("Grid:", tp) ) } par(mfrow = c(1, 1)) # Estimate seed counts for planning snic_count_seeds(s2, spacing = 12L, padding = 18L) par(op) } # Example 2: In-memory image (JPEG) if (requireNamespace("jpeg", quietly = TRUE)) { img_path <- system.file( "demo-jpeg/clownfish.jpeg", package = "snic", mustWork = TRUE ) rgb <- jpeg::readJPEG(img_path) # Compare grid types visually using snic_plot for immediate feedback types <- c("rectangular", "diamond", "hexagonal", "random") op <- par(mfrow = c(2, 2), mar = c(2, 2, 2, 2)) for (tp in types) { seeds <- snic_grid(rgb, type = tp, spacing = 12L, padding = 18L) snic_plot( rgb, r = 1, g = 2, b = 3, seeds = seeds, main = paste("Grid:", tp) ) } par(mfrow = c(1, 1)) par(op) }
Collect seed points interactively by clicking on the image. Each left-click
adds a new seed; pressing ESC ends the session. After each click,
SNIC segmentation is recomputed and plotted for visual feedback. This is
intended for exploratory and fine-tuning workflows, where automatic seeding
may not be ideal.
snic_grid_manual( x, seeds = NULL, ..., snic_args = list(compactness = 0.5), snic_plot_args = list(stretch = "lin", seeds_plot_args = list(pch = 4, col = "#FFFF00", cex = 1), seg_plot_args = list(border = "#FFFF00", col = NA, lwd = 0.4)) )snic_grid_manual( x, seeds = NULL, ..., snic_args = list(compactness = 0.5), snic_plot_args = list(stretch = "lin", seeds_plot_args = list(pch = 4, col = "#FFFF00", cex = 1), seg_plot_args = list(border = "#FFFF00", col = NA, lwd = 0.4)) )
x |
A |
seeds |
Optional existing seed set to display and extend.
If pixel coordinates are supplied, they are internally converted. If
|
... |
Arguments forwarded to |
snic_args |
A list of arguments passed to |
snic_plot_args |
A list of display modifiers forwarded to
|
After each new seed is placed interactively, segmentation is recomputed to provide immediate feedback on how the seed placement affects clustering.
A two-column data frame of seed coordinates. If x lacks a CRS the
result is always pixel indices (r, c). When x has a CRS:
If seeds were supplied, their coordinate system is preserved
in the output.
Otherwise the result is expressed as (lat, lon) in
EPSG:4326.
The output can be passed directly to snic.
snic, snic_grid, snic_animation.
if (interactive() && requireNamespace("terra", quietly = TRUE) && terra_is_working()) { tiff_dir <- system.file("demo-geotiff", package = "snic", mustWork = TRUE ) files <- file.path( tiff_dir, c( "S2_20LMR_B02_20220630.tif", "S2_20LMR_B04_20220630.tif", "S2_20LMR_B08_20220630.tif", "S2_20LMR_B12_20220630.tif" ) ) s2 <- terra::aggregate(terra::rast(files), fact = 8) seeds <- snic_grid_manual( s2, snic_args = list(compactness = 0.1), snic_plot_args = list(r = 4, g = 3, b = 1) ) seg <- snic(s2, seeds, compactness = 0.1) snic_plot( s2, r = 4, g = 3, b = 1, stretch = "lin", seeds = seeds, seg = seg ) }if (interactive() && requireNamespace("terra", quietly = TRUE) && terra_is_working()) { tiff_dir <- system.file("demo-geotiff", package = "snic", mustWork = TRUE ) files <- file.path( tiff_dir, c( "S2_20LMR_B02_20220630.tif", "S2_20LMR_B04_20220630.tif", "S2_20LMR_B08_20220630.tif", "S2_20LMR_B12_20220630.tif" ) ) s2 <- terra::aggregate(terra::rast(files), fact = 8) seeds <- snic_grid_manual( s2, snic_args = list(compactness = 0.1), snic_plot_args = list(r = 4, g = 3, b = 1) ) seg <- snic(s2, seeds, compactness = 0.1) snic_plot( s2, r = 4, g = 3, b = 1, stretch = "lin", seeds = seeds, seg = seg ) }
Render image data processed by SNIC either from in-memory numeric arrays
or from terra::SpatRaster objects
provided by the terra package. The function supports plotting a
single band or a three-channel RGB composite, with optional overlays for
seed points and segmentation boundaries.
snic_plot( x, ..., band = 1L, r = NULL, g = NULL, b = NULL, col = getOption("snic.col", grDevices::hcl.colors(128L, "Spectral")), stretch = "lin", seeds = NULL, seeds_plot_args = getOption("snic.seeds_plot", list(pch = 20, col = "#00FFFF", cex = 1)), seg = NULL, seg_plot_args = getOption("snic.seg_plot", list(border = "#FFD700", col = NA, lwd = 0.6)) )snic_plot( x, ..., band = 1L, r = NULL, g = NULL, b = NULL, col = getOption("snic.col", grDevices::hcl.colors(128L, "Spectral")), stretch = "lin", seeds = NULL, seeds_plot_args = getOption("snic.seeds_plot", list(pch = 20, col = "#00FFFF", cex = 1)), seg = NULL, seg_plot_args = getOption("snic.seg_plot", list(border = "#FFD700", col = NA, lwd = 0.6)) )
x |
Image data. For the array method this must be a numeric array
with dimensions |
... |
Additional arguments forwarded to the underlying plotting
function. For arrays, these are passed to
|
band |
Integer index of the band to display when producing a single-band plot. Defaults to the first band. |
r, g, b
|
Integer indices (1-based) of the bands to use when composing an RGB plot. All three must be supplied to trigger RGB rendering and the image must contain at least three bands. |
col |
Color palette used for single-band plots. Ignored for RGB plots. |
stretch |
Character string indicating the contrast-stretching method.
Determines how band values are scaled to the
Non-numeric arrays or bands with only constant values are plotted as-is. |
seeds |
Optional object containing seed coordinates with
columns |
seeds_plot_args |
Optional named list with additional arguments passed
to |
seg |
For |
seg_plot_args |
Named list of arguments forwarded to
|
Invisibly, NULL.
if (requireNamespace("terra", quietly = TRUE) && terra_is_working()) { tiff_dir <- system.file("demo-geotiff", package = "snic", mustWork = TRUE ) files <- file.path( tiff_dir, c( "S2_20LMR_B02_20220630.tif", "S2_20LMR_B04_20220630.tif", "S2_20LMR_B08_20220630.tif", "S2_20LMR_B12_20220630.tif" ) ) # Load and optionally downsample for faster segmentation s2 <- terra::aggregate(terra::rast(files), fact = 8) # Visualize snic_plot(s2, r = 4, g = 3, b = 1, stretch = "lin") } # Simple array example using bundled JPEG if (requireNamespace("jpeg", quietly = TRUE)) { img_path <- system.file("demo-jpeg/clownfish.jpeg", package = "snic", mustWork = TRUE ) # Load rgb <- jpeg::readJPEG(img_path) # Visualize snic_plot(rgb, r = 1, g = 2, b = 3, stretch = "none") }if (requireNamespace("terra", quietly = TRUE) && terra_is_working()) { tiff_dir <- system.file("demo-geotiff", package = "snic", mustWork = TRUE ) files <- file.path( tiff_dir, c( "S2_20LMR_B02_20220630.tif", "S2_20LMR_B04_20220630.tif", "S2_20LMR_B08_20220630.tif", "S2_20LMR_B12_20220630.tif" ) ) # Load and optionally downsample for faster segmentation s2 <- terra::aggregate(terra::rast(files), fact = 8) # Visualize snic_plot(s2, r = 4, g = 3, b = 1, stretch = "lin") } # Simple array example using bundled JPEG if (requireNamespace("jpeg", quietly = TRUE)) { img_path <- system.file("demo-jpeg/clownfish.jpeg", package = "snic", mustWork = TRUE ) # Load rgb <- jpeg::readJPEG(img_path) # Visualize snic_plot(rgb, r = 1, g = 2, b = 3, stretch = "none") }
This helper attempts the same coordinate reprojection used elsewhere in
the package (via terra::project()). When the bundled PROJ /
GDAL data are missing, terra raises an error; here we catch
it and return FALSE so that examples, tests, and vignettes can
skip gracefully.
terra_is_working()terra_is_working()
Results are cached for the current R session to avoid repeatedly hitting
terra::project() during a single run.
A logical flag indicating whether terra can perform CRS transformations.