Example #1
0
def test_rmsdev():

    t1 = np.eye(4)
    t2 = affine.scaleOffsetXform([1, 1, 1], [2, 0, 0])

    assert np.isclose(affine.rmsdev(t1, t2), 2)
    assert np.isclose(affine.rmsdev(t1, t2, R=2), 2)
    assert np.isclose(affine.rmsdev(t1, t2, R=2, xc=(1, 1, 1)), 2)

    t1 = np.eye(3)
    lastdist = 0

    for i in range(1, 11):
        rot = np.pi * i / 10.0
        t2 = affine.axisAnglesToRotMat(rot, 0, 0)
        result = affine.rmsdev(t1, t2)

        assert result > lastdist

        lastdist = result

    for i in range(11, 20):
        rot = np.pi * i / 10.0
        t2 = affine.axisAnglesToRotMat(rot, 0, 0)
        result = affine.rmsdev(t1, t2)

        assert result < lastdist

        lastdist = result
Example #2
0
    def doMovieUpdate(self, overlay, opts):
        """Overrides :meth:`.CanvasPanel.doMovieUpdate`. For x/y/z axis
        movies, the scene is rotated. Otherwise (for time) the ``CanvasPanel``
        implementation is called.
        """

        if self.movieAxis >= 3:
            return canvaspanel.CanvasPanel.doMovieUpdate(self, overlay, opts)
        else:

            canvas = self.__canvas
            currot = canvas.opts.rotation
            rate = float(self.movieRate)
            rateMin = self.getAttribute('movieRate', 'minval')
            rateMax = self.getAttribute('movieRate', 'maxval')
            rate = 0.1 + 0.9 * (rate - rateMin) / (rateMax - rateMin)
            rate = rate * np.pi / 10

            rots = [0, 0, 0]
            rots[self.movieAxis] = rate

            xform = affine.axisAnglesToRotMat(*rots)
            xform = affine.concat(xform, currot)

            canvas.opts.rotation = xform
            return np.copy(xform)
Example #3
0
    def lightPos(self):
        """Takes the values of :attr:`.Scene3DOpts.lightPos` and
        :attr:`.Scene3DOpts.lightDistance`, and converts it to a position in
        the display coordinate system. The ``Scene3DOpts.lightPos`` property
        contains rotations about the centre of the display bounding box,
        and the :attr:`.Scene3DOpts.lightDistance` property specifies the
        distance of the light from the bounding box centre.
        """
        b = self.__displayCtx.bounds
        centre = np.array([
            b.xlo + 0.5 * (b.xhi - b.xlo), b.ylo + 0.5 * (b.yhi - b.ylo),
            b.zlo + 0.5 * (b.zhi - b.zlo)
        ])

        yaw, pitch, roll = self.opts.lightPos
        distance = self.opts.lightDistance
        yaw = yaw * np.pi / 180
        pitch = pitch * np.pi / 180
        roll = roll * np.pi / 180

        rotmat = affine.axisAnglesToRotMat(pitch, roll, yaw)
        xform = affine.compose([1, 1, 1], [0, 0, 0], rotmat, origin=centre)

        lightPos = centre + [0, 0, distance * b.zlen]
        lightPos = affine.transform(lightPos, xform)

        return lightPos
Example #4
0
def test_rotMatToAffine(seed):

    pi = np.pi
    pi2 = pi / 2

    for i in range(100):

        rots = [
            -pi + 2 * pi * np.random.random(),
            -pi2 + 2 * pi2 * np.random.random(),
            -pi + 2 * pi * np.random.random()
        ]

        if np.random.random() < 0.5: origin = None
        else: origin = np.random.random(3)

        rmat = affine.axisAnglesToRotMat(*rots)
        mataff = affine.rotMatToAffine(rmat, origin)
        rotaff = affine.rotMatToAffine(rots, origin)

        exp = np.eye(4)
        exp[:3, :3] = rmat
        exp[:3, 3] = origin

        assert np.all(np.isclose(mataff, rotaff))
Example #5
0
    def _rotateModeLeftMouseDrag(self, ev, canvas, mousePos, canvasPos):
        """Called on left mouse drag events in ``rotate`` mode.
        Modifies the canvas rotation matrix according to the X and Y
        mouse position (relative to the mouse down location).
        """

        if self.__rotateMousePos is None:
            return

        w, h = canvas.GetSize()
        x0, y0 = self.__rotateMousePos
        x1, y1 = mousePos

        # Normalise x/y mouse pos to [-fac*pi, +fac*pi]
        fac = 1
        x0 = -1 + 2 * (x0 / float(w)) * fac * np.pi
        y0 = -1 + 2 * (y0 / float(h)) * fac * np.pi
        x1 = -1 + 2 * (x1 / float(w)) * fac * np.pi
        y1 = -1 + 2 * (y1 / float(h)) * fac * np.pi

        xrot = x1 - x0
        yrot = y1 - y0

        rot = affine.axisAnglesToRotMat(yrot, 0, xrot)

        self.__lastRot = rot
        self.__rotateMousePos = mousePos

        canvas.opts.rotation = affine.concat(rot, self.__lastRot,
                                             self.__baseXform)
def swapdim(infile):
    basename = fslimage.removeExt(op.basename(infile))
    outfile = '{}_swapdim.nii.gz'.format(basename)
    img = fslimage.Image(infile)

    data = img.data
    xform = img.voxToWorldMat

    data = data.transpose((2, 0, 1))
    rot = affine.rotMatToAffine(
        affine.concat(affine.axisAnglesToRotMat(np.pi / 2, 0, 0),
                      affine.axisAnglesToRotMat(0, 0, 3 * np.pi / 2)))
    xform = affine.concat(xform, affine.scaleOffsetXform((1, -1, -1),
                                                         (0, 0, 0)), rot)

    fslimage.Image(data, xform=xform, header=img.header).save(outfile)

    return outfile
