Example #1
0
def are_blended_voxels_aligned(blended, main_dr, main_r0,
                               over_arr, over_dr, over_r0):
    """Tests that the over_arr was mixed into blended in the correct
    voxels, given the spacing and offset parameters.
    
    NOTE: It is assumed that the blended array was zero everywhere before
    blending, making any nonzero elements the contribution of over_arr
    """
    main_map = ni_api.AffineTransform.from_start_step('ijk', 'xyz',
                                                      main_r0, main_dr)
    over_map = ni_api.AffineTransform.from_start_step('ijk', 'xyz',
                                                      over_r0, over_dr)
    over_vox_from_main_vox = ni_api.compose(over_map.inverse(), main_map)
    #checking the red component
    main_nz_vox = np.array( blended[...,0].nonzero() ).T
    over_nz_vox = over_vox_from_main_vox(main_nz_vox)
    over_nz_vox = over_nz_vox[(over_nz_vox >= 0).all(axis=-1)]
    max_idx = np.array(over_arr.shape[:3])
    over_nz_vox = over_nz_vox[(over_nz_vox < max_idx).all(axis=-1)].astype('i')
    # check that in fact the nonzero components from the main blended
    # image are the nonzero components from the overlay image..
    # this mask is False at all over_nz_vox
    mask = np.ma.getmask(vu.signal_array_to_masked_vol(
        np.empty(len(over_nz_vox)), over_nz_vox
        ))
    # where the mask is True should be 0 -- well, not so if part of the
    # over array lies outside of the under array. Then there are regions
    # where the over array does not blend!
##     none_outside = not over_arr[...,0][mask].any()

    # where the mask is False should be != 0
    all_inside = over_arr[...,0][np.logical_not(mask)].all()
    return all_inside
Example #2
0
def resample_to_world_grid(img, bbox=None, grid_spacing=None, order=3,
                           axis_permutation=None,
                           **interp_kws):
    cmap_ijk_xyz = img.coordmap.reordered_range(
        xipy_ras
        ).reordered_domain('ijk')
    T = cmap_ijk_xyz.affine
    if grid_spacing is None:
        # find the (i,j,k) voxel sizes, which should be the norm of the columns
        grid_spacing = voxel_size(T)
    if bbox is None:
        # the extent of the rotated image may cover a larger box
        bbox = world_limits(img)

    box_limits = np.diff(bbox).reshape(3)
    
    diag_affine = np.diag(list(grid_spacing) + [1])
    diag_affine[:3,3] = np.asarray(bbox)[:,0]
    if not axis_permutation:
        target_domain = 'ijk'
    else:
        target_domain = [ 'ijk'[ax] for ax in axis_permutation ]
    resamp_affine = ni_api.AffineTransform.from_params(
        target_domain,
        xipy_ras,
        diag_affine
        )
    resamp_affine = resamp_affine.reordered_domain(
        img.coordmap.function_domain.coord_names
        )
    # Doing the mapping this way, we don't have to assume what
    # the input space of the Image is like
    cmap_xyz = img.coordmap.reordered_range(xipy_ras)
    mapping = ni_api.compose(cmap_xyz, img.coordmap.inverse())

    # this is the ijk dim ordering.. how do we permute it to match
    # the input coordinates of the original image?
    new_dims = np.ceil(box_limits/grid_spacing).astype('i')
    dim_ordering = map(lambda x: target_domain.index(x),
                       img.coordmap.function_domain.coord_names)
    new_dims = np.take(new_dims, dim_ordering)
    new_img = resample.resample(img, resamp_affine, mapping.affine,
                                tuple(new_dims), order=order, **interp_kws)

    return new_img
Example #3
0
    def _resample_over_into_main(self):
        i_bad = self.over_cmap.i_bad
        vox_to_vox = ni_api.compose(
            self.over.coordmap.inverse(), self.main.coordmap
            )
        print vox_to_vox.affine
        print self._main_idx.shape
        print self._over_idx.shape
        # this is supposed to be diagonal!!
        mat = vox_to_vox.affine.diagonal()[:3]
        offset = vox_to_vox.affine[:3,-1]
