#' Morphology
#'
#' Apply a morphology method. This is a very flexible function which
#' can be used to apply any morphology method with custom parameters.
#' See [imagemagick website](https://legacy.imagemagick.org/Usage/morphology/)
#' for examples.
#'
#' @export
#' @inheritParams effects
#' @param method a string with a valid method from [morphology_types()]
#' @param opts a named list or character vector with custom attributes
#' @rdname morphology
#' @name morphology
#' @family image
#' @examples #example from IM website:
#' if(magick_config()$version > "6.8.8"){
#' pixel <- image_blank(1, 1, 'white') |> image_border('black', '5x5')
#'
#' # See the effect of Dilate method
#' pixel |> image_scale('800%')
#' pixel |> image_morphology('Dilate', "Diamond") |> image_scale('800%')
#'
#' # These produce the same output:
#' pixel |> image_morphology('Dilate', "Diamond", iter = 3) |> image_scale('800%')
#' pixel |> image_morphology('Dilate', "Diamond:3") |> image_scale('800%')
#'
#' # Plus example
#' pixel |> image_morphology('Dilate', "Plus", iterations = 2) |> image_scale('800%')
#'
#' # Rose examples
#' rose |> image_morphology('ErodeI', 'Octagon', iter = 3)
#' rose |> image_morphology('DilateI', 'Octagon', iter = 3)
#' rose |> image_morphology('OpenI', 'Octagon', iter = 3)
#' rose |> image_morphology('CloseI', 'Octagon', iter = 3)
#'
#' # Edge detection
#' man <- demo_image('man.gif')
#' man |> image_morphology('EdgeIn', 'Octagon')
#' man |> image_morphology('EdgeOut', 'Octagon')
#' man |> image_morphology('Edge', 'Octagon')
#'
#' # Octagonal Convex Hull
#' man |>
#' image_morphology('Close', 'Diamond') |>
#' image_morphology('Thicken', 'ConvexHull', iterations = 1)
#'
#' # Thinning down to a Skeleton
#' man |> image_morphology('Thinning', 'Skeleton', iterations = 1)
#'
#' # Specify custom kernel matrix usingn a string:
#' img <- demo_image("test_mag.gif")
#' i <- image_convolve(img, kernel = '4x5:
#' 0 -1 0 0
#' -1 +1 -1 0
#' -1 +1 -1 0
#' -1 +1 +1 -1
#' 0 -1 -1 0 ', bias = "50%")
#' }
image_morphology <- function(image, method = "convolve", kernel = "Gaussian",
iterations = 1, opts = list()){
assert_image(image)
method <- as.character(method)
kernel <- as.character(kernel)
opt_names <- as.character(names(opts))
opt_values <- as.character(unname(opts))
magick_image_morphology(image, method, kernel, iterations, opt_names, opt_values)
}
#' @export
#' @rdname morphology
#' @param kernel either a square matrix or a string. The string can either be a
#' parameterized [kerneltype][kernel_types] such as: `"DoG:0,0,2"` or `"Diamond"`
#' or it can contain a custom matrix (see examples)
#' @param iterations number of iterations
#' @param scaling string with kernel scaling. The special flag `"!"` automatically scales to full
#' dynamic range, for example: \code{"50\%!"}
#' @param bias output bias string, for example \code{"50\%"}
image_convolve <- function(image, kernel = 'Gaussian', iterations = 1, scaling = NULL, bias = NULL){
assert_image(image)
iterations <- as.integer(iterations)
scaling <- as.character(scaling)
bias <- as.character(bias)
if(is.character(kernel)){
magick_image_convolve_kernel(image, kernel, iterations, scaling, bias)
} else if(is.matrix(kernel)) {
if(nrow(kernel) != ncol(kernel))
stop("Kernel matrix must be squared")
kernel <- t(kernel) #See issue #126
if(iterations < 1)
stop("Convolve with matrix kernel does not support negative iterations")
magick_image_convolve_matrix(image, kernel, iterations, scaling, bias)
} else {
stop("Argument 'kernel' must either be a string or matrix")
}
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.