Esempio n. 1
0
def test_applyDeformation_premat():

    src2ref = affine.compose(
        np.random.randint(2, 5, 3),
        np.random.randint(1, 10, 3),
        [0, 0, 0])
    ref2src = affine.invert(src2ref)

    srcdata = np.random.randint(1, 65536, (10, 10, 10))
    refdata = np.random.randint(1, 65536, (10, 10, 10))

    src   = fslimage.Image(srcdata)
    ref   = fslimage.Image(refdata, xform=src2ref)
    field = _affine_field(src, ref, ref2src, 'world', 'world')

    # First try a down-sampled version
    # of the original source image
    altsrc, xf = resample.resample(src, (5, 5, 5), origin='corner')
    altsrc     = fslimage.Image(altsrc, xform=xf, header=src.header)
    expect, xf = resample.resampleToReference(
        altsrc, ref, matrix=src2ref, order=1, mode='nearest')
    premat = affine.concat(src   .getAffine('world', 'voxel'),
                           altsrc.getAffine('voxel', 'world'))
    result = nonlinear.applyDeformation(
        altsrc, field, order=1, mode='nearest', premat=premat)
    assert np.all(np.isclose(expect, result))

    # Now try a down-sampled ROI
    # of the original source image
    altsrc     = roi.roi(src, [(2, 9), (2, 9), (2, 9)])
    altsrc, xf = resample.resample(altsrc, (4, 4, 4))
    altsrc     = fslimage.Image(altsrc, xform=xf, header=src.header)
    expect, xf = resample.resampleToReference(
        altsrc, ref, matrix=src2ref, order=1, mode='nearest')
    premat = affine.concat(src   .getAffine('world', 'voxel'),
                           altsrc.getAffine('voxel', 'world'))
    result = nonlinear.applyDeformation(
        altsrc, field, order=1, mode='nearest', premat=premat)
    assert np.all(np.isclose(expect, result))

    # down-sampled and offset ROI
    # of the original source image
    altsrc     = roi.roi(src, [(-5, 8), (-5, 8), (-5, 8)])
    altsrc, xf = resample.resample(altsrc, (6, 6, 6))
    altsrc     = fslimage.Image(altsrc, xform=xf, header=src.header)
    expect, xf = resample.resampleToReference(
        altsrc, ref, matrix=src2ref, order=1, mode='nearest')
    premat = affine.concat(src   .getAffine('world', 'voxel'),
                           altsrc.getAffine('voxel', 'world'))
    result = nonlinear.applyDeformation(
        altsrc, field, order=1, mode='nearest', premat=premat)
    assert np.all(np.isclose(expect, result))
Esempio n. 2
0
def test_applyDeformation_worldAligned():
    refv2w   = affine.scaleOffsetXform([1, 1, 1], [10,   10,   10])
    fieldv2w = affine.scaleOffsetXform([2, 2, 2], [10.5, 10.5, 10.5])
    src2ref  = refv2w
    ref2src  = affine.invert(src2ref)

    srcdata = np.random.randint(1, 65536, (10, 10, 10))

    src   = fslimage.Image(srcdata)
    ref   = fslimage.Image(srcdata, xform=src2ref)
    field = _affine_field(src, ref, ref2src, 'world', 'world',
                          shape=(5, 5, 5), fv2w=fieldv2w)

    field = nonlinear.DeformationField(
        nonlinear.convertDeformationType(field, 'absolute'),
        header=field.header,
        src=src,
        ref=ref,
        srcSpace='world',
        refSpace='world',
        defType='absolute')

    expect, xf = resample.resampleToReference(
        src, ref, matrix=src2ref, order=1, mode='constant', cval=0)
    result = nonlinear.applyDeformation(
        src, field, order=1, mode='constant', cval=0)

    expect = expect[1:-1, 1:-1, 1:-1]
    result = result[1:-1, 1:-1, 1:-1]

    assert np.all(np.isclose(expect, result))
