--- a +++ b/R/ear_mask.R @@ -0,0 +1,203 @@ +#' @rdname ear_mask +#' @title Create Mask of the Ears +#' @aliases ct_ear_mask,mri_ear_mask +#' @description Creates a rough mask of the ear from a head scan +#' +#' @param file File for face masking - either filename or class nifti +#' @param mask file or \code{nifti} to mask the \code{file} +#' @param robust If \code{mask = NULL}, then \code{robust} is +#' passed to \code{\link{CT_Skull_Stripper}} +#' @param template.file Template to warp to original image space +#' @param template.ear_mask Mask of template to use as rough ear mask. If +#' \code{template.file} is not specified, \code{template.left_ear_inds} and +#' \code{template.right_ear_inds} +#' must be +#' @param template.left_ear_inds List of length 3 for indices of +#' \code{template.file} to indicate the left-ear mask. +#' @param template.right_ear_inds List of length 3 for indices of +#' \code{template.file} to indicate the right-ear mask. +#' @param extend_left after transformation, should the mask be extended to the +#' left of the image to ensure all left ear has been removed? +#' @param extend_right after transformation, should the mask be extended to the +#' right of the image to ensure all right ear has been removed? +#' @param typeofTransform Transformation for template to image, passed to +#' \code{\link{ants_regwrite}}. +#' @param swapdim Should the dimensions be swapped before registration, +#' and then reset after +#' @param skull_strip Should the data require skull stripping if +#' no mask is provided? +#' @param verbose Print out diagnostic messages +#' @param ... arguments passed to \code{\link{CT_Skull_Stripper}} +#' @export +#' @return Object of class nifti +#' @examples \dontrun{ +#' file = "~/Desktop/Desktop/scratch/100-318_20070723_0957_CT_3_CT_Head-.nii.gz" +#' mask = NULL +#' robust = FALSE +#' ears = ct_ear_mask( +#' file = file, +#' robust = FALSE +#' ) +#' img = readnii(file) +#' rimg = randomize_mask(img, mask = ears) +#' } +ct_ear_mask = function( + file, + skull_strip = TRUE, + mask = NULL, + robust = TRUE, + template.file = + system.file( + "scct_unsmooth_SS_0.01.nii.gz", + package = "ichseg"), + template.ear_mask = NULL, + template.left_ear_inds = list(170:180, 60:110, 1:60), + template.right_ear_inds = list(1:10, 60:110, 1:60), + extend_left = TRUE, + extend_right = TRUE, + typeofTransform = "Affine", + swapdim = TRUE, + verbose = TRUE, + ...){ + + if (skull_strip) { + mask = .make_ss_mask(file = file, + mask = mask, + verbose = verbose, + robust = robust, + template.file = template.file, ...) + } + + template.left_ear_mask = .make_template_mask( + template.file = template.file, + template.mask = template.ear_mask, + template.inds = template.left_ear_inds) + template.right_ear_mask = .make_template_mask( + template.file = template.file, + template.mask = template.ear_mask, + template.inds = template.right_ear_inds) + + template.ear_mask = template.left_ear_mask | template.right_ear_mask + + L = .mask_reg(file = file, + mask = mask, + verbose = verbose, + swapdim = swapdim, + template.file = template.file, + typeofTransform = typeofTransform, + template.mask = template.ear_mask) + + mask_trans = L$mask_trans + img = L$img + + + ###################################### + # Applying the mask to the image + ###################################### + mask_trans = mask_trans > 0.5 + any_in_mask = any(mask_trans) + ind = which(mask_trans, arr.ind = TRUE) + dimg = dim(img) + xdim = dimg[1] + midx = xdim/2 + if (extend_left || extend_right) { + if (any_in_mask) { + df = data.frame(ind) + df$left = c("left", "right")[ (df$dim1 > midx) + 1] + ss = split(df, df$left) + ss = lapply(ss, function(x) { + x$left = NULL + x + }) + inds = NULL + ind = ss$left + if (!is.null(ind) && nrow(ind) > 0) { + xs = seq(1, max(ind$dim1)) # for left + ys = unique(ind$dim2) + zs = unique(ind$dim3) + run_inds = expand.grid(xs, ys, zs) + run_inds = as.matrix(run_inds) + } + inds = rbind(inds, run_inds) + + ind = ss$right + if (!is.null(ind) && nrow(ind) > 0) { + xs = seq(min(ind$dim1), xdim) # for right + ys = unique(ind$dim2) + zs = unique(ind$dim3) + run_inds = expand.grid(xs, ys, zs) + run_inds = as.matrix(run_inds) + } + inds = rbind(inds, run_inds) + + newimg = niftiarr(img, 0) + newimg[inds] = 1 + newimg = cal_img(newimg) + } else { + warning("No registered object in mask found - cannot extend!") + newimg = mask_trans + } + } else { + newimg = mask_trans + } + + + if (swapdim) { + if (verbose) { + message(paste0("# Swapping Dimensions Back\n")) + } + sorient = L$sorient + ori = L$ori + newimg = reverse_rpi_orient( + file = newimg, + convention = ori, + orientation = sorient, + verbose = verbose) + } + return(newimg) +} + + + +#' @rdname ear_mask +#' @export +mri_ear_mask = function( + ..., + skull_strip = TRUE, + mask = NULL, + robust = FALSE, + template.file = mni_fname(brain = skull_strip) +){ + + L = list(...) + L$robust = robust + L$skull_strip = skull_strip + L$mask = mask + L$template.file = template.file + + if (is.null(mask) & skull_strip) { + func = function(L, arg, opt) { + nL = names(L) + if (!arg %in% nL) { + L[arg] = opt + } + return(L) + } + uthresh = L$uthresh + if (is.null(uthresh)) { + file = L$file + if (is.null(file)) { + file = L[[1]] + } + uthresh = fslr::fslmax(file) + L$uthresh = uthresh + } + + L = func(L, "presmooth", FALSE) + L = func(L, "remask", FALSE) + L = func(L, "inskull_mesh", FALSE) + L = func(L, "opts", "-v") + } + res = do.call("ct_ear_mask", args = L) + return(res) +}