Beispiel #1
0
def display_feedback(regu_match, data_match, k, model):
    """Display feedback window with objective function values and images"""
    # 2D feedback windows
    fig = plt.figure('Optimization', figsize=(16, 10))
    plt.clf()
    for i in range(2):
        # original input images
        fig.add_subplot(2, 3, i + 1)
        plt.imshow(np.rot90(model.dc.J[i]), cmap=cm.gray)
        plt.axis('off')
        # template and match to target
        fig.add_subplot(2, 3, i + 4)
        plt.imshow(np.rot90(model.dc.Ifr[i]), cmap=cm.gray)
        plt.axis('off')
    # objective function values
    fig.add_subplot(2, 3, 3)
    colors = ['blue', 'green', 'red']
    for i in range(2):
        dm = [x[i] for x in data_match]
        plt.plot(range(k), dm, color=colors[i])  # TODO: add color
    fig.add_subplot(2, 3, 3)
    plt.plot(range(k), regu_match, color=colors[-1])
    # jacobian determinants
    fig.add_subplot(2, 3, 6)
    jd = la.det(vcalc.jacobian(model.get_warp(-1), model.get_current_voxel()))
    jd = np.log10(jd)
    plt.imshow(np.rot90(jd))
    plt.axis('off')
    plt.colorbar()
    # show plot
    plt.pause(0.001)
    plt.draw()
Beispiel #2
0
    def _solve_forward(self):
        """Shoot the geodesic forward given initial conditions"""

        # cut down on all the self calls
        dc = self.dc
        # check cfl condition
        dc.satisfy_cfl()

        # compute initial velocity from initial momentum
        dI = vcalc.gradient(dc.I[0], dc.curr_vox)
        m = dI * dc.P[0][..., np.newaxis]
        dc.v = -self._r.regularize(m)

        # compute magnitude of initial momentum field
        P0_mag = -np.prod(dc.curr_vox) * np.sum(m * dc.v)
        P0_mag *= dc.params['sigma']

        # Initial min number of time steps due to CFL condition
        dc.cfl_nums[0] = abs(dc.v * dc.T[-1] / dc.curr_vox).max()

        i = 1
        while i < dc.params['timesteps']:
            # Forward Euler
            dc.uf[i] = (dc.uf[i - 1] +
                        (dc.t[i] - dc.t[i - 1]) * self._t.apply_transform(
                            dc.v, dc.curr_vox, dc.uf[i - 1], vec=True))

            # Advance backward transformation, ctu
            dc.ub[i] = fvm.solve_advection_ctu(dc.ub[i - 1], dc.v, dc.curr_vox,
                                               dc.t[i] - dc.t[i - 1], self._t)

            # Advance the image with group action
            dc.I[i] = self._t.apply_transform(dc.Ifr[0], dc.full_vox, dc.ub[i])

            # Advance the momentum with coadjoint transport
            jdet = la.det(vcalc.jacobian(dc.ub[i], dc.curr_vox))
            dc.P[i] = jdet * self._t.apply_transform(dc.P[0], dc.curr_vox,
                                                     dc.ub[i])

            # Compute velocity from momentum
            dI = vcalc.gradient(dc.I[i], dc.curr_vox)
            dc.v = -self._r.regularize(dI * dc.P[i][..., np.newaxis])

            # Store new CFL min number of time steps
            dc.cfl_nums[i] = abs(dc.v * dc.T[-1] / dc.curr_vox).max()

            i += 1

        # Compute full resolution version of final image
        txm = self._t.resample(dc.ub[-1], dc.curr_vox, dc.full_res, vec=True)
        dc.Ifr[1] = self._t.apply_transform(dc.Ifr[0], dc.full_vox, txm)

        # compute image matching functionals at both ends
        obj_func = []
        obj_func.append(self._m.dist(dc.Ifr[0], dc.J[0]))
        obj_func.append(self._m.dist(dc.Ifr[1], dc.J[1]))

        # return complete evaluation of objective function
        return [P0_mag] + [obj_func]
Beispiel #3
0
    def _solve_backward(self):
        """Solve the adjoint system backward to get gradient"""

        # cut down on all the self calls
        dc = self.dc

        # initialize the adjoint momentum
        dc.Pa = 0

        # initialize the adjoint image (which contains residuals)
        m = self._m.residual(dc.J[-1], dc.Ifr[-1])
        jdet = la.det(vcalc.jacobian(dc.uf[-1], dc.curr_vox))
        mtil = jdet * self._t.apply_transform(m, dc.full_vox, dc.uf[-1])
        dc.Ia = mtil

        # initialize adjoint velocity
        m = self._t.resample(m, dc.full_vox, dc.curr_res)
        dI = vcalc.gradient(dc.I[-1], dc.curr_vox)
        va = -self._r.regularize(dI * m[..., np.newaxis])

        i = dc.params['timesteps'] - 2
        while i > -1:

            # advance the adjoint momentum
            dIva = np.einsum('...i,...i', dI, va)
            # forward Euler
            dc.Pa -= ((dc.t[i + 1] - dc.t[i]) *
                      self._t.apply_transform(dIva, dc.curr_vox, dc.uf[i + 1]))

            # advance the adjoint image
            Pv = va * dc.P[i + 1][..., np.newaxis]
            divPv = vcalc.divergence(Pv, dc.curr_vox)
            jdet = la.det(vcalc.jacobian(dc.uf[i + 1], dc.curr_vox))
            # Forward Euler
            dc.Ia += (
                (dc.t[i + 1] - dc.t[i]) * jdet *
                self._t.apply_transform(divPv, dc.curr_vox, dc.uf[i + 1]))

            # advance adjoint velocity
            Phat = self._t.apply_transform(dc.Pa, dc.curr_vox, dc.ub[i])
            dPhat = vcalc.gradient(Phat, dc.curr_vox)
            A = dPhat * dc.P[i][..., np.newaxis]

            jdet = la.det(vcalc.jacobian(dc.ub[i], dc.curr_vox))
            Ihat = jdet * self._t.apply_transform(dc.Ia, dc.curr_vox, dc.ub[i])
            dI = vcalc.gradient(dc.I[i], dc.curr_vox)
            B = dI * Ihat[..., np.newaxis]

            va = self._r.regularize(A - B)

            i -= 1

        # compute the gradient
        A = self._r.regularize(dI * dc.P[0][..., np.newaxis])
        A = dc.params['sigma'] * np.einsum('...i,...i', dI, A)
        grad = A - dc.Pa

        # compute the gradient magnitude
        # TODO: explore speeding this up (less copies, preallocated output?)
        sd = np.copy(grad)
        ksd = self._r.regularize(np.copy(sd)[..., np.newaxis]).squeeze()
        grad_mag = np.prod(dc.curr_vox) * np.sum(sd * ksd)

        # return gradient and its magnitude
        return [grad, grad_mag]
Beispiel #4
0
# -*- coding: utf-8 -*-
"""
Created on Wed Dec 16 13:00:38 2015

@author: gfleishman
"""

import sys
import numpy as np
import nibabel as nib
import pyrpl.image_tools.vcalc as vcalc

path = sys.argv[1]
wPath = sys.argv[2]
vox = np.array([1., 1., 1.])

uf1 = np.empty((220, 220, 220, 3))
for i in range(3):
    p = path + str(i + 1) + '.nii.gz'
    uf1[..., i] = nib.load(p).get_data().squeeze()

jd = np.linalg.det(vcalc.jacobian(uf1, vox))
jd = nib.Nifti1Image(jd, np.eye(4))
nib.save(jd, wPath)