Esempio n. 3
0
def test_applyDeformation_altref():
    src2ref = affine.compose(
        np.random.randint(2, 5, 3),
        np.random.randint(1, 10, 3),
        np.random.random(3))
    ref2src = affine.invert(src2ref)

    srcdata = np.random.randint(1, 65536, (10, 10, 10))
    refdata = np.random.randint(1, 65536, (10, 10, 10))

    src   = fslimage.Image(srcdata)
    ref   = fslimage.Image(refdata, xform=src2ref)
    field = _affine_field(src, ref, ref2src, 'world', 'world')

    altrefxform = affine.concat(
        src2ref,
        affine.scaleOffsetXform([1, 1, 1], [5, 0, 0]))

    altref = fslimage.Image(refdata, xform=altrefxform)

    expect, xf = resample.resampleToReference(
        src, altref, matrix=src2ref, order=1, mode='constant', cval=0)
    result = nonlinear.applyDeformation(
        src, field, ref=altref, order=1, mode='constant', cval=0)

    # boundary voxels can get truncated
    # (4 is the altref-ref overlap boundary)
    expect[4, :, :] = 0
    result[4, :, :] = 0
    expect = expect[1:-1, 1:-1, 1:-1]
    result = result[1:-1, 1:-1, 1:-1]

    assert np.all(np.isclose(expect, result))
Esempio n. 4
0
def test_nonlinear(seed):
    with tempdir.tempdir():

        src2ref = _random_affine()
        ref2src = affine.invert(src2ref)
        src = _random_image(np.eye(4))
        ref = _random_image(src2ref)
        field = _affine_field(src, ref, ref2src, 'world', 'world')

        x5.writeNonLinearX5('xform.x5', field)

        src.save('src')

        fsl_apply_x5.main('src xform.x5 out'.split())

        result = fslimage.Image('out')
        expect = resample.resampleToReference(src,
                                              ref,
                                              matrix=src2ref,
                                              smooth=False)[0]

        assert result.sameSpace(ref)

        # We might get truncation on the edges
        result = result.data[1:-1, 1:-1, 1:-1]
        expect = expect[1:-1, 1:-1, 1:-1]

        tol = dict(atol=1e-3, rtol=1e-3)
        assert np.all(np.isclose(result, expect, **tol))
Esempio n. 5
0
def test_linear_altsrc(seed):
    with tempdir.tempdir():

        src2ref = _random_affine()
        src = _random_image(np.eye(4), (20, 20, 20))
        ref = _random_image(src2ref)

        x5.writeLinearX5('xform.x5', src2ref, src, ref)

        src.save('src')
        ref.save('ref')

        srclo, xf = resample.resample(src, (10, 10, 10))
        srclo = fslimage.Image(srclo, xform=xf)
        srchi, xf = resample.resample(src, (40, 40, 40))
        srchi = fslimage.Image(srchi, xform=xf)

        srcoff = roi.roi(src, [(-10, 10), (-10, 10), (-10, 10)])

        srclo.save('srclo')
        srchi.save('srchi')
        srcoff.save('srcoff')

        fsl_apply_x5.main('src    xform.x5 out'.split())
        fsl_apply_x5.main('srclo  xform.x5 outlo'.split())
        fsl_apply_x5.main('srchi  xform.x5 outhi'.split())
        fsl_apply_x5.main('srcoff xform.x5 outoff'.split())

        out = fslimage.Image('out')
        outlo = fslimage.Image('outlo')
        outhi = fslimage.Image('outhi')
        outoff = fslimage.Image('outoff')

        exp = resample.resampleToReference(src, ref, matrix=src2ref)[0]
        explo = resample.resampleToReference(srclo, ref, matrix=src2ref)[0]
        exphi = resample.resampleToReference(srchi, ref, matrix=src2ref)[0]
        expoff = resample.resampleToReference(srcoff, ref, matrix=src2ref)[0]

        assert out.sameSpace(ref)
        assert outlo.sameSpace(ref)
        assert outhi.sameSpace(ref)
        assert outoff.sameSpace(ref)

        assert np.all(np.isclose(out.data, exp))
        assert np.all(np.isclose(outlo.data, explo))
        assert np.all(np.isclose(outhi.data, exphi))
        assert np.all(np.isclose(outoff.data, expoff))
Esempio n. 6
0
def test_resampleToReference3():

    # Test resampling image to ref
    # with mismatched dimensions
    imgdata = np.random.randint(0, 65536, (5, 5, 5))
    img = fslimage.Image(imgdata,
                         xform=affine.scaleOffsetXform((2, 2, 2),
                                                       (0.5, 0.5, 0.5)))

    # reference/expected data when
    # resampled to ref (using nn interp).
    # Same as image, upsampled by a
    # factor of 2
    refdata = np.repeat(np.repeat(np.repeat(imgdata, 2, 0), 2, 1), 2, 2)
    refdata = np.array([refdata] * 8).transpose((1, 2, 3, 0))
    ref = fslimage.Image(refdata)

    # We should be able to use a 4D reference
    resampled, xform = resample.resampleToReference(img,
                                                    ref,
                                                    order=0,
                                                    mode='nearest')
    assert np.all(resampled == ref.data[..., 0])

    # If resampling a 4D image with a 3D reference,
    # the fourth dimension should be passed through
    resampled, xform = resample.resampleToReference(ref,
                                                    img,
                                                    order=0,
                                                    mode='nearest')
    exp = np.array([imgdata] * 8).transpose((1, 2, 3, 0))
    assert np.all(resampled == exp)

    # When resampling 4D to 4D, only the
    # first 3 dimensions should be resampled
    imgdata = np.array([imgdata] * 15).transpose((1, 2, 3, 0))
    img = fslimage.Image(imgdata, xform=img.voxToWorldMat)
    exp = np.array([refdata[..., 0]] * 15).transpose((1, 2, 3, 0))
    resampled, xform = resample.resampleToReference(img,
                                                    ref,
                                                    order=0,
                                                    mode='nearest')
    assert np.all(resampled == exp)
