Skip to content

Commit

Permalink
Merge pull request #1036 from OldLipe/feat/temp_seg
Browse files Browse the repository at this point in the history
Re-introduces `sits_clean` function to SITS API
  • Loading branch information
gilbertocamara authored Nov 13, 2023
2 parents b14307b + 8f5d28c commit ee3531c
Show file tree
Hide file tree
Showing 8 changed files with 335 additions and 53 deletions.
1 change: 1 addition & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,7 @@ Collate:
'sits_csv.R'
'sits_cube.R'
'sits_cube_copy.R'
'sits_clean.R'
'sits_cluster.R'
'sits_factory.R'
'sits_filters.R'
Expand Down
6 changes: 6 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,11 @@ S3method(sits_classify,raster_cube)
S3method(sits_classify,segs_cube)
S3method(sits_classify,sits)
S3method(sits_classify,tbl_df)
S3method(sits_clean,class_cube)
S3method(sits_clean,default)
S3method(sits_clean,derived_cube)
S3method(sits_clean,raster_cube)
S3method(sits_clean,tbl_df)
S3method(sits_cluster_dendro,default)
S3method(sits_cluster_dendro,sits)
S3method(sits_cluster_dendro,tbl_df)
Expand Down Expand Up @@ -389,6 +394,7 @@ export(sits_as_sf)
export(sits_bands)
export(sits_bbox)
export(sits_classify)
export(sits_clean)
export(sits_cluster_clean)
export(sits_cluster_dendro)
export(sits_cluster_frequency)
Expand Down
20 changes: 17 additions & 3 deletions R/api_clean.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#' the most frequently values within the neighborhood.
#' In a tie, the first value of the vector is considered.
#'
#' @param asset Subset of a data cube
#' @param tile Subset of a data cube
#' @param block Image block to be cleaned
#' @param band Band to be processed
#' @param window_size Size of local neighborhood
Expand All @@ -26,6 +26,19 @@
out_file <- .file_derived_name(
tile = tile, band = band, version = version, output_dir = output_dir
)
# Resume tile
if (.raster_is_valid(out_file, output_dir = output_dir)) {
# recovery message
.check_recovery(out_file)
# Create tile based on template
tile <- .tile_derived_from_file(
file = out_file, band = band,
base_tile = tile, derived_class = .tile_derived_class(tile),
labels = .tile_labels(tile),
update_bbox = FALSE
)
return(tile)
}
# Create chunks as jobs
chunks <- .tile_chunks_create(
tile = tile, overlap = overlap, block = block
Expand Down Expand Up @@ -86,8 +99,9 @@
update_bbox = FALSE
)
# Return a asset
band_tile
return(band_tile)
}

#' @title Read data for cleaning operation
#' @name .clean_data_read
#' @author Felipe Carvalho, \email{felipe.carvalho@@inpe.br}
Expand All @@ -103,5 +117,5 @@
# Set columns name
colnames(values) <- band
# Return values
values
return(values)
}
13 changes: 13 additions & 0 deletions R/api_label_class.R
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,19 @@
out_file <- .file_derived_name(
tile = tile, band = band, version = version, output_dir = output_dir
)
# Resume feature
if (file.exists(out_file)) {
.check_recovery(tile[["tile"]])
class_tile <- .tile_derived_from_file(
file = out_file,
band = "class",
base_tile = tile,
derived_class = "class_cube",
labels = .tile_labels(tile),
update_bbox = FALSE
)
return(class_tile)
}
# Create chunks as jobs
chunks <- .tile_chunks_create(tile = tile, overlap = 0)
# Process jobs in parallel
Expand Down
165 changes: 165 additions & 0 deletions R/sits_clean.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
#' @title Cleans a classified map using a local window
#'
#' @name sits_clean
#'
#' @author Felipe Carvalho, \email{felipe.carvalho@@inpe.br}
#'
#' @description
#' Applies a modal function to clean up possible noisy pixels keeping
#' the most frequently values within the neighborhood.
#' In a tie, the first value of the vector is considered.
#'
#' @param cube Classified data cube (tibble of class "class_cube").
#' @param window_size An odd integer representing the size of the
#' sliding window of the modal function (min = 1, max = 15).
#' @param memsize Memory available for classification in GB
#' (integer, min = 1, max = 16384).
#' @param multicores Number of cores to be used for classification
#' (integer, min = 1, max = 2048).
#' @param output_dir Valid directory for output file.
#' (character vector of length 1).
#' @param version Version of the output file
#' (character vector of length 1)
#' @param progress Logical: Show progress bar?
#'
#' @return A tibble with an classified map (class = "class_cube").
#'
#' @examples
#' if (sits_run_examples()) {
#' rf_model <- sits_train(samples_modis_ndvi, ml_method = sits_rfor)
#' # create a data cube from local files
#' data_dir <- system.file("extdata/raster/mod13q1", package = "sits")
#' cube <- sits_cube(
#' source = "BDC",
#' collection = "MOD13Q1-6",
#' data_dir = data_dir
#' )
#' # classify a data cube
#' probs_cube <- sits_classify(
#' data = cube,
#' ml_model = rf_model,
#' output_dir = tempdir()
#' )
#' # label the probability cube
#' label_cube <- sits_label_classification(
#' probs_cube,
#' output_dir = tempdir()
#' )
#' # apply a mode function in the labelled cube
#' clean_cube <- sits_clean(
#' cube = label_cube,
#' window_size = 5,
#' output_dir = tempdir(),
#' multicores = 1
#' )
#' }
#'
#' @export
sits_clean <- function(cube, window_size = 5L, memsize = 4L,
multicores = 2L, output_dir, version = "v1-clean",
progress = TRUE) {
# Precondition
# Check the cube is valid
.check_valid(cube)
UseMethod("sits_clean", cube)
}
#' @rdname sits_clean
#' @export
sits_clean.class_cube <- function(cube, window_size = 5L, memsize = 4L,
multicores = 2L, output_dir,
version = "v1-clean", progress = TRUE) {
# Preconditions
# Check cube has files
.check_cube_files(cube)
# Check window size
.check_window_size(window_size, min = 1, max = 15)
# Check memsize
.check_memsize(memsize, min = 1, max = 16384)
# Check multicores
.check_multicores(multicores, min = 1, max = 2048)
# Check output_dir
.check_output_dir(output_dir)
# Check version
.check_version(version)
# version is case-insensitive in sits
version <- tolower(version)
# Check progress
.check_progress(progress)

# Get input band
band <- .cube_bands(cube)
# image size
image_size <- .raster_size(.raster_open_rast(.tile_path(cube)))
# Overlapping pixels
overlap <- ceiling(window_size / 2) - 1
# Check minimum memory needed to process one block
job_memsize <- .jobs_memsize(
job_size = .block_size(block = image_size, overlap = overlap),
npaths = 1, nbytes = 8,
proc_bloat = .conf("processing_bloat")
)
# Update multicores parameter
multicores <- .jobs_max_multicores(
job_memsize = job_memsize, memsize = memsize, multicores = multicores
)
# Prepare parallelization
.parallel_start(workers = multicores)
on.exit(.parallel_stop(), add = TRUE)

# Process each tile sequentially
clean_cube <- .cube_foreach_tile(cube, function(tile) {
# Process the data
clean_tile <- .clean_tile(
tile = tile,
block = image_size,
band = band,
window_size = window_size,
overlap = overlap,
output_dir = output_dir,
version = version
)
return(clean_tile)
})
# Update cube class
class(clean_cube) <- c("class_cube", class(clean_cube))
# Return cleaned cube
return(clean_cube)
}