##         self._over_idx = ndimage.affine_transform(
##             self._over_idx, mat, offset,
##             output_shape=self._main_idx.shape,
##             output=self._over_idx.dtype,
##             order=0, cval=i_bad)
        self._over_idx = resize_lookup_array(
            self._main_idx.shape, i_bad, self._over_idx, mat, offset
            )
Example #4
0
def test_rotate2d3():
    # Another way to rotate/transpose the image, similar to
    # test_rotate2d2 and test_rotate2d except the world of the
    # output coordmap are the same as the world of the
    # original image. That is, the data is transposed on disk, but the
    # output coordinates are still 'x,'y' order, not 'y', 'x' order as
    # above

    # this functionality may or may not be used a lot. if data is to
    # be transposed but one wanted to keep the NIFTI order of output
    # coords this would do the trick

    g = AffineTransform.from_params("xy", "ij", np.diag([0.5, 0.7, 1]))
    i = Image(np.ones((100, 80)), g)
    i[50:55, 40:55] = 3.0

    a = np.identity(3)
    g2 = AffineTransform.from_params("xy", "ij", np.array([[0, 0.5, 0], [0.7, 0, 0], [0, 0, 1]]))
    ir = resample(i, g2, a, (80, 100))
    v2v = compose(g.inverse(), g2)
    yield assert_array_almost_equal, np.asarray(ir).T, i
Example #5
0
def resample(image, target, mapping, shape, order=3, **interp_kws):
    """
    Resample an image to a target CoordinateMap with a "world-to-world" mapping
    and spline interpolation of a given order.

    Here, "world-to-world" refers to the fact that mapping should be
    a callable that takes a physical coordinate in "target"
    and gives a physical coordinate in "image". 

    Parameters
    ----------
    image : Image instance that is to be resampled
    target :target CoordinateMap for output image
    mapping : transformation from target.function_range
               to image.coordmap.function_range, i.e. 'world-to-world mapping'
               Can be specified in three ways: a callable, a
               tuple (A, b) representing the mapping y=dot(A,x)+b
               or a representation of this in homogeneous coordinates. 
    shape : shape of output array, in target.function_domain
    order : what order of interpolation to use in `scipy.ndimage`
    interp_kws : keyword arguments for ndimage interpolator routine

    Returns
    -------
    output : Image instance with interpolated data and output.coordmap == target
                  
    """

    if not callable(mapping):
        if type(mapping) is type(()):
            A, b = mapping
            ndimout = b.shape[0]
            ndimin = A.shape[1]
            mapping  = np.zeros((ndimout+1, ndimin+1))
            mapping[:ndimout,:ndimin] = A
            mapping[:ndimout,-1] = b
            mapping[-1,-1] = 1.

     # image world to target world mapping

        TW2IW = AffineTransform(target.function_range, image.coordmap.function_range, mapping)
    else:
        TW2IW = CoordinateMap(mapping, target.function_range, image.coordmap.function_range)

    function_domain = target.function_domain
    function_range = image.coordmap.function_range

    # target voxel to image world mapping
    TV2IW = compose(TW2IW, target)

    # CoordinateMap describing mapping from target voxel to
    # image world coordinates

    if not isinstance(TV2IW, AffineTransform):
        # interpolator evaluates image at values image.coordmap.function_range,
        # i.e. physical coordinates rather than voxel coordinates
        grid = ArrayCoordMap.from_shape(TV2IW, shape)
        interp = ImageInterpolator(image, order=order)
        idata = interp.evaluate(grid.transposed_values, **interp_kws)
        del(interp)
    else:
        TV2IV = compose(image.coordmap.inverse(), TV2IW)
        if isinstance(TV2IV, AffineTransform):
            A, b = affines.to_matrix_vector(TV2IV.affine)
            data = np.asarray(image)
            idata = affine_transform(data, A,
                                     offset=b,
                                     output_shape=shape,
                                     output=data.dtype,
                                     order=order,
                                     **interp_kws)
        else:
            interp = ImageInterpolator(image, order=order)
            grid = ArrayCoordMap.from_shape(TV2IV, shape)
            idata = interp.evaluate(grid.values, **interp_kws)
            del(interp)
            
    return Image(idata, target)