Esempio n. 7
0
    def __resample(self):
        """Called when this ``ResampleAction`` is invoked. Shows a
        ``ResampleDialog``, and then resamples the currently selected overlay.
        """

        ovl = self.displayCtx.getSelectedOverlay()
        opts = self.displayCtx.getOpts(ovl)

        def refCandidate(o):
            return (isinstance(o, fslimage.Nifti) and (o is not ovl)
                    and not o.sameSpace(ovl))

        refs = [o for o in self.overlayList if refCandidate(o)]
        dlg = ResampleDialog(self.__frame,
                             title=ovl.name,
                             shape=ovl.shape,
                             pixdim=ovl.pixdim,
                             refs=refs)

        if dlg.ShowModal() != wx.ID_OK:
            return

        newShape = dlg.GetVoxels()
        interp = dlg.GetInterpolation()
        origin = dlg.GetOrigin()
        dtype = dlg.GetDataType()
        smoothing = dlg.GetSmoothing()
        ref = dlg.GetReference()
        allvols = dlg.GetAllVolumes()
        interp = {'nearest': 0, 'linear': 1, 'cubic': 3}[interp]
        name = '{}_resampled'.format(ovl.name)

        if allvols or ovl.ndim == 3: slc = None
        else: slc = opts.index()

        if allvols and ovl.ndim > 3:
            newShape = list(newShape) + list(ovl.shape[3:])

        kwargs = dict(sliceobj=slc,
                      dtype=dtype,
                      order=interp,
                      origin=origin,
                      smooth=smoothing)

        if ref is not None:
            resampled, xform = resample.resampleToReference(ovl, ref, **kwargs)
        else:
            resampled, xform = resample.resample(ovl, newShape, **kwargs)

        resampled = fslimage.Image(resampled,
                                   xform=xform,
                                   header=ovl.header,
                                   name=name)

        self.overlayList.append(resampled)
Esempio n. 8
0
def test_resampleToReference4():

    # the image and ref are out of
    # alignment, but this affine
    # will bring them into alignment
    img2ref = affine.scaleOffsetXform([2, 2, 2], [10, 10, 10])

    imgdata = np.random.randint(0, 65536, (5, 5, 5))
    refdata = np.zeros((5, 5, 5))
    img = fslimage.Image(imgdata)
    ref = fslimage.Image(refdata, xform=img2ref)

    # Without the affine, the image
    # will be out of the FOV of the
    # reference
    resampled, xform = resample.resampleToReference(img, ref)
    assert np.all(resampled == 0)

    # But applying the affine will
    # cause them to overlap
    # perfectly in world coordinates
    resampled, xform = resample.resampleToReference(img, ref, matrix=img2ref)
    assert np.all(resampled == imgdata)
Esempio n. 9
0
def test_resampleToReference1():

    # Basic test - output has same
    # dimensions/space as reference
    for i in range(25):

        ishape = np.random.randint(5, 50, 3)
        rshape = np.random.randint(5, 50, 3)
        iv2w = random_affine()
        rv2w = random_affine()
        img = fslimage.Image(make_random_image(dims=ishape, xform=iv2w))
        ref = fslimage.Image(make_random_image(dims=rshape, xform=rv2w))
        res = resample.resampleToReference(img, ref)
        res = fslimage.Image(res[0], header=ref.header)

        assert res.sameSpace(ref)
Esempio n. 10
0
def test_resampleToReference2():

    # More specific test - output
    # data gets transformed correctly
    # into reference space
    img = np.zeros((5, 5, 5), dtype=float)
    img[1, 1, 1] = 1
    img = fslimage.Image(img)

    refv2w = affine.scaleOffsetXform([1, 1, 1], [-1, -1, -1])
    ref = np.zeros((5, 5, 5), dtype=float)
    ref = fslimage.Image(ref, xform=refv2w)
    res = resample.resampleToReference(img, ref, order=0)

    exp = np.zeros((5, 5, 5), dtype=float)
    exp[2, 2, 2] = 1

    assert np.all(np.isclose(res[0], exp))
