code: def __make_mask_3d(self, image):
      assert image.ndim == 3
      image_shape = image.shape
      image = image.reshape(-1)
      mask = np.zeros_like(image, dtype=np.bool)
      thr = self.threshold
      if self.type_str == "threshold_plus":
          mask[image > thr] = True
      elif self.type_str == "threshold_minus":
          mask[image < thr] = True
      elif self.type_str == "otsu_plus":
          thr = otsu_threshold(image) if np.any(image) else thr
          mask[image > thr] = True
      elif self.type_str == "otsu_minus":
          thr = otsu_threshold(image) if np.any(image) else thr
          mask[image < thr] = True
      elif self.type_str == "mean_plus":
          thr = np.mean(image)
          mask[image > thr] = True
      mask = mask.reshape(image_shape)
      mask = ndimg.binary_dilation(mask, iterations=2)
      mask = fill_holes(mask)
      # foreground should not be empty
      assert np.any(mask == True), (
          "no foreground based on the specified combination parameters, "
          "please change choose another `mask_type` or double-check all "
          "input images"
      )
      return mask
  
file_path: NiftyNet/niftynet/layer/binary_masking.py
imports: from __future__ import absolute_import, print_function, division
  import numpy
  import scipy.ndimage
  from scipy.ndimage.morphology import binary_fill_holes
  from niftynet.layer.base_layer import Layer
  from niftynet.utilities.util_common import look_up_operations
  from niftynet.utilities.util_common import otsu_threshold
label_desc: Use image node_id 2 for calling the BinaryMaskingLayer obj's underlying member method code with example usage: obj.__make_mask_3d(image) and returns: mask