Example #1
0
    def _udpate_obytes(self):
        if self.over==None:
            self._over_idx = np.array([], np.int32)
            self._adapt_to_slicer()
            return
        # define the axes order to resample onto
        if self.vtk_order:
            ax_order = vtk_ax_order
        elif self.main:
            ax_order = vu.find_spatial_correspondence(self.main.coordmap)
        else:
            ax_order = None
        if type(self.over)==ni_api.Image:
            over = ResampledIndexVolumeSlicer(
                self.over, norm=self.over_norm,
                spatial_axes=ax_order,
                order=self.over_spline_order
                )
            # go ahead and be re-entrant
            self.over = over
            return
        if type(self.over) != ResampledIndexVolumeSlicer:
            raise ValueError('over image should be a NIPY Image, or '\
                             'a ResampledIndexVolumeSlicer')
        
        # self.over is definitely the right type, but is it aligned?
        if ax_order:
            axes = vu.find_spatial_correspondence(self.over.coordmap)
            if axes != ax_order:
                print 'Re-mapping because original mapping is not aligned '\
                'to the main image'
                # re-make a NIPY Image, and send it back!
                ni_image = ni_api.Image(
                    self.over.image_arr, self.over.coordmap
                    )
                self.over = ResampledIndexVolumeSlicer(
                    ni_image, norm=False, spatial_axes=ax_order,
                    order=self.over_spline_order
                    )
                return
            
        temp_idx = self.over.image_arr

        if not self.main:
            self._over_idx = temp_idx
            self._adapt_to_slicer()
        else:
            self.trait_setq(_over_idx=temp_idx)
            self._resample_over_into_main()
Example #2
0
    def _update_mbytes(self):
        """Makes a ResampledIndexVolumeSlicer out of the argument, and
        enforces the spatial-to-array correspondence set up in the
        transpose mode.
        """
        if self.main==None:
            # "unload" main image
            self._main_idx = np.array([], np.int32)
            # trigger remapping of over index
            self.over = self.over
            return
        if isinstance(self.main, ni_api.Image):
            img = self.main
            spatial_axes = vtk_ax_order if self.vtk_order else None
            main = ResampledIndexVolumeSlicer(
                img, norm=self.main_norm,
                spatial_axes=spatial_axes,
                order=self.main_spline_order
                )
            # go ahead and be re-entrant
            self.main = main
            return
        if not isinstance(self.main, ResampledIndexVolumeSlicer):
            raise ValueError('main image should be a NIPY Image, or '\
                             'a ResampledIndexVolumeSlicer')
        # self.main is definitely the right type, but is it aligned?
        if self.vtk_order:
            # with VTK order, x,y,z must be aligned with k, j, i
            axes = vu.find_spatial_correspondence(self.main.coordmap)
            if axes != vtk_ax_order:
                # re-make a NIPY Image, and send it back!
                ni_image = ni_api.Image(
                    self.main.image_arr, self.main.coordmap
                    )
                self.main = ni_image
                return
            

        if len(self._over_idx) and \
               self.main.image_arr.shape != self._over_idx.shape:
            # in case anything is watching main_rgba, (which will change with
            # this update), temporarily set over_idx to an empty array so that
            # the blending is valid
            over_img = self.over
            self.over = None
            self._main_idx = self.main.image_arr
            # send the over image back through its vetting process
            self.over = over_img
        else:
            self._main_idx = self.main.image_arr
            # remap the over image (??)
            self.over = self.over
        self._adapt_to_slicer()
Example #3
0
    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)