Esempio n. 11
0
def test_linear(seed):
    with tempdir.tempdir():

        src2ref = _random_affine()
        src = _random_image(np.eye(4))
        ref = _random_image(src2ref)

        x5.writeLinearX5('xform.x5', src2ref, src, ref)

        src.save('src')
        ref.save('ref')

        fsl_apply_x5.main('src xform.x5 out'.split())

        result = fslimage.Image('out')
        expect = resample.resampleToReference(src, ref, matrix=src2ref)[0]

        assert result.sameSpace(ref)
        assert np.all(np.isclose(result.data, expect))
Esempio n. 12
0
def applyLinear(args):
    """Applies a linear X5 transformation file to the input.

    :arg args: ``argparse.Namespace`` object
    :returns:  The transformed input as an :class:`.Image` object
    """

    input           = args.input
    xform, src, ref = x5.readLinearX5(args.xform)

    if args.ref is not None:
        ref = args.ref

    res, xform = resample.resampleToReference(input,
                                              ref,
                                              matrix=xform,
                                              order=args.interp)

    return fslimage.Image(res, xform=xform, header=ref.header)
Esempio n. 13
0
def test_applyDeformation():

    src2ref = affine.compose(np.random.randint(2, 5, 3),
                             np.random.randint(1, 10, 3), np.random.random(3))
    ref2src = affine.invert(src2ref)

    srcdata = np.random.randint(1, 65536, (10, 10, 10))
    refdata = np.random.randint(1, 65536, (10, 10, 10))

    src = fslimage.Image(srcdata)
    ref = fslimage.Image(refdata, xform=src2ref)
    field = _affine_field(src, ref, ref2src, 'world', 'world')

    expect, xf = resample.resampleToReference(src,
                                              ref,
                                              matrix=src2ref,
                                              order=1,
                                              mode='nearest')
    result = nonlinear.applyDeformation(src, field, order=1, mode='nearest')

    assert np.all(np.isclose(expect, result))
Esempio n. 14
0
def applyDeformation(image,
                     field,
                     ref=None,
                     order=1,
                     mode=None,
                     cval=None,
                     premat=None):
    """Applies a :class:`DeformationField` to an :class:`.Image`.

    The image is transformed into the space of the field's reference image
    space. See the ``scipy.ndimage.interpolation.map_coordinates`` function
    for details on the ``order``, ``mode`` and ``cval`` options.

    If an alternate reference image is provided via the ``ref`` argument,
    the deformation field is resampled into its space, and then applied to
    the input image. It is therefore assumed that an alternate ``ref`` is
    aligned in world coordinates with the field's actual reference image.

    :arg image:  :class:`.Image` to be transformed

    :arg field:  :class:`DeformationField` to use

    :arg ref:    Alternate reference image - if not provided, ``field.ref``
                 is used

    :arg order:  Spline interpolation order, passed through to the
                 ``scipy.ndimage.affine_transform`` function - ``0``
                 corresponds to nearest neighbour interpolation, ``1``
                 (the default) to linear interpolation, and ``3`` to
                 cubic interpolation.

    :arg mode:   How to handle regions which are outside of the image FOV.
                 Defaults to `''nearest'``.

    :arg cval:   Constant value to use when ``mode='constant'``.

    :arg premat: Optional affine transform which can be used if ``image`` is
                 not in the same space as ``field.src``. Assumed to transform
                 from ``image`` **voxel** coordinates into ``field.src``
                 **voxel** coordinates.

    :return:     ``numpy.array`` containing the transformed image data.
    """

    if order is None: order = 1
    if mode is None: mode = 'nearest'
    if cval is None: cval = 0
    if ref is None: ref = field.ref

    # We need the field to contain
    # absolute source image voxel
    # coordinates
    field = convertDeformationSpace(field, 'voxel', 'voxel')
    if field.deformationType != 'absolute':
        field = DeformationField(convertDeformationType(field, 'absolute'),
                                 header=field.header,
                                 src=field.src,
                                 ref=field.ref,
                                 srcSpace='voxel',
                                 refSpace='voxel',
                                 defType='absolute')

    # If the field is not voxel-aligned
    # to the reference, we need to
    # resample the field itself into the
    # reference image space (assumed to
    # be world-aligned). If field and ref
    # are not not world  aligned, regions
    # of the field outside of the
    # reference image space will contain
    # -1s, so will be detected as out of
    # bounds by map_coordinates below.
    #
    # This will potentially result in
    # truncation at the field boundaries,
    # but there's nothing we can do about
    # that.
    src = field.src

    if not field.sameSpace(ref):
        field = resample.resampleToReference(field,
                                             ref,
                                             order=order,
                                             mode='constant',
                                             cval=-1)[0]
    else:
        field = field.data

    # If the input image is in a
    # different space to the field
    # source space, we need to
    # adjust the resampling matrix.
    # We assume world-world alignment
    # between the original source
    # and the image to be resampled
    if (premat is not None) or (not image.sameSpace(src)):
        if premat is None:
            premat = affine.concat(image.getAffine('world', 'voxel'),
                                   src.getAffine('voxel', 'world'))
        else:
            premat = affine.invert(premat)
        shape = field.shape
        field = field.reshape((-1, 3))
        field = affine.transform(field, premat)
        field = field.reshape(shape)

    field = field.transpose((3, 0, 1, 2))
    return ndinterp.map_coordinates(image.data,
                                    field,
                                    order=order,
                                    mode=mode,
                                    cval=cval)