Example #7
0
    def get3DClipPlane(self, planeIdx):
        """A convenience method which calculates a point-vector description
        of the specified clipping plane. ``planeIdx`` is an index into the
        :attr:`clipPosition`, :attr:`clipAzimuth`, and
        :attr:`clipInclination`, properties.

        Returns the clip plane at the given ``planeIdx`` as an origin and
        normal vector, in the display coordinate system..
        """

        pos     = self.clipPosition[   planeIdx]
        azimuth = self.clipAzimuth[    planeIdx]
        incline = self.clipInclination[planeIdx]

        b       = self.bounds
        pos     = pos             / 100.0
        azimuth = azimuth * np.pi / 180.0
        incline = incline * np.pi / 180.0

        xmid = b.xlo + 0.5 * b.xlen
        ymid = b.ylo + 0.5 * b.ylen
        zmid = b.zlo + 0.5 * b.zlen

        centre = [xmid, ymid, zmid]
        normal = [0, 0, -1]

        rot1     = affine.axisAnglesToRotMat(incline, 0, 0)
        rot2     = affine.axisAnglesToRotMat(0, 0, azimuth)
        rotation = affine.concat(rot2, rot1)

        normal = affine.transformNormal(normal, rotation)
        normal = affine.normalise(normal)

        offset = (pos - 0.5) * max((b.xlen, b.ylen, b.zlen))
        origin = centre + normal * offset

        return origin, normal
Example #8
0
def rotate(infile, rx, ry, rz):
    basename = fslimage.removeExt(op.basename(infile))
    outfile = '{}_rotated_{}_{}_{}.nii.gz'.format(basename, rx, ry, rz)
    img = fslimage.Image(infile)

    rx = rx * np.pi / 180
    ry = ry * np.pi / 180
    rz = rz * np.pi / 180

    rot = affine.axisAnglesToRotMat(rx, ry, rz)
    rot = affine.rotMatToAffine(rot)
    img.voxToWorldMat = affine.concat(rot, img.voxToWorldMat)

    img.save(outfile)

    return outfile
Example #9
0
def test_rotMatToAxisAngles(seed):

    pi = np.pi
    pi2 = pi / 2

    for i in range(100):

        rots = [
            -pi + 2 * pi * np.random.random(),
            -pi2 + 2 * pi2 * np.random.random(),
            -pi + 2 * pi * np.random.random()
        ]

        rmat = affine.axisAnglesToRotMat(*rots)
        gotrots = affine.rotMatToAxisAngles(rmat)

        assert np.all(np.isclose(rots, gotrots))
Example #10
0
def test_compose_and_decompose():

    testfile = op.join(datadir, 'test_transform_test_compose.txt')
    lines = readlines(testfile)
    ntests = len(lines) // 4

    for i in range(ntests):

        xform = lines[i * 4:i * 4 + 4]
        xform = np.genfromtxt(xform)

        scales, offsets, rotations, shears = affine.decompose(xform,
                                                              shears=True)

        result = affine.compose(scales, offsets, rotations, shears=shears)

        assert np.all(np.isclose(xform, result, atol=1e-5))

        # The decompose function does not support a
        # different rotation origin, but we test
        # explicitly passing the origin for
        # completeness
        scales, offsets, rotations, shears = affine.decompose(xform,
                                                              shears=True)
        result = affine.compose(scales,
                                offsets,
                                rotations,
                                origin=[0, 0, 0],
                                shears=shears)

        assert np.all(np.isclose(xform, result, atol=1e-5))

    # compose should also accept a rotation matrix
    rots = [np.pi / 5, np.pi / 4, np.pi / 3]
    rmat = affine.axisAnglesToRotMat(*rots)
    xform = affine.compose([1, 1, 1], [0, 0, 0], rmat)

    # And the angles flag should cause decompose
    # to return the rotation matrix, instead of
    # the axis angls
    sc, of, rot = affine.decompose(xform)
    scat, ofat, rotat = affine.decompose(xform, angles=True)
    scaf, ofaf, rotaf = affine.decompose(xform, angles=False)

    sc, of, rot = np.array(sc), np.array(of), np.array(rot)
    scat, ofat, rotat = np.array(scat), np.array(ofat), np.array(rotat)
    scaf, ofaf, rotaf = np.array(scaf), np.array(ofaf), np.array(rotaf)

    assert np.all(np.isclose(sc, [1, 1, 1]))
    assert np.all(np.isclose(of, [0, 0, 0]))
    assert np.all(np.isclose(scat, [1, 1, 1]))
    assert np.all(np.isclose(ofat, [0, 0, 0]))
    assert np.all(np.isclose(scaf, [1, 1, 1]))
    assert np.all(np.isclose(ofaf, [0, 0, 0]))

    assert np.all(np.isclose(rot, rots))
    assert np.all(np.isclose(rotat, rots))
    assert np.all(np.isclose(rotaf, rmat))

    # decompose should accept a 3x3
    # affine, and return translations of 0
    affine.decompose(xform[:3, :3])
    sc, of, rot = affine.decompose(xform[:3, :3])
    sc, of, rot = np.array(sc), np.array(of), np.array(rot)
    assert np.all(np.isclose(sc, [1, 1, 1]))
    assert np.all(np.isclose(of, [0, 0, 0]))
    assert np.all(np.isclose(rot, rots))