#' @rdname sits_clean
#' @export
sits_clean.raster_cube <- function(cube, window_size = 5L, memsize = 4L,
multicores = 2L, output_dir,
version = "v1-clean", progress = TRUE) {
stop("Input should be a classified cube")
return(cube)
}
#' @rdname sits_clean
#' @export
sits_clean.derived_cube <- function(cube, window_size = 5L, memsize = 4L,
multicores = 2L, output_dir,
version = "v1-clean", progress = TRUE) {
stop("Input should be a classified cube")
return(cube)
}
#' @rdname sits_clean
#' @export
sits_clean.tbl_df <- function(cube, window_size = 5L, memsize = 4L,
multicores = 2L, output_dir,
version = "v1-clean", progress = TRUE) {
cube <- tibble::as_tibble(cube)
if (all(.conf("sits_cube_cols") %in% colnames(cube))) {
cube <- .cube_find_class(cube)
} else
stop("Input should be a classified cube")
clean_cube <- sits_clean(cube, window_size, memsize, multicores,
output_dir, version, progress)
return(clean_cube)
}
#' @rdname sits_clean
#' @export
sits_clean.default <- function(cube, window_size = 5L, memsize = 4L,
multicores = 2L, output_dir,
version = "v1-clean", progress = TRUE) {
stop("Input should be a classified cube")
}
39 changes: 0 additions & 39 deletions R/sits_label_classification.R
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,6 @@
#'
#' @param cube Classified image data cube.
#' @param ... Other parameters for specific functions.
#' @param clean A logical value to apply a modal function to clean up
#' possible noisy pixels keeping the most frequently
#' values within the neighborhood. Default is TRUE.
#' @param window_size An odd integer representing the size of the
#' sliding window of the modal function (min = 1, max = 15).
#' @param multicores Number of workers to label the classification in
#' parallel.
#' @param memsize maximum overall memory (in GB) to label the
Expand Down Expand Up @@ -58,8 +53,6 @@
#' }
#' @export
sits_label_classification <- function(cube,
clean = TRUE,
window_size = 3L,
memsize = 4,
multicores = 2,
output_dir,
Expand All @@ -72,8 +65,6 @@ sits_label_classification <- function(cube,
#' @rdname sits_label_classification
#' @export
sits_label_classification.probs_cube <- function(cube, ...,
clean = TRUE,
window_size = 3L,
memsize = 4L,
multicores = 2L,
output_dir,
Expand Down Expand Up @@ -120,24 +111,6 @@ sits_label_classification.probs_cube <- function(cube, ...,
label_fn <- .label_fn_majority()
# Process each tile sequentially
class_cube <- .cube_foreach_tile(cube, function(tile) {
# Output file
out_file <- .file_derived_name(
tile = tile, band = "class", version = version,
output_dir = output_dir
)
# Resume feature
if (file.exists(out_file)) {
.check_recovery(tile[["tile"]])
class_tile <- .tile_derived_from_file(
file = out_file,
band = "class",
base_tile = tile,
derived_class = "class_cube",
labels = .tile_labels(tile),
update_bbox = FALSE
)
return(class_tile)
}
# Label the data
class_tile <- .label_tile(
tile = tile,
Expand All @@ -147,18 +120,6 @@ sits_label_classification.probs_cube <- function(cube, ...,
version = version,
progress = progress
)
if (clean) {
# Apply clean in data
class_tile <- .clean_tile(
tile = class_tile,
block = image_size,
band = "class",
window_size = window_size,
overlap = overlap,
output_dir = output_dir,
version = version
)
}
return(class_tile)
})
return(class_cube)
Expand Down
Loading

0 comments on commit ee3531c

Please sign in to comment.