Esempio n. 15
0
def test_nonlinear_altsrc(seed):
    with tempdir.tempdir():

        src2ref = _random_affine()
        ref2src = affine.invert(src2ref)
        src = _random_image(np.eye(4), (20, 20, 20))
        ref = _random_image(src2ref, (20, 20, 20))

        field = _affine_field(src, ref, ref2src, 'world', 'world')

        x5.writeNonLinearX5('xform.x5', field)

        src.save('src')
        ref.save('ref')

        # use origin=corner so that the
        # resampled variants are exactly
        # aligned in the world coordinate
        # system
        srclo, xf = resample.resample(src, (10, 10, 10),
                                      origin='corner',
                                      smooth=False)
        srclo = fslimage.Image(srclo, xform=xf)
        srchi, xf = resample.resample(src, (40, 40, 40),
                                      origin='corner',
                                      smooth=False)
        srchi = fslimage.Image(srchi, xform=xf)

        srcoff = roi.roi(src, [(-10, 10), (-10, 10), (-10, 10)])

        srclo.save('srclo')
        srchi.save('srchi')
        srcoff.save('srcoff')

        fsl_apply_x5.main('src    xform.x5 out'.split())
        fsl_apply_x5.main('srclo  xform.x5 outlo'.split())
        fsl_apply_x5.main('srchi  xform.x5 outhi'.split())
        fsl_apply_x5.main('srcoff xform.x5 outoff'.split())

        out = fslimage.Image('out')
        outlo = fslimage.Image('outlo')
        outhi = fslimage.Image('outhi')
        outoff = fslimage.Image('outoff')

        exp, x1 = resample.resampleToReference(src,
                                               ref,
                                               matrix=src2ref,
                                               mode='constant',
                                               smooth=False)
        explo, x2 = resample.resampleToReference(srclo,
                                                 ref,
                                                 matrix=src2ref,
                                                 mode='constant',
                                                 smooth=False)
        exphi, x3 = resample.resampleToReference(srchi,
                                                 ref,
                                                 matrix=src2ref,
                                                 mode='constant',
                                                 smooth=False)
        expoff, x4 = resample.resampleToReference(srcoff,
                                                  ref,
                                                  matrix=src2ref,
                                                  mode='constant',
                                                  smooth=False)

        assert out.sameSpace(ref)
        assert outlo.sameSpace(ref)
        assert outhi.sameSpace(ref)
        assert outoff.sameSpace(ref)

        # We get boundary cropping,
        # so ignore edge slices
        out = out.data[1:-1, 1:-1, 1:-1]
        outlo = outlo.data[1:-1, 1:-1, 1:-1]
        outhi = outhi.data[1:-1, 1:-1, 1:-1]
        outoff = outoff.data[:9, :9, :9]
        exp = exp[1:-1, 1:-1, 1:-1]
        explo = explo[1:-1, 1:-1, 1:-1]
        exphi = exphi[1:-1, 1:-1, 1:-1]
        expoff = expoff[:9, :9, :9]

        tol = dict(atol=1e-3, rtol=1e-3)

        assert np.all(np.isclose(out, exp, **tol))
        assert np.all(np.isclose(outlo, explo, **tol))
        assert np.all(np.isclose(outhi, exphi, **tol))
        assert np.all(np.isclose(outoff, expoff, **tol))