def __init__(self, image, bbox=None, mask=False, grid_spacing=None, interpolation_order=3): """ Creates a new SampledVolumeSlicer Parameters ---------- image : a NIPY Image The image to slice bbox : iterable (optional) The {x,y,z} limits of the enrounding volume box. If None, then slices planes in the natural box of the image. This argument is useful for overlaying an image onto another image's volume box mask : bool or ndarray (optional) A binary mask, with same shape as image, with unmasked points marked as True (opposite of MaskedArray convention) grid_spacing : iterable (optional) New grid spacing for the sliced planes. If None, then the natural voxel spacing is used. """ xyz_image = ni_api.Image( np.asarray(image), image.coordmap.reordered_range(xipy_ras) ) ## reorder_output(image.coordmap, 'xyz')) self.coordmap = xyz_image.coordmap self.raw_image = xyz_image nvox = np.product(self.raw_image.shape) # if the volume array of the map is more than 100mb in memory, # better use a memmap self._use_mmap = nvox*8 > 100e6 self.interpolator = ImageInterpolator(xyz_image, order=interpolation_order, use_mmap=self._use_mmap) ## if mask is True: ## mask = compute_mask(np.asarray(self.raw_image), cc=0, m=.1, M=.999) if type(mask) is np.ndarray: self.update_mask(mask, positive_mask=True) else: self._masking = False self.raw_mask = None if grid_spacing is None: self.grid_spacing = list(vu.voxel_size(image.affine)) else: self.grid_spacing = grid_spacing if bbox is None: self._nominal_bbox = vu.world_limits(xyz_image) else: self._nominal_bbox = bbox # defines {x,y,z}shape and {x,y,z}grid self._define_grids()
def __init__(self, image, bbox=None, mask=False, grid_spacing=None, spatial_axes=None, **interp_kws): """ Creates a new ResampledVolumeSlicer Parameters ---------- image : a NIPY Image The image to slice bbox : iterable (optional) The {x,y,z} limits of the enrounding volume box. If None, then slices planes in the natural box of the image. This argument is useful for overlaying an image onto another image's volume box mask : bool or ndarray (optional) A binary mask, with same shape as image, with unmasked points marked as True (opposite of MaskedArray convention) grid_spacing : sequence (optional) New grid spacing for the sliced planes. If None, then the natural voxel spacing is used. spatial_axes : sequence (optional) Normally the image will not be resampled as long as there is a one-to-one correspondence from array axes to spatial axes. However, a desired correspondence can be specified here. List in 'x, y, z' order. interp_kws : dict Keyword args for the interpolating machinery.. eg: * order -- spline order * mode -- Points outside the boundaries of the input are filled according to the given mode ('constant', 'nearest', 'reflect' or 'wrap'). Default is 'constant'. * cval -- fill value if mode is 'constant' """ # XYZ: NEED TO BREAK API HERE FOR MASKED ARRAY xyz_image = ni_api.Image( image._data, image.coordmap.reordered_range(xipy_ras) ) native_spacing = vu.voxel_size(xyz_image.affine) zoom_grid = grid_spacing is not None and \ (np.array(grid_spacing) != native_spacing).any() # if no special instructions and image is somewhat aligned, # don't bother with rotations aligned = vu.is_spatially_aligned(image.coordmap) and not zoom_grid self.__resamp_kws = dict() if aligned: # if aligned, double check that it is also aligned with # spatial_axes (if present) axes = vu.find_spatial_correspondence(image.coordmap) if spatial_axes and axes != spatial_axes: # XYZ: IF ARRAY IS ALIGNED IN SOME ORIENTATION, COULD # RE-ALIGN WITH "spatial_axes" WITH A SIMPLE TRANSFORM aligned = False interp_kws['order'] = 0 else: world_image = xyz_image if not aligned: print 'resampling entire Image volume' self.__resamp_kws.update(interp_kws) self.__resamp_kws.update( dict(grid_spacing=grid_spacing, axis_permutation=spatial_axes) ) world_image = vu.resample_to_world_grid( image, **self.__resamp_kws ) self.coordmap = world_image.coordmap self.image_arr = np.asanyarray(world_image) self.grid_spacing = vu.voxel_size(world_image.affine) # take down the final bounding box; this will define the # field of the overlay plot self.bbox = vu.world_limits(world_image) # now find the logical axis to array axis mapping self._ax_lookup = vu.spatial_axes_lookup(self.coordmap) w_shape = world_image.shape # these planes are shaped as if the image_arr were # sliced along a given axis self.null_planes = [np.ma.masked_all((w_shape[0], w_shape[1]),'B'), np.ma.masked_all((w_shape[0], w_shape[2]),'B'), np.ma.masked_all((w_shape[1], w_shape[2]),'B')] # finally, update mask if necessary mask = np.ma.getmask(image._data) if mask is not np.ma.nomask: mask = ni_api.Image(mask, image.coordmap) self.update_mask(mask, positive_mask=False)