diff --git a/DESCRIPTION b/DESCRIPTION index 7e953a3..c17a71b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -7,11 +7,12 @@ Authors@R: role = c("aut", "cre"), email = "tiagoolivoto@gmail.com", comment = c(ORCID = "0000-0002-0241-9636")) -Description: Provides tools for image manipulation and plant image - analysis that will help you to segment images, create binary images, - measure leaf area, quantify disease severity, count the number of - disease lesions, and obtain statistics of image objects such as - grains, pods, pollen, leaves and more. +Description: Provides tools for image manipulation that will help you to + quantify plant leaf area, disease severity, number of disease lesions, + and obtain statistics of image objects such as grains, pods, pollen, + leaves, and more. Tools for segment images and create binary images + using the method of automatic threshold selection method proposed by + Otsu (1979) are also provided. License: GPL (>= 3) Depends: R (>= 4.0.0) diff --git a/NAMESPACE b/NAMESPACE index d9506fa..6372a77 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -20,7 +20,7 @@ export(image_horizontal) export(image_hreflect) export(image_import) export(image_index) -export(image_pallete) +export(image_palette) export(image_pliman) export(image_resize) export(image_rotate) @@ -52,6 +52,7 @@ importFrom(parallel,makeCluster) importFrom(parallel,parLapply) importFrom(parallel,stopCluster) importFrom(stats,aggregate) +importFrom(stats,as.formula) importFrom(stats,binomial) importFrom(stats,glm) importFrom(stats,kmeans) diff --git a/R/color_palette.R b/R/color_palette.R deleted file mode 100644 index e98c581..0000000 --- a/R/color_palette.R +++ /dev/null @@ -1,5 +0,0 @@ -color_pal <- function(n = 20, color, trim_upp, trim_low){ - pal <- hcl.colors(20, "Blues")[-c(1:2)] - image_show(pal) - as.matrix(t(col2rgb(pal))) -} diff --git a/R/count_lesions.R b/R/count_lesions.R index 648dc2e..dea1f3a 100644 --- a/R/count_lesions.R +++ b/R/count_lesions.R @@ -85,7 +85,12 @@ #' processing, when `save_image = TRUE`, the processed image will be also #' saved in such a directory. #' @param verbose If `TRUE` (default) a summary is shown in the console. -#' @return A data frame with the results for each image. +#' @return A list with the following objects: +#' * `results` A data frame with the results (area, perimeter, radius) for +#' object. +#' * `statistics` A data frame with the summary statistics for the image. +#' * `count` (If `img_pattern` is used), summarizing the count number for each +#' image. #' @export #' @md #' @author Tiago Olivoto \email{tiagoolivoto@@gmail.com} @@ -96,6 +101,7 @@ #' healthy <- image_import(image_pliman("sev_healthy.jpg")) #' lesions <- image_import(image_pliman("sev_sympt.jpg")) #' image_combine(img, healthy, lesions, ncol = 3) +#' a <- #' count_lesions(img = img, #' img_healthy = healthy, #' img_lesion = lesions, @@ -224,18 +230,6 @@ count_lesions <- function(img, nmask <- watershed(distmap(plant_symp), tolerance = tol, ext = ext)) - # shape <- - # cbind(data.frame(computeFeatures.shape(nmask)), - # data.frame(computeFeatures.moment(nmask))[,1:2] - # ) - # ifelse(!is.null(lower_size), - # shape <- shape[shape$s.area > lower_size, ], - # shape <- shape[shape$s.area > mean(shape$s.area) * 0.1, ]) - # if(!is.null(upper_size)){ - # shape <- shape[shape$s.area < upper_size, ] - # } - # shape$id <- 1:nrow(shape) - # shape <- shape[, c(9, 7, 8, 1, 2:6)] if(show_original == TRUE & show_segmentation == FALSE){ im2 <- img im2@.Data[,,1][!ID] <- col_lesions[1] @@ -292,14 +286,12 @@ count_lesions <- function(img, sintoma$df_in[sample(1:nrow(sintoma$df_in)),][1:nrows,], fundo$df_in[sample(1:nrow(fundo$df_in)),][1:nrows,]) %>% transform(Y = ifelse(CODE == "img_background", 0, 1)) - # fundo_resto$CODE <- NULL modelo1 <- glm(Y ~ R + G + B, family = binomial("logit"), data = fundo_resto) %>% suppressWarnings() pred1 <- predict(modelo1, newdata = original$df_in, type="response") %>% round(0) plant_background <- matrix(pred1, ncol = ncol(original$R)) plant_background <- image_correct(plant_background, perc = 0.009) - # image_show(plant_background) plant_background[plant_background == 1] <- 2 sadio_sintoma <- rbind(sadio$df_in[sample(1:nrow(sadio$df_in)),][1:nrows,], @@ -318,7 +310,6 @@ count_lesions <- function(img, leaf_sympts <- matrix(pred3, ncol = ncol(original$R)) leaf_sympts <- 1 - image_correct(leaf_sympts, perc = 0.009) plant_background[leaf_sympts == 1] <- 3 - # mpred1 <- bwlabel(leaf_sympts == 0) parms <- read.csv(file=system.file("parameters.csv", package = "pliman", mustWork = TRUE), header = T, sep = ";") parms2 <- parms[parms$object_size == lesion_size,] @@ -333,18 +324,6 @@ count_lesions <- function(img, nmask <- watershed(distmap(leaf_sympts), tolerance = tol, ext = ext)) - # shape <- - # cbind(data.frame(computeFeatures.shape(nmask)), - # data.frame(computeFeatures.moment(nmask))[,1:2] - # ) - # ifelse(!is.null(lower_size), - # shape <- shape[shape$s.area > lower_size, ], - # shape <- shape[shape$s.area > mean(shape$s.area) * 0.1, ]) - # if(!is.null(upper_size)){ - # shape <- shape[shape$s.area < upper_size, ] - # } - # shape$id <- 1:nrow(shape) - # shape <- shape[, c(9, 7, 8, 1, 2:6)] if(show_original == TRUE & show_segmentation == TRUE){ im2 <- colorLabels(nmask) if(backg){ @@ -413,9 +392,6 @@ count_lesions <- function(img, eval(parse(text=x))})) ext <- ifelse(is.null(extension), parms2[rowid, 3], extension) tol <- ifelse(is.null(tolerance), parms2[rowid, 4], tolerance) - # print(res) - # print(ext) - # print(tol) nmask <- watershed(distmap(img2), tolerance = tol, ext = ext) @@ -464,8 +440,6 @@ count_lesions <- function(img, } } - - shape <- cbind(data.frame(computeFeatures.shape(nmask)), data.frame(computeFeatures.moment(nmask))[,1:2] @@ -478,7 +452,6 @@ count_lesions <- function(img, } shape$id <- 1:nrow(shape) shape <- shape[, c(9, 7, 8, 1, 2:6)] - show_mark <- !is.null(marker) && show_segmentation == TRUE | show_segmentation == FALSE marker <- ifelse(is.null(marker), "point", marker) marker_col <- ifelse(is.null(marker_col), "white", marker_col) @@ -553,8 +526,12 @@ count_lesions <- function(img, NA)) %>% transform(statistics = c("n", "min", "mean", "max", "sd", "sum", "prop")) stats <- stats[c(3, 1, 2)] + shape <- shape[,c(1:6, 8:9, 7)] + colnames(shape) <- c("id", "x", "y", "area", "perimeter", "radius_mean", + "radius_min", "radius_max", "radius_sd") results <- list(results = shape, statistics = stats) + class(results) <- "plm_count" if(verbose == TRUE){ print(results$statistics, row.names = FALSE) } diff --git a/R/count_objects.R b/R/count_objects.R index dfa19bc..2843908 100644 --- a/R/count_objects.R +++ b/R/count_objects.R @@ -95,7 +95,12 @@ #' processing, when `save_image = TRUE`, the processed image will be also #' saved in such a directory. #' @param verbose If `TRUE` (default) a summary is shown in the console. -#' @return A data frame with the results for each image. +#' @return A list with the following objects: +#' * `results` A data frame with the results (area, perimeter, radius) for +#' object. +#' * `statistics` A data frame with the summary statistics for the image. +#' * `count` (If `img_pattern` is used), summarizing the count number for each +#' image. #' @export #' @import EBImage #' @md @@ -245,7 +250,6 @@ count_objects <- function(img, ext = ext) ID <- which(img2 == 1) ID2 <- which(img2 == 0) - feat <- computeFeatures.moment(nmask) } backg <- !is.null(col_background) col_background <- col2rgb(ifelse(is.null(col_background), "white", col_background)) @@ -309,7 +313,7 @@ count_objects <- function(img, shape$id <- 1:nrow(shape) shape <- shape[, c(9, 7, 8, 1, 2:6)] show_mark <- !is.null(marker) && show_segmentation == TRUE | show_segmentation == FALSE - marker <- ifelse(is.null(marker), "point", marker) + marker <- ifelse(is.null(marker), "text", marker) marker_col <- ifelse(is.null(marker_col), "white", marker_col) marker_size <- ifelse(is.null(marker_size), 0.9, marker_size) if(show_image == TRUE){ @@ -346,16 +350,16 @@ count_objects <- function(img, if(marker == "text"){ marker_size <- ifelse(is.null(marker_size), 0.75, marker_size) image_show(im2) - text(feat[,1], - feat[,2], - seq(1:nrow(feat)), + text(shape[,2], + shape[,3], + shape[,1], col = marker_col, cex = marker_size) } else{ marker_size <- ifelse(is.null(marker_size), 0.75, marker_size) image_show(im2) - points(feat[,1], - feat[,2], + text(shape[,2], + shape[,3], col = marker_col, pch = 16, cex = marker_size) diff --git a/R/symptomatic_area.R b/R/symptomatic_area.R index 79ae821..0b6ab7b 100644 --- a/R/symptomatic_area.R +++ b/R/symptomatic_area.R @@ -44,7 +44,8 @@ #' processing, when `save_image = TRUE`, the processed image will be also #' saved in such a directory. #' @param verbose If `TRUE` (default) a summary is shown in the console. -#' @return A data frame with the results for each image. +#' @return A data frame with the results (healthy and symptomatic area) for each +#' image. #' @export #' @md #' @importFrom stats binomial glm predict kmeans sd aggregate diff --git a/R/utils_file.R b/R/utils_file.R index 94cfe89..d7cbabf 100644 --- a/R/utils_file.R +++ b/R/utils_file.R @@ -29,9 +29,23 @@ #' @param remove_original Remove original files after manipulation? defaults to #' `FALSE`. If `TRUE` the files in `pattern` will be removed. #' @param verbose If `FALSE`, the code is run silently. +#' @return +#' * `file_extension()`, `file_name()`, and `file_dir()` return a character +#' string. +#' * `manipulate_files()` No return value. If `verbose == TRUE`, a message is +#' printed indicating which operation succeeded (or not) for each of the files +#' attempted. #' @export #' @examples #' \donttest{ +#' library(pliman) +#' # get file name, directory and extension +#' file <- "E:/my_folder/my_subfolder/image1.png" +#' file_dir(file) +#' file_name(file) +#' file_extension(file) +#' +#' # manipulate files #' dir <- tempdir() #' list.files(dir) #' file.create(paste0(dir, "/test.txt")) diff --git a/R/utils_imagem.R b/R/utils_imagem.R index 405f12e..7dc69f0 100644 --- a/R/utils_imagem.R +++ b/R/utils_imagem.R @@ -535,9 +535,9 @@ image_binary <- function(image, } } -#' Image indices +#' Image indexes #' -#' Builds image indices using Red, Green, Blue, Red-Edge, and NIR bands. +#' Builds image indexes using Red, Green, Blue, Red-Edge, and NIR bands. #' @details #' The following indexes are available in pliman. #' @@ -992,14 +992,17 @@ image_to_mat <- function(image, #' @param workers A positive numeric scalar or a function specifying the maximum #' number of parallel processes that can be active at the same time. #' @param verbose If `TRUE` (default) a summary is shown in the console. +#' @return A list with `npal` color palettes of class `Image`. #' @export #' @examples +#' \donttest{ #' library(pliman) #'img <- image_import(image_pliman("sev_leaf.jpg")) -#'pal <- image_pallete(img, 2) +#'pal <- image_palette(img, 2) #'image_show(pal[[1]]) #'image_show(pal[[2]]) -image_pallete <- function(image, +#'} +image_palette <- function(image, npal, nstart = 25, parallel = FALSE, @@ -1017,9 +1020,9 @@ image_pallete <- function(image, if(verbose == TRUE){ message("Image processing using multiple sessions (",nworkers, "). Please wait.") } - parLapply(clust, image, image_pallete, npal, nstart) + parLapply(clust, image, image_palette, npal, nstart) } else{ - lapply(image, image_pallete, npal, nstart) + lapply(image, image_palette, npal, nstart) } } else{ df <- image_to_mat(image)$df_in @@ -1032,7 +1035,7 @@ image_pallete <- function(image, R <- df1[1:dim_mat^2, 1] G <- df1[1:dim_mat^2, 2] B <- df1[1:dim_mat^2, 3] - rgbs[[i]] <- array(c(R, G, B), dim = c(dim_mat, dim_mat, 3)) + rgbs[[i]] <- as.Image(array(c(R, G, B), dim = c(dim_mat, dim_mat, 3))) } return(rgbs) } @@ -1048,7 +1051,8 @@ image_pallete <- function(image, #' @param dpi The image resolution in dots per inch. #' @param px The number of pixels. #' @param cm The size in centimeters. -#' @return A numerical value. +#' @return A numeric value or a vector of numeric values if the input data is a +#' vector #' @export #' @author Tiago Olivoto \email{tiagoolivoto@@gmail.com} #' @examples diff --git a/R/utils_measures.R b/R/utils_measures.R index e80387b..cc23c94 100644 --- a/R/utils_measures.R +++ b/R/utils_measures.R @@ -1,6 +1,6 @@ #' Utilities for object measures #' -#'* `get_measures()` Computes object measures (area, perimeter, radius) by using +#'* `get_measures()` computes object measures (area, perimeter, radius) by using #'either a known resolution (dpi) or an object with known measurements. #' * `plot_measures()` draws the object measures given in an object to the #' current plot. The object identification (`"id"`) is drawn by default. @@ -9,32 +9,33 @@ #' @param object An object computed with [count_objects()] or [leaf_area()]. #' @param dpi A known resolution of the image in DPI (dots per inch). #' @param id An object in the image to indicate a known value. -#' @param measure The measure of the known object. One of the following: -#' * `"area"` The known area of the object. -#' * `"perimeter"` The known perimeter of the object. -#' * `"radius_mean"` The known radius of the object. -#' * `"radius_min"` The known minimum radius of the object. If the object is a +#' @param measure A two-sided formula, e.g., `measure = area ~ 100` indicating +#' the known value of object `id`. The right-hand side is the known value and +#' the left-hand side can be one of the following. +#' * `area` The known area of the object. +#' * `perimeter` The known perimeter of the object. +#' * `radius_mean` The known radius of the object. +#' * `radius_min` The known minimum radius of the object. If the object is a #' square, then the `radius_min` of such object will be `L/2` where `L` is the #' length of the square side. -#' * `"radius_max"` The known maximum radius of the object. If the object is a +#' * `radius_max` The known maximum radius of the object. If the object is a #' square, then the `radius_max` of such object according to the Pythagorean #' theorem will be `L x sqrt(2) / 2` where `L` is the length of the square side. -#' @param true_value The know value of the object `id.` #' @param digits The number of significant figures. Defaults to `2.` #' @param size The size of the text. Defaults to `0.9`. #' @param col The color of the text. Defaults to `"white"`. #' @param verbose If `FALSE`, runs the code silently. #' @param ... Further arguments passed on to [graphics::text()]. #' @return -#' * `get_measures()` returns a data frame with the object `id` and the measures. If any of the -#' `"area"`, `"perimeter"`, `"radius_mean"`, `"radius_min"` or `"radius_max"` -#' is informed, the informed measure will be returned in the unit given in -#' `true_value` and the other measures in pixels. If `dpi` is informed, then -#' all the measures will be adjusted to the known `dpi` and the values -#' returned in cm2 (area) and cm (the other measures). +#' * `get_measures()` returns a data frame with the object `id` and the +#' measures. If `measure` is informed, the pixel values will be corrected by the +#' value of the known object, given in the unit of the right-hand side of +#' `measure`. If `dpi` is informed, then all the measures will be adjusted to +#' the known `dpi`. #' * `plot_measures()` returns a `NULL` object, drawing the text according to #' the x and y coordinates of the objects in `object`. #' @export +#' @importFrom stats as.formula #' @examples #' \donttest{ #' library(pliman) @@ -62,17 +63,15 @@ #' measures[1, "radius_max"] * 2 #' #' -#' # Get object measures by declaring the known area. +#' # Get object measures by declaring the known area of object 1 #' get_measures(results, #' id = 1, -#' measure = "area", -#' true_value = 100) +#' area ~ 100) #'} get_measures <- function(object, - dpi = NULL, id = NULL, measure = NULL, - true_value = NULL, + dpi = NULL, verbose = TRUE){ if(is.data.frame(object)){ if(any(c("area", "perimeter", "radius_mean") %in% colnames(object) == FALSE)){ @@ -81,7 +80,7 @@ get_measures <- function(object, res <- object } if(any(class(object) == "plm_count")){ - res <- object$results + res <- object$results } if(any(class(object) == "plm_la")){ obj <- as.numeric(class(object)[[3]]) @@ -94,7 +93,7 @@ get_measures <- function(object, } } if(any(class(object) == "objects_rgb")){ - res <- object[["objects"]] + res <- object[["objects"]] } if(!is.null(id) & !is.null(dpi)){ stop("Only one of 'dpi' or 'id' can be used.", call. = FALSE) @@ -102,22 +101,41 @@ get_measures <- function(object, if(!is.null(id) & is.null(measure) ){ stop("'measure' must be informed.", call. = FALSE) } - if(!is.null(id) & is.null(true_value)){ - stop("'true_value' must be informed.", call. = FALSE) - } if(!is.null(id)){ + if(class(measure) != "formula"){ + stop("'measure' must be a two-sided formula, e.g., 'area ~ 25'.") + } + terms <- as.formula(measure) + var <- as.character(terms[[2]]) + value <- as.numeric(terms[[3]]) measures <- c("area", "perimeter", "radius_mean", "radius_min", "radius_max") - if(!measure %in% measures){ - stop("'measure' must be one of ", paste(measures, collapse = ", "), call. = FALSE) + if(!var %in% measures){ + stop("The left-hand side of 'measure' must be one of ", paste(measures, collapse = ", "), call. = FALSE) + } + if(var == "area"){ + id_val <- res[which(res$id == id), var] + px_side <- sqrt(value / id_val) + values <- res[, var] + corrected <- values * value / id_val + res$area <- corrected + res$perimeter <- res$perimeter * px_side + res$radius_mean <- res$radius_mean * px_side + res$radius_min <- res$radius_min * px_side + res$radius_max <- res$radius_max * px_side + } + if(var != "area"){ + id_val <- res[which(res$id == id), var] + px_side <- value / id_val + res$area <- res$area * px_side^2 + res$perimeter <- res$perimeter * px_side + res$radius_mean <- res$radius_mean * px_side + res$radius_min <- res$radius_min * px_side + res$radius_max <- res$radius_max * px_side } - id_val <- res[which(res$id == id), measure] - values <- res[, measure] - corrected <- values * true_value / id_val - res[which(colnames(res) == measure)] <- corrected if(verbose == TRUE){ - cat("-----------------------------------------\n") - cat(paste0("measures corrected with:\nobject id: ", id, "\n", measure, ": ", true_value, "\n")) - cat("-----------------------------------------\n") + cat("-----------------------------------------\n") + cat(paste0("measures corrected with:\nobject id: ", id, "\n", var, ": ", value, "\n")) + cat("-----------------------------------------\n") } } if(!is.null(dpi)){ diff --git a/cran-comments.md b/cran-comments.md index 1279e17..5992fe8 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -1,5 +1,32 @@ ## Release summary -This is the first submission of `pliman` (0.1.0) to CRAN +This is a resubmission of the `pliman` (0.1.0) that includes the suggestions given by Julia Haider in the first submission of the package to CRAN + +## Suggestions + +If there are references describing the methods in your package, please +add these in the description field of your DESCRIPTION file in the form +authors (year) +authors (year) +authors (year, ISBN:...) +or if those are not available: +with no space after 'doi:', 'arXiv:', 'https:' and angle brackets for +auto-linking. +(If you want to add a title as well please put it in quotes: "Title") + +* Implemented. Please, see the DESCRIPTION file. + + +Please add \value to .Rd files regarding exported methods and explain +the functions results in the documentation. Please write about the +structure of the output (class) and also what the output means. (If a +function does not return a value, please document that too, e.g. +\value{No return value, called for side effects} or similar) +Missing Rd-tags: + image_pallete.Rd: \value + utils_file.Rd: \value + +* Done! I have included \value to all the .Rd files. + ## Test environments * local R installation, R 4.0.5 diff --git a/man/count_lesions.Rd b/man/count_lesions.Rd index 66d1ebc..c02223f 100644 --- a/man/count_lesions.Rd +++ b/man/count_lesions.Rd @@ -149,7 +149,14 @@ saved in such a directory.} \item{verbose}{If \code{TRUE} (default) a summary is shown in the console.} } \value{ -A data frame with the results for each image. +A list with the following objects: +\itemize{ +\item \code{results} A data frame with the results (area, perimeter, radius) for +object. +\item \code{statistics} A data frame with the summary statistics for the image. +\item \code{count} (If \code{img_pattern} is used), summarizing the count number for each +image. +} } \description{ Counts the number of lesions in a sample or entire leaf based on provided @@ -168,6 +175,7 @@ img <- image_import(image_pliman("sev_leaf_nb.jpg")) healthy <- image_import(image_pliman("sev_healthy.jpg")) lesions <- image_import(image_pliman("sev_sympt.jpg")) image_combine(img, healthy, lesions, ncol = 3) +a <- count_lesions(img = img, img_healthy = healthy, img_lesion = lesions, diff --git a/man/count_objects.Rd b/man/count_objects.Rd index bf4073a..0b35915 100644 --- a/man/count_objects.Rd +++ b/man/count_objects.Rd @@ -148,7 +148,14 @@ saved in such a directory.} \item{verbose}{If \code{TRUE} (default) a summary is shown in the console.} } \value{ -A data frame with the results for each image. +A list with the following objects: +\itemize{ +\item \code{results} A data frame with the results (area, perimeter, radius) for +object. +\item \code{statistics} A data frame with the summary statistics for the image. +\item \code{count} (If \code{img_pattern} is used), summarizing the count number for each +image. +} } \description{ Counts the number of objects in an image. See more at details. diff --git a/man/image_index.Rd b/man/image_index.Rd index 3833a28..f16129f 100644 --- a/man/image_index.Rd +++ b/man/image_index.Rd @@ -3,7 +3,7 @@ \name{image_index} \alias{image_index} \alias{plot.image_index} -\title{Image indices} +\title{Image indexes} \usage{ image_index( image, @@ -74,7 +74,7 @@ A \code{ggplot} object containing the distribution of the pixels for each index. } \description{ -Builds image indices using Red, Green, Blue, Red-Edge, and NIR bands. +Builds image indexes using Red, Green, Blue, Red-Edge, and NIR bands. Produces an histogram of an \code{image_index} object } diff --git a/man/image_pallete.Rd b/man/image_palette.Rd similarity index 86% rename from man/image_pallete.Rd rename to man/image_palette.Rd index 25c88ac..4d8afaf 100644 --- a/man/image_pallete.Rd +++ b/man/image_palette.Rd @@ -1,10 +1,10 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils_imagem.R -\name{image_pallete} -\alias{image_pallete} +\name{image_palette} +\alias{image_palette} \title{Create an image palette} \usage{ -image_pallete( +image_palette( image, npal, nstart = 25, @@ -30,13 +30,18 @@ number of parallel processes that can be active at the same time.} \item{verbose}{If \code{TRUE} (default) a summary is shown in the console.} } +\value{ +A list with \code{npal} color palettes of class \code{Image}. +} \description{ Creates image palettes by applying the k-means algorithm to the RGB values. } \examples{ +\donttest{ library(pliman) img <- image_import(image_pliman("sev_leaf.jpg")) -pal <- image_pallete(img, 2) +pal <- image_palette(img, 2) image_show(pal[[1]]) image_show(pal[[2]]) } +} diff --git a/man/symptomatic_area.Rd b/man/symptomatic_area.Rd index 6122bb0..58e9a9f 100644 --- a/man/symptomatic_area.Rd +++ b/man/symptomatic_area.Rd @@ -84,7 +84,8 @@ saved in such a directory.} \item{verbose}{If \code{TRUE} (default) a summary is shown in the console.} } \value{ -A data frame with the results for each image. +A data frame with the results (healthy and symptomatic area) for each +image. } \description{ Calculates the percentage of symptomatic leaf area in sample or entire diff --git a/man/utils_dpi.Rd b/man/utils_dpi.Rd index 4d509b9..099f3e8 100644 --- a/man/utils_dpi.Rd +++ b/man/utils_dpi.Rd @@ -24,7 +24,8 @@ cm_to_pixels(cm, dpi) \item{px}{The number of pixels.} } \value{ -A numerical value. +A numeric value or a vector of numeric values if the input data is a +vector } \description{ Provides useful conversions between size (cm), number of pixels (px) and diff --git a/man/utils_file.Rd b/man/utils_file.Rd index abd9658..ee5fa00 100644 --- a/man/utils_file.Rd +++ b/man/utils_file.Rd @@ -60,6 +60,15 @@ Set \code{overwrite = TRUE} to overwrite the files.} \item{verbose}{If \code{FALSE}, the code is run silently.} } +\value{ +\itemize{ +\item \code{file_extension()}, \code{file_name()}, and \code{file_dir()} return a character +string. +\item \code{manipulate_files()} No return value. If \code{verbose == TRUE}, a message is +printed indicating which operation succeeded (or not) for each of the files +attempted. +} +} \description{ \itemize{ \item \code{file_extension()} Get the extension of a file. @@ -72,6 +81,14 @@ directory. } \examples{ \donttest{ +library(pliman) +# get file name, directory and extension +file <- "E:/my_folder/my_subfolder/image1.png" +file_dir(file) +file_name(file) +file_extension(file) + +# manipulate files dir <- tempdir() list.files(dir) file.create(paste0(dir, "/test.txt")) diff --git a/man/utils_measures.Rd b/man/utils_measures.Rd index 0ac59cd..f2ae8e8 100644 --- a/man/utils_measures.Rd +++ b/man/utils_measures.Rd @@ -6,14 +6,7 @@ \alias{plot_measures} \title{Utilities for object measures} \usage{ -get_measures( - object, - dpi = NULL, - id = NULL, - measure = NULL, - true_value = NULL, - verbose = TRUE -) +get_measures(object, id = NULL, measure = NULL, dpi = NULL, verbose = TRUE) plot_measures( object, @@ -27,24 +20,24 @@ plot_measures( \arguments{ \item{object}{An object computed with \code{\link[=count_objects]{count_objects()}} or \code{\link[=leaf_area]{leaf_area()}}.} -\item{dpi}{A known resolution of the image in DPI (dots per inch).} - \item{id}{An object in the image to indicate a known value.} -\item{measure}{The measure of the known object. One of the following: +\item{measure}{A two-sided formula, e.g., \code{measure = area ~ 100} indicating +the known value of object \code{id}. The right-hand side is the known value and +the left-hand side can be one of the following. \itemize{ -\item \code{"area"} The known area of the object. -\item \code{"perimeter"} The known perimeter of the object. -\item \code{"radius_mean"} The known radius of the object. -\item \code{"radius_min"} The known minimum radius of the object. If the object is a +\item \code{area} The known area of the object. +\item \code{perimeter} The known perimeter of the object. +\item \code{radius_mean} The known radius of the object. +\item \code{radius_min} The known minimum radius of the object. If the object is a square, then the \code{radius_min} of such object will be \code{L/2} where \code{L} is the length of the square side. -\item \code{"radius_max"} The known maximum radius of the object. If the object is a +\item \code{radius_max} The known maximum radius of the object. If the object is a square, then the \code{radius_max} of such object according to the Pythagorean theorem will be \verb{L x sqrt(2) / 2} where \code{L} is the length of the square side. }} -\item{true_value}{The know value of the object \code{id.}} +\item{dpi}{A known resolution of the image in DPI (dots per inch).} \item{verbose}{If \code{FALSE}, runs the code silently.} @@ -58,19 +51,18 @@ theorem will be \verb{L x sqrt(2) / 2} where \code{L} is the length of the squar } \value{ \itemize{ -\item \code{get_measures()} returns a data frame with the object \code{id} and the measures. If any of the -\code{"area"}, \code{"perimeter"}, \code{"radius_mean"}, \code{"radius_min"} or \code{"radius_max"} -is informed, the informed measure will be returned in the unit given in -\code{true_value} and the other measures in pixels. If \code{dpi} is informed, then -all the measures will be adjusted to the known \code{dpi} and the values -returned in cm2 (area) and cm (the other measures). +\item \code{get_measures()} returns a data frame with the object \code{id} and the +measures. If \code{measure} is informed, the pixel values will be corrected by the +value of the known object, given in the unit of the right-hand side of +\code{measure}. If \code{dpi} is informed, then all the measures will be adjusted to +the known \code{dpi}. \item \code{plot_measures()} returns a \code{NULL} object, drawing the text according to the x and y coordinates of the objects in \code{object}. } } \description{ \itemize{ -\item \code{get_measures()} Computes object measures (area, perimeter, radius) by using +\item \code{get_measures()} computes object measures (area, perimeter, radius) by using either a known resolution (dpi) or an object with known measurements. \item \code{plot_measures()} draws the object measures given in an object to the current plot. The object identification (\code{"id"}) is drawn by default. @@ -103,10 +95,9 @@ plot_measures(results, measure = "id") measures[1, "radius_max"] * 2 -# Get object measures by declaring the known area. +# Get object measures by declaring the known area of object 1 get_measures(results, id = 1, - measure = "area", - true_value = 100) + area ~ 100) } } diff --git a/vignettes/count_objects.Rmd b/vignettes/count_objects.Rmd index 4b22d4a..f6be284 100644 --- a/vignettes/count_objects.Rmd +++ b/vignettes/count_objects.Rmd @@ -70,8 +70,7 @@ Since we have known the area of the larger square (object 1), let us adjust the ```{r} get_measures(img_res, id = 1, - measure = "area", - true_value = 100) + area ~ 100) ``` The same can be used to adjust the measures based on the perimeter or radius. Let us adjust the perimeter of objects by the perimeter of object 2 (20 cm). @@ -79,8 +78,7 @@ The same can be used to adjust the measures based on the perimeter or radius. Le ```{r} get_measures(img_res, id = 2, - measure = "perimeter", - true_value = 20) + perimeter ~ 20) ``` ## Declaring the image resolution diff --git a/vignettes/leaf_area.Rmd b/vignettes/leaf_area.Rmd index e1b679a..bae83ed 100644 --- a/vignettes/leaf_area.Rmd +++ b/vignettes/leaf_area.Rmd @@ -90,8 +90,7 @@ The function `get_measures()` is used to adjust the leaf area using the object 6 area <- get_measures(count, id = 6, - measure = "area", - true_value = 4) + area ~ 4) area image_show(leaves) plot_measures(area, measure = "area")