docstr: ScaleSpace.
  
  Computes the Scale Space representation of an image. The scale space is
  simply a list of images produced by smoothing the input image with a
  Gaussian kernel with increasing smoothing parameter. If the image's
  voxels are isotropic, the smoothing will be the same along all
  directions: at level L = 0, 1, ..., the sigma is given by
  $s * ( 2^L - 1 )$.
  If the voxel dimensions are not isotropic, then the smoothing is
  weaker along low resolution directions.
  
  Parameters
  ----------
  image : array, shape (r,c) or (s, r, c) where s is the number of
      slices, r is the number of rows and c is the number of columns of
      the input image.
  num_levels : int
      the desired number of levels (resolutions) of the scale space
  image_grid2world : array, shape (dim + 1, dim + 1), optional
      the grid-to-space transform of the image grid. The default is
      the identity matrix
  input_spacing : array, shape (dim,), optional
      the spacing (voxel size) between voxels in physical space. The
      default is 1.0 along all axes
  sigma_factor : float, optional
      the smoothing factor to be used in the construction of the scale
      space. The default is 0.2
  mask0 : Boolean, optional
      if True, all smoothed images will be zero at all voxels that are
      zero in the input image. The default is False.
docstr_tok: ["ScaleSpace",".","Computes","the","Scale","Space","representation","of","an","image",".","The","scale","space","is","simply","a","list","of","images","produced","by","smoothing","the","input","image","with","a","Gaussian","kernel","with","increasing","smoothing","parameter",".","If","the","image's","voxels","are","isotropic",",","the","smoothing","will","be","the","same","along","all","directions",":","at","level","L","=","0",",","1",",","...",",","the","sigma","is","given","by","$","s","*","(","2^L","-","1",")","$",".","If","the","voxel","dimensions","are","not","isotropic",",","then","the","smoothing","is","weaker","along","low","resolution","directions",".","Parameters","--","--","--","--","--","image",":","array",",","shape","(","r",",","c",")","or","(","s",",","r",",","c",")","where","s","is","the","number","of","slices",",","r","is","the","number","of","rows","and","c","is","the","number","of","columns","of","the","input","image",".","num_levels",":","int","the","desired","number","of","levels","(","resolutions",")","of","the","scale","space","image_grid2world",":","array",",","shape","(","dim","+","1",",","dim","+","1",")",",","optional","the","grid-to-space","transform","of","the","image","grid",".","The","default","is","the","identity","matrix","input_spacing",":","array",",","shape","(","dim",",",")",",","optional","the","spacing","(","voxel","size",")","between","voxels","in","physical","space",".","The","default","is","1.0","along","all","axes","sigma_factor",":","float",",","optional","the","smoothing","factor","to","be","used","in","the","construction","of","the","scale","space",".","The","default","is","0.2","mask0",":","Boolean",",","optional","if","True",",","all","smoothed","images","will","be","zero","at","all","voxels","that","are","zero","in","the","input","image",".","The","default","is","False","."]
code: def __init__(
      self,
      image,
      num_levels,
      image_grid2world=None,
      input_spacing=None,
      sigma_factor=0.2,
      mask0=False,
  ):
      """ScaleSpace.
  
      Computes the Scale Space representation of an image. The scale space is
      simply a list of images produced by smoothing the input image with a
      Gaussian kernel with increasing smoothing parameter. If the image's
      voxels are isotropic, the smoothing will be the same along all
      directions: at level L = 0, 1, ..., the sigma is given by
      $s * ( 2^L - 1 )$.
      If the voxel dimensions are not isotropic, then the smoothing is
      weaker along low resolution directions.
  
      Parameters
      ----------
      image : array, shape (r,c) or (s, r, c) where s is the number of
          slices, r is the number of rows and c is the number of columns of
          the input image.
      num_levels : int
          the desired number of levels (resolutions) of the scale space
      image_grid2world : array, shape (dim + 1, dim + 1), optional
          the grid-to-space transform of the image grid. The default is
          the identity matrix
      input_spacing : array, shape (dim,), optional
          the spacing (voxel size) between voxels in physical space. The
          default is 1.0 along all axes
      sigma_factor : float, optional
          the smoothing factor to be used in the construction of the scale
          space. The default is 0.2
      mask0 : Boolean, optional
          if True, all smoothed images will be zero at all voxels that are
          zero in the input image. The default is False.
  
      """
      self.dim = len(image.shape)
      self.num_levels = num_levels
      input_size = np.array(image.shape)
      if mask0:
          mask = np.asarray(image > 0, dtype=np.int32)
  
      # Normalize input image to [0,1]
      img = (image - np.min(image)) / (np.max(image) - np.min(image))
      if mask0:
          img *= mask
  
      # The properties are saved in separate lists. Insert input image
      # properties at the first level of the scale space
      self.images = [img.astype(floating)]
      self.domain_shapes = [input_size.astype(np.int32)]
      if input_spacing is None:
          input_spacing = np.ones((self.dim,), dtype=np.int32)
      self.spacings = [input_spacing]
      self.scalings = [np.ones(self.dim)]
      self.affines = [image_grid2world]
      self.sigmas = [np.zeros(self.dim)]
  
      if image_grid2world is not None:
          self.affine_invs = [npl.inv(image_grid2world)]
      else:
          self.affine_invs = [None]
  
      # Compute the rest of the levels
      min_spacing = np.min(input_spacing)
      for i in range(1, num_levels):
          scaling_factor = 2**i
          # Note: the minimum below is present in ANTS to prevent the scaling
          # from being too large (making the sub-sampled image to be too
          # small) this makes the sub-sampled image at least 32 voxels at
          # each direction it is risky to make this decision based on image
          # size, though (we need to investigate more the effect of this)
  
          # scaling = np.minimum(scaling_factor * min_spacing /input_spacing,
          #                     input_size / 32)
  
          scaling = scaling_factor * min_spacing / input_spacing
          output_spacing = input_spacing * scaling
          extended = np.append(scaling, [1])
          if image_grid2world is not None:
              affine = image_grid2world.dot(np.diag(extended))
          else:
              affine = np.diag(extended)
          output_size = (
              input_size * (input_spacing / output_spacing) + 0.5
          )
          output_size = output_size.astype(np.int32)
          sigmas = sigma_factor * (output_spacing / input_spacing - 1.0)
  
          # Filter along each direction with the appropriate sigma
          filtered = gaussian_filter(image, sigmas)
          filtered = (filtered - np.min(filtered)) / (
              np.max(filtered) - np.min(filtered)
          )
          if mask0:
              filtered *= mask
  
          # Add current level to the scale space
          self.images.append(filtered.astype(floating))
          self.domain_shapes.append(output_size)
          self.spacings.append(output_spacing)
          self.scalings.append(scaling)
          self.affines.append(affine)
          self.affine_invs.append(npl.inv(affine))
          self.sigmas.append(sigmas)
  
imports: import logging
  from dipy.align import floating
  import numpy
  import numpy.linalg
  from scipy.ndimage import gaussian_filter
label_desc: Use image node_id 1 to create a new ScaleSpace object  with example: obj = ScaleSpace(image, num_levels, image_grid2world, input_spacing, sigma_factor, mask0)