a b/R/face_mask.R
1
#' @rdname face_mask
2
#' @title Create Mask of the Face
3
#' @aliases ct_face_mask,mri_face_mask
4
#' @description Creates a rough mask of the face from a head scan
5
#'
6
#' @param file File for face masking - either filename or class nifti
7
#' @param mask file or \code{nifti} to mask the \code{file}
8
#' @param robust If \code{mask = NULL}, then \code{robust} is
9
#' passed to \code{\link{CT_Skull_Stripper}}
10
#' @param template.file Template to warp to original image space
11
#' @param template.face_mask Mask of template to use as rough face mask.  If
12
#' \code{template.file} is not specified, \code{template.face_mask_inds}
13
#' must be
14
#' @param template.face_mask_inds List of length 3 for indices of
15
#' \code{template.file} to indicate the mask.
16
#' @param extend_mask after transformation, should the mask be extended to the
17
#' front of the image to ensure all face has been removed?
18
#' @param typeofTransform Transformation for template to image, passed to
19
#' \code{\link{ants_regwrite}}.
20
#' @param swapdim Should the dimensions be swapped before registration,
21
#' and then reset after
22
#' @param skull_strip Should the data require skull stripping if
23
#' no mask is provided?
24
#' @param verbose Print out diagnostic messages
25
#' @param ... arguments passed to \code{\link{CT_Skull_Stripper}}
26
#' @export
27
#' @return Object of class nifti
28
#' @importFrom neurobase check_mask_fail
29
#' @importFrom fslr rpi_orient reverse_rpi_orient
30
#' @examples \dontrun{
31
#' file = "~/Desktop/Desktop/scratch/100-318_20070723_0957_CT_3_CT_Head-.nii.gz"
32
#' mask = NULL
33
#' robust = FALSE
34
#' face = ct_face_mask(
35
#'    file = file,
36
#'    robust = FALSE
37
#'    )
38
#'  img = readnii(file)
39
#'  rimg = randomize_mask(img, mask = face)
40
#' }
41
#'
42
ct_face_mask <- function(
43
  file,
44
  skull_strip = TRUE,
45
  mask = NULL,
46
  robust = TRUE,
47
  template.file =
48
    system.file(
49
      ifelse(skull_strip,
50
             "scct_unsmooth_SS_0.01.nii.gz",
51
             "scct_unsmooth.nii.gz"),
52
      package = "ichseg"),
53
  template.face_mask = NULL,
54
  template.face_mask_inds = list(50:130, 170:217, 1:15),
55
  extend_mask = TRUE,
56
  typeofTransform = "Affine",
57
  swapdim = TRUE,
58
  verbose = TRUE,
59
  ...){
60
61
  if (skull_strip) {
62
    mask = .make_ss_mask(file = file,
63
                         mask = mask,
64
                         verbose = verbose,
65
                         robust = robust,
66
                         template.file = template.file, ...)
67
  }
68
69
  template.face_mask = .make_template_mask(
70
    template.file = template.file,
71
    template.mask = template.face_mask,
72
    template.inds = template.face_mask_inds)
73
74
  L = .mask_reg(file = file,
75
                mask = mask,
76
                verbose = verbose,
77
                swapdim = swapdim,
78
                template.file = template.file,
79
                typeofTransform = typeofTransform,
80
                template.mask = template.face_mask)
81
82
  mask_trans = L$mask_trans
83
  img = L$img
84
85
86
  ######################################
87
  # Applying the mask to the image
88
  ######################################
89
  mask_trans = mask_trans > 0.5
90
  any_in_mask = any(mask_trans)
91
  ind = which(mask_trans, arr.ind = TRUE)
92
  if (extend_mask) {
93
    if (any_in_mask) {
94
      minz = ceiling(mean(ind[,"dim3"]))
95
      zs = seq(minz)
96
      miny = min(ind[,"dim2"])
97
      ys = seq(miny, dim(mask_trans)[2])
98
      xs = unique(ind[,"dim1"])
99
      inds = expand.grid(xs, ys, zs)
100
      inds = as.matrix(inds)
101
102
      newimg = niftiarr(img, 0)
103
      newimg[inds] = 1
104
      newimg = cal_img(newimg)
105
    } else {
106
      warning("No registered object in mask found - cannot extend!")
107
      newimg = mask_trans
108
    }
109
  } else {
110
    newimg = mask_trans
111
  }
112
113
114
  if (swapdim) {
115
    if (verbose) {
116
      message(paste0("# Swapping Dimensions Back\n"))
117
    }
118
    sorient = L$sorient
119
    ori = L$ori
120
    newimg = reverse_rpi_orient(
121
      file = newimg,
122
      convention = ori,
123
      orientation = sorient,
124
      verbose = verbose)
125
  }
126
  return(newimg)
127
}
128
129
130
#' @rdname face_mask
131
#' @export
132
#' @importFrom fslr mni_fname
133
#' @examples \dontrun{
134
#' library(fslr)
135
#' library(extrantsr)
136
#' mri = "~/Desktop/Desktop/scratch/SUBJ0001-01-MPRAGE.nii.gz"
137
#'
138
#' template.file = mni_fname(brain = TRUE)
139
#' tmask = mni_fname(brain = TRUE, mask = TRUE)
140
#'
141
#' template.face_mask_inds = list(50:130, 170:217, 1:15)
142
#' brain = fslbet_robust(mri,
143
#' remove.neck = TRUE,
144
#' remover = "double_remove_neck",
145
#' template.file = template.file,
146
#' template.mask = tmask)
147
#' mask = brain > 0
148
#' img = brain
149
#' template.face_mask = NULL
150
#' verbose = TRUE
151
#' face = mri_face_mask(
152
#'    file = img,
153
#'    mask = mask,
154
#'    template.file = template.file
155
#'    )
156
#' }
157
#'
158
mri_face_mask <- function(
159
  ...,
160
  skull_strip = TRUE,
161
  mask = NULL,
162
  robust = FALSE,
163
  template.file = mni_fname(brain = skull_strip)
164
){
165
166
167
  L = list(...)
168
  L$robust = robust
169
  L$skull_strip = skull_strip
170
  L$mask = mask
171
  L$template.file = template.file
172
173
  if (is.null(mask) & skull_strip) {
174
    func = function(L, arg, opt) {
175
      nL = names(L)
176
      if (!arg %in% nL) {
177
        L[arg] = opt
178
      }
179
      return(L)
180
    }
181
    uthresh = L$uthresh
182
    if (is.null(uthresh)) {
183
      file = L$file
184
      if (is.null(file)) {
185
        file = L[[1]]
186
      }
187
      uthresh = fslr::fslmax(file)
188
      L$uthresh = uthresh
189
    }
190
191
    L = func(L, "presmooth", FALSE)
192
    L = func(L, "remask", FALSE)
193
    L = func(L, "inskull_mesh", FALSE)
194
    L = func(L, "opts", "-v")
195
  }
196
  res = do.call("ct_face_mask", args = L)
197
  return(res)
198
}