예제 #1
0
def combining_transforms():

    X = util.test_object(1)

    #------------------------------------------------------------------#
    # Experiment with combining transformation matrices.
    X1_1 = reg.rotate(np.pi / 4).dot(reg.reflect(-1, 1).dot(X))
    X1_2 = reg.reflect(-1, 1).dot(reg.rotate(np.pi / 4).dot(X))
    X2_1 = reg.shear(0.6, 0.3).dot(reg.reflect(-1, -1).dot(X))
    X2_2 = reg.shear(0.6, 0.3).dot(reg.reflect(-1, 1).dot(X))
    X3_1 = reg.reflect(-1, 1).dot(reg.shear(0.6, 0.3).dot(X))
    X3_2 = reg.shear(0.6, 0.3).dot(reg.reflect(-1, 1).dot(X))

    fig = plt.figure(figsize=(12, 5))
    ax1 = fig.add_subplot(141, xlim=(-4, 4), ylim=(-4, 4))
    ax2 = fig.add_subplot(142, xlim=(-4, 4), ylim=(-4, 4))
    ax3 = fig.add_subplot(143, xlim=(-4, 4), ylim=(-4, 4))
    ax4 = fig.add_subplot(144, xlim=(-4, 4), ylim=(-4, 4))

    util.plot_object(ax1, X)
    util.plot_object(ax2, X1_1)
    util.plot_object(ax2, X1_2)
    util.plot_object(ax3, X2_1)
    util.plot_object(ax3, X2_2)
    util.plot_object(ax4, X3_1)
    util.plot_object(ax4, X3_2)

    ax1.grid()
    ax2.grid()
    ax3.grid()
    ax4.grid()
예제 #2
0
def combining_transforms():

    X = util.test_object(1)

    #------------------------------------------------------------------#
    # TODO: Experiment with combining transformation matrices.
    Example_1_temp = reg.rotate(5 * np.pi / 3).dot(X)
    Example_1_result = reg.reflect(-1, 1).dot(Example_1_temp)

    Example2 = reg.reflect(-1, 1).dot(X)
    Example2_result = reg.rotate(np.pi / 2).dot(Example2)

    Example2_reversed = reg.rotate(np.pi / 2).dot(X)
    Example2_reversed_result = reg.rotate(5 * np.pi / 3).dot(X)

    #plotting
    fig = plt.figure(figsize=(12, 5))
    ax1 = fig.add_subplot(141, xlim=(-4, 4), ylim=(-4, 4))
    ax2 = fig.add_subplot(142, xlim=(-4, 4), ylim=(-4, 4))
    ax3 = fig.add_subplot(143, xlim=(-4, 4), ylim=(-4, 4))

    util.plot_object(ax1, X)
    util.plot_object(ax2, Example2_result)
    util.plot_object(ax3, Example2_reversed_result)

    ax1.set_title('Original')
    ax2.set_title('Reflection, rotation')
    ax3.set_title('Reversed')

    ax1.grid()
    ax2.grid()
    ax3.grid()
예제 #3
0
def combining_transforms():

    X = util.test_object(1)

    #------------------------------------------------------------------#
    # TODO: Experiment with combining transformation matrices.

    X_t = reg.reflect(-1, 1).dot(reg.rotate(np.pi / 2)).dot(X)
    X_u = reg.shear(2, 1).dot(reg.reflect(1, -1)).dot(X)
    X_v = reg.reflect(1, -1).dot(reg.shear(2, 1)).dot(X)
    X_w = reg.rotate(np.pi / 2).dot(reg.shear(2, 1)).dot(X)

    fig = plt.figure(figsize=(12, 5))
    ax1 = fig.add_subplot(141, xlim=(-8, 8), ylim=(-8, 8))
    ax2 = fig.add_subplot(142, xlim=(-8, 8), ylim=(-8, 8))
    ax3 = fig.add_subplot(143, xlim=(-8, 8), ylim=(-8, 8))
    ax4 = fig.add_subplot(144, xlim=(-8, 8), ylim=(-8, 8))

    util.plot_object(ax1, X_t)
    util.plot_object(ax2, X_u)
    util.plot_object(ax3, X_v)
    util.plot_object(ax4, X_w)

    ax1.set_title('reflect, rotate')
    ax2.set_title('shear, reflect')
    ax3.set_title('reflect, shear')
    ax4.set_title('rotate, shear')

    ax1.grid()
    ax2.grid()
    ax3.grid()
    ax4.grid()
예제 #4
0
def combining_transforms():

    X = util.test_object(1)

    X_1 = X
    X_2 = reg.rotate(3 * np.pi / 4).dot(X)
    X_3 = reg.reflect(-1, 1).dot(reg.rotate(3 * np.pi / 4).dot(X))
    X_4 = reg.shear(0.1, 0.2).dot(
        reg.reflect(-1, 1).dot(reg.rotate(3 * np.pi / 4).dot(X)))

    fig = plt.figure(figsize=(12, 5))
    ax1 = fig.add_subplot(141, xlim=(-4, 4), ylim=(-4, 4))
    ax2 = fig.add_subplot(142, xlim=(-4, 4), ylim=(-4, 4))
    ax3 = fig.add_subplot(143, xlim=(-4, 4), ylim=(-4, 4))
    ax4 = fig.add_subplot(144, xlim=(-4, 4), ylim=(-4, 4))

    util.plot_object(ax1, X_1)
    util.plot_object(ax2, X_2)
    util.plot_object(ax3, X_3)
    util.plot_object(ax4, X_4)

    ax1.set_title('Original')
    ax2.set_title('Then rotate')
    ax3.set_title('Now reflect over x')
    ax4.set_title('Lastly, shear')

    for ax_obj in [ax1, ax2, ax3, ax4]:
        ax_obj.grid()
예제 #5
0
def combining_transforms():

    X = util.test_object(1)

    X_rot = reg.rotate(3 * np.pi / 7).dot(X)
    X_shear = reg.shear(0.3, 0.22).dot(X)

    X_rot_shear = reg.shear(0.1, 0.3).dot(X_rot)
    X_shear_reflect = reg.reflect(-1, 1).dot(X_shear)
    X_multicom = reg.rotate(np.pi / 3).dot(X_rot_shear)

    fig = plt.figure(figsize=(12, 5))
    ax1 = fig.add_subplot(141, xlim=(-4, 4), ylim=(-4, 4))
    ax2 = fig.add_subplot(142, xlim=(-4, 4), ylim=(-4, 4))
    ax3 = fig.add_subplot(143, xlim=(-4, 4), ylim=(-4, 4))
    ax4 = fig.add_subplot(144, xlim=(-4, 4), ylim=(-4, 4))

    util.plot_object(ax1, X)
    util.plot_object(ax2, X_rot_shear)
    util.plot_object(ax3, X_shear_reflect)
    util.plot_object(ax4, X_multicom)

    ax1.set_title('Original')
    ax2.set_title('Combination 1')
    ax3.set_title('Combination 2')
    ax4.set_title('Combination 3')

    ax1.grid()
    ax2.grid()
    ax3.grid()
    ax4.grid()
예제 #6
0
def arbitrary_rotation():

    X = util.test_object(1)  # The object that is rotated
    Xh = util.c2h(X)  # Convert the object vectors to homogeneous coords

    t = X[:, 0]  # First vertex to rotate around

    # Define separate transformations in homogeneous coords

    T_ftrans = util.t2h(reg.identity(), -1 *
                        t)  # Translate to ensure first vertex is in the origin
    T_rot = util.t2h(reg.rotate(np.pi / 4), np.array([0,
                                                      0]))  # Rotate 45 degrees
    T_btrans = util.t2h(reg.identity(),
                        t)  # Translate back to the original position

    # Create the final transformation matrix
    T = T_btrans.dot(T_rot.dot(T_ftrans))
    #------------------------------------------------------------------#
    # TODO: TODO: Perform rotation of the test shape around the first vertex
    #------------------------------------------------------------------#

    # Transform
    X_rot = T.dot(Xh)

    # Plot
    fig = plt.figure(figsize=(5, 5))
    ax1 = fig.add_subplot(111)
    util.plot_object(ax1, X)
    util.plot_object(ax1, X_rot)
    ax1.set_xlim(ax1.get_ylim())
    ax1.grid()
예제 #7
0
def affine_corr(I, Im, x, MI):
    # Computes normalized cross-correlation between a fixed and
    # a moving image transformed with an affine transformation.
    # Input:
    # I - fixed image
    # Im - moving image
    # x - parameters of the rigid transform: the first element
    #     is the rotation angle, the second and third are the
    #     scaling parameters, the fourth and fifth are the
    #     shearing parameters and the remaining two elements
    #     are the translation
    # Output:
    # C - normalized cross-correlation between I and T(Im)
    # Im_t - transformed moving image T(Im)

    Tro = reg.rotate(x[0])
    Tsc = reg.scale(x[1], x[2])
    Tsh = reg.shear(x[3], x[4])
    Trss = Tro.dot(Tsc).dot(Tsh)
    Th = util.t2h(Trss, [x[5], x[6]])

    Im_t, Xt = reg.image_transform(Im, Th)

    if MI:
        p = joint_histogram(I, Im_t)
        S = reg.mutual_information(p)
    else:
        S = reg.correlation(I, Im_t)

    return S, Im_t, Th
예제 #8
0
def transforms_test():

    X = util.test_object(1)

    X_rot = reg.rotate(3*np.pi/4).dot(X)
    X_shear = reg.shear(0.1, 0.2).dot(X)
    X_reflect = reg.reflect(-1, -1).dot(X)

    fig = plt.figure(figsize=(12,5))
    ax1 = fig.add_subplot(141, xlim=(-4,4), ylim=(-4,4))
    ax2 = fig.add_subplot(142, xlim=(-4,4), ylim=(-4,4))
    ax3 = fig.add_subplot(143, xlim=(-4,4), ylim=(-4,4))
    ax4 = fig.add_subplot(144, xlim=(-4,4), ylim=(-4,4))

    util.plot_object(ax1, X)
    util.plot_object(ax2, X_rot)
    util.plot_object(ax3, X_shear)
    util.plot_object(ax4, X_reflect)

    ax1.set_title('Original')
    ax2.set_title('Rotation')
    ax3.set_title('Shear')
    ax4.set_title('Reflection')

    ax1.grid()
    ax2.grid()
    ax3.grid()
    ax4.grid()
예제 #9
0
def rigid_corr(I, Im, x, MI):
    # Computes normalized cross-correlation between a fixed and
    # a moving image transformed with a rigid transformation.
    # Input:
    # I - fixed image
    # Im - moving image
    # x - parameters of the rigid transform: the first element
    #     is the rotation angle and the remaining two elements
    #     are the translation
    # Output:
    # C - normalized cross-correlation between I and T(Im)
    # Im_t - transformed moving image T(Im)

    SCALING = 100

    # the first element is the rotation angle
    T = reg.rotate(x[0])
    Th = util.t2h(T, x[1:] * SCALING)

    # transform the moving image
    Im_t, Xt = reg.image_transform(Im, Th)

    # compute the similarity between the fixed and transformed moving image
    if MI:
        p = joint_histogram(I, Im_t)
        S = reg.mutual_information(p)
    else:
        S = reg.correlation(I, Im_t)

    return S, Im_t, Th
예제 #10
0
def arbitrary_rotation():

    X = util.test_object(1)
    Xh = util.c2h(X)

    #------------------------------------------------------------------#
    # Perform rotation of the test shape around the first vertex

    t = -X[:, 0]
    Trot = reg.rotate(np.pi / 4)
    Throt = util.t2h(Trot, np.zeros([1, np.size(Trot, axis=1)]))
    th = util.t2h(reg.identity(), t)
    thin = np.linalg.inv(th)
    T = thin.dot(Throt.dot(th))

    #------------------------------------------------------------------#

    X_rot = T.dot(Xh)

    fig = plt.figure(figsize=(5, 5))
    ax1 = fig.add_subplot(111)
    util.plot_object(ax1, X)
    util.plot_object(ax1, X_rot)
    ax1.set_xlim(ax1.get_ylim())
    ax1.grid()
예제 #11
0
def arbitrary_rotation():

    X = util.test_object(1)
    Xh = util.c2h(X)  #the object in homogeneous form

    #------------------------------------------------------------------#
    Xt = np.array(X[:, 0])
    T_rot = reg.rotate(np.pi / 4)

    Xt_down = util.t2h(
        reg.identity(),
        -Xt)  #with Xt being the translation vector set into homogeneous form
    Xt_up = util.t2h(reg.identity(), Xt)
    T_rot = util.t2h(T_rot, np.array(
        [0, 0]))  #with T being the rotational vector set into homogeneous form

    T = Xt_up.dot(T_rot).dot(Xt_down)
    X_fin = T.dot(Xh)
    #------------------------------------------------------------------#

    fig = plt.figure(figsize=(5, 5))
    ax1 = fig.add_subplot(111)
    util.plot_object(ax1, X)
    util.plot_object(ax1, X_fin)
    ax1.set_xlim(ax1.get_ylim())
    ax1.grid()
예제 #12
0
def ls_affine_test():

    X = util.test_object(1)
    # convert to homogeneous coordinates
    Xh = util.c2h(X)

    T_rot = reg.rotate(np.pi / 4)
    T_scale = reg.scale(1.2, 0.9)
    T_shear = reg.shear(0.2, 0.1)

    T = util.t2h(T_rot.dot(T_scale).dot(T_shear), [10, 20])

    Xm = T.dot(Xh)

    Te = reg.ls_affine(Xh, Xm)

    Xmt = Te.dot(Xm)

    fig = plt.figure(figsize=(12, 5))

    ax1 = fig.add_subplot(131)
    ax2 = fig.add_subplot(132)
    ax3 = fig.add_subplot(133)

    util.plot_object(ax1, Xh)
    util.plot_object(ax2, Xm)
    util.plot_object(ax3, Xmt)

    ax1.set_title('Test shape')
    ax2.set_title('Arbitrary transformation')
    ax3.set_title('Retrieved test shape')

    ax1.grid()
    ax2.grid()
    ax3.grid()
def combining_transforms():

    X = util.test_object(1)

    #------------------------------------------------------------------#
    # TODO: Experiment with combining transformation matrices.
    X_t = reg.rotate(np.pi/2).dot(X)*reg.reflect(-1,1).dot(X)
    return X_t
def affine_mi_adapted(I, Im, x):

    # Computes mutual information between a fixed and

    # a moving image transformed with an affine transformation.

    # Input:

    # I - fixed image

    # Im - moving image

    # x - parameters of the rigid transform: the first element

    #     is the rotation angle, the second and third are the

    #     scaling parameters, the fourth and fifth are the

    #     shearing parameters and the remaining two elements

    #     are the translation

    # Output:

    # MI - mutual information between I and T(Im)

    # Im_t - transformed moving image T(Im)

    NUM_BINS = 64

    SCALING = 100

    #------------------------------------------------------------------#

    # TODO: Implement the missing functionality

    T_rotate = reg.rotate(x[0])

    T_scaled = reg.scale(x[1], x[2])

    T_shear = reg.shear(x[3], x[4])

    t = np.array(x[5:]) * SCALING

    T_total = T_shear.dot((T_scaled).dot(T_rotate))

    Th = util.t2h(T_total, t)

    Im_t, Xt = reg.image_transform(Im, Th)

    p = reg.joint_histogram(Im, Im_t)

    MI = reg.mutual_information(p)

    #------------------------------------------------------------------#

    return MI
예제 #15
0
def combining_transforms():
    X = util.test_object(1)

    X_combined = (reg.rotate(3 * np.pi / 5) * reg.shear(0.2, 0.2) * reg.shear(2, 8)).dot(X)

    fig = plt.figure(figsize=(12, 5))

    ax1 = fig.add_subplot(141, xlim=(-4, 4), ylim=(-4, 4))

    util.plot_object(ax1, X_combined)
예제 #16
0
def combining_transforms():

    X = util.test_object(1)
    T = reg.reflect(-1, 1).dot(reg.rotate(np.pi / 2))
    X_t = T.dot(X)

    fig = plt.figure(figsize=(5, 5))
    ax1 = fig.add_subplot(111)
    ax1.grid()
    util.plot_object(ax1, X)
    util.plot_object(ax1, X_t)
예제 #17
0
def t2h_test():
    X = util.test_object(1)
    Xh = util.c2h(X)

    # translation vector
    t = np.array([10, 20])

    # rotation matrix
    T_rot = reg.rotate(np.pi / 4)

    Th = util.t2h(T_rot, t)

    X_rot_tran = Th.dot(Xh)

    fig = plt.figure(figsize=(5, 5))
    ax1 = fig.add_subplot(111)
    util.plot_object(ax1, X)
    util.plot_object(ax1, X_rot_tran)
    ax1.grid()
예제 #18
0
def optim_affine_corr(x, I, Im, MI):
    # Identical to affine_corr in functionality but the x variable is placed
    # in front when calling for use in scipy.optimize function.
    # Output is changed to only give the similarity because scipy.optimize
    # uses this metric to optimize the parameters

    Tro = reg.rotate(x[0])
    Tsc = reg.scale(x[1], x[2])
    Tsh = reg.shear(x[3], x[4])
    Trss = Tro.dot(Tsc).dot(Tsh)
    Th = util.t2h(Trss, [x[5], x[6]])

    Im_t, Xt = reg.image_transform(Im, Th)

    if MI:
        p = joint_histogram(I, Im_t)
        S = reg.mutual_information(p)
    else:
        S = reg.correlation(I, Im_t)

    return S
예제 #19
0
def arbitrary_rotation():

    X = util.test_object(1)
    Xh = util.c2h(X)

    #------------------------------------------------------------------#
    Xt= X[:0]
    T_trans = util.t2h(reg.identity(), Xt)
    T_rot = reg.rotate(0.25*np.pi)
    T_trans_inv = np.linalg.inv(T_trans)
    T = T_trans_inv.dot(T_rot.dot(T_trans))
    #------------------------------------------------------------------#

    X_rot = T.dot(Xh)

    fig = plt.figure(figsize=(5,5))
    ax1 = fig.add_subplot(111)
    util.plot_object(ax1, X)
    util.plot_object(ax1, X_rot)
    ax1.set_xlim(ax1.get_ylim())
    ax1.grid()
예제 #20
0
def arbitrary_rotation():
    X = util.test_object(1)
    Xh = util.c2h(X)

    p_rot = X[:, 0]
    T_to_zero = util.t2h(reg.identity(), -p_rot)
    T_return = util.t2h(reg.identity(), p_rot)
    T_rot = util.t2h(reg.rotate(45))

    T = T_return.dot(T_rot.dot(T_to_zero))

    X_rot = T.dot(Xh)

    fig = plt.figure(figsize=(5, 5))
    ax1 = fig.add_subplot(111)
    util.plot_object(ax1, X)
    util.plot_object(ax1, X_rot)
    ax1.set_xlim(ax1.get_ylim())
    ax1.grid()

    fig.show()
예제 #21
0
def arbitrary_rotation():

    X = util.test_object(1)
    Xh = util.c2h(X)

    #------------------------------------------------------------------#
    # TODO: Perform rotation of the test shape around the first vertex

    Xt = X[:, 0]

    T = util.t2h(reg.rotate(np.pi / 4), Xt).dot(util.t2h(reg.identity(), -Xt))

    #------------------------------------------------------------------#

    X_rot = T.dot(Xh)

    fig = plt.figure(figsize=(5, 5))
    ax1 = fig.add_subplot(111)
    util.plot_object(ax1, X)
    util.plot_object(ax1, X_rot)
    ax1.set_xlim(ax1.get_ylim())
    ax1.grid()
예제 #22
0
def image_transform_test():

    I = plt.imread('8dc00-mia/data/cameraman.tif')

    # 45 deg. rotation around the image center
    T_1 = util.t2h(reg.identity(), 128 * np.ones(2))
    T_2 = util.t2h(reg.rotate(np.pi / 4), np.zeros(2))
    T_3 = util.t2h(reg.identity(), -128 * np.ones(2))
    T_rot = T_1.dot(T_2).dot(T_3)

    # 45 deg. rotation around the image center followed by shearing
    T_shear = util.t2h(reg.shear(0.0, 0.5), np.zeros(2)).dot(T_rot)

    # scaling in the x direction and translation
    T_scale = util.t2h(reg.scale(1.5, 1), np.array([10, 20]))

    It1, Xt1 = reg.image_transform(I, T_rot)
    It2, Xt2 = reg.image_transform(I, T_shear)
    It3, Xt3 = reg.image_transform(I, T_scale)

    fig = plt.figure(figsize=(12, 5))

    ax1 = fig.add_subplot(131)
    im11 = ax1.imshow(I)
    im12 = ax1.imshow(It1, alpha=0.7)

    ax2 = fig.add_subplot(132)
    im21 = ax2.imshow(I)
    im22 = ax2.imshow(It2, alpha=0.7)

    ax3 = fig.add_subplot(133)
    im31 = ax3.imshow(I)
    im32 = ax3.imshow(It3, alpha=0.7)

    ax1.set_title('Rotation')
    ax2.set_title('Shearing')
    ax3.set_title('Scaling')

    plt.show()
예제 #23
0
def arbitrary_rotation():
    X = util.test_object(1)
    Xh = util.c2h(X)

    # ------------------------------------------------------------------#
    Tlat = util.t2h(reg.identity(), np.array(X[:, 0]))
    Tlat_down = util.t2h(reg.identity(), -np.array(X[:, 0]))
    T_rot = reg.rotate(np.pi / 4)

    T_rot_hom = util.t2h(T_rot, np.array([0, 0]))

    T_tot = Tlat.dot(T_rot_hom).dot(Tlat_down)
    X_fin = T_tot.dot(Xh)

    # ------------------------------------------------------------------#

    fig = plt.figure(figsize=(5, 5))
    ax1 = fig.add_subplot(111)
    util.plot_object(ax1, X)
    util.plot_object(ax1, X_fin)
    ax1.set_xlim(ax1.get_ylim())
    ax1.grid()
예제 #24
0
def optim_rigid_corr(x, I, Im, MI):
    # Identical to rigid_corr in functionality but the x variable is placed
    # in front when calling for use in scipy.optimize function.
    # Output is changed to only give the similarity because scipy.optimize
    # uses this metric to optimize the parameters

    SCALING = 100

    # the first element is the rotation angle
    T = reg.rotate(x[0])
    Th = util.t2h(T, x[1:] * SCALING)

    # transform the moving image
    Im_t, Xt = reg.image_transform(Im, Th)

    # compute the similarity between the fixed and transformed moving image
    if MI:
        p = joint_histogram(I, Im_t)
        S = reg.mutual_information(p)
    else:
        S = reg.correlation(I, Im_t)

    return S
예제 #25
0
def arbitrary_rotation():

    X = util.test_object(1)
    Xh = util.c2h(X)

    #------------------------------------------------------------------#
    # TODO: TODO: Perform rotation of the test shape around the first vertex
    #------------------------------------------------------------------#
    tdown = X[:, 0] * -1
    tup = X[:, 0]
    tdown = util.t2h(reg.identity(), tdown)
    tup = util.t2h(reg.identity(), tup)
    r = util.t2h(reg.rotate(45), [0, 0])
    T = tup.dot(r.dot(tdown))

    X_rot = T.dot(Xh)

    fig = plt.figure(figsize=(5, 5))
    ax1 = fig.add_subplot(111)
    util.plot_object(ax1, X)
    util.plot_object(ax1, X_rot)
    ax1.set_xlim(ax1.get_ylim())
    ax1.grid()
    plt.show()
예제 #26
0
def combining_transforms():

    X = util.test_object(1)

    #------------------------------------------------------------------#
    X_t = reg.reflect(-1,1).dot(reg.rotate(2)).dot(X)
예제 #27
0
def registration_metrics_demo(use_t2=False):

    # read a T1 image
    I = plt.imread('../data/t1_demo.tif')

    if use_t2:
        # read the corresponding T2 image
        # note that the T1 and T2 images are already registered
        I_t2 = plt.imread('../data/t2_demo.tif')

    # create a linear space of rotation angles - 101 angles between 0 and 360 deg.
    angles = np.linspace(-np.pi, np.pi, 101, endpoint=True)

    CC = np.full(angles.shape, np.nan)
    MI = np.full(angles.shape, np.nan)

    # visualization
    fig = plt.figure(figsize=(14,6))

    # correlation
    ax1 = fig.add_subplot(131, xlim=(-np.pi, np.pi), ylim=(-1.1, 1.1))
    line1, = ax1.plot(angles, CC, lw=2)
    ax1.set_xlabel('Rotation angle')
    ax1.set_ylabel('Correlation coefficient')
    ax1.grid()

    # mutual mutual_information
    ax2  = fig.add_subplot(132, xlim=(-np.pi, np.pi), ylim=(0, 2))
    line2, = ax2.plot(angles, MI, lw=2)
    ax2.set_xlabel('Rotation angle')
    ax2.set_ylabel('Mutual information')
    ax2.grid()

    # images
    ax3 = fig.add_subplot(133)
    im1 = ax3.imshow(I)
    im2 = ax3.imshow(I, alpha=0.7)

    # used for rotation around image center
    t = np.array([I.shape[0], I.shape[1]])/2 + 0.5
    T_1 = util.t2h(reg.identity(), t)
    T_3 = util.t2h(reg.identity(), -t)

    # loop over the rotation angles
    for k, ang in enumerate(angles):
        # transformation matrix for rotating the image
        # I by angles(k) around its center point
        T_2 = util.t2h(reg.rotate(ang), np.zeros(2))
        T_rot = T_1.dot(T_2).dot(T_3)

        if use_t2:
            # rotate the T2 image
            J, Xt = reg.image_transform(I_t2, T_rot)
        else:
            # rotate the T1 image
            J, Xt = reg.image_transform(I, T_rot)

        # compute the joint histogram with 16 bins
        p = reg.joint_histogram(I, J, 16, [0, 255])

        CC[k] = reg.correlation(I, J)
        MI[k] = reg.mutual_information(p)

        clear_output(wait = True)
        
        # visualize the results
        line1.set_ydata(CC)
        line2.set_ydata(MI)
        im2.set_data(J)

        display(fig)
def affine_corr_adapted(I, Im, x):

    #ADAPTED: In order to determine the gradient of the parameters, you only

    #need the correlation value. So, the outputs: Th and Im_t are removed.

    #Nothing else is changed.

    #Attention this function will be used for ngradient in the function:

    #intensity_based_registration_rigid_adapted.

    # Computes normalized cross-corrleation between a fixed and

    # a moving image transformed with an affine transformation.

    # Input:

    # I - fixed image

    # Im - moving image

    # x - parameters of the rigid transform: the first element

    #     is the roation angle, the second and third are the

    #     scaling parameters, the fourth and fifth are the

    #     shearing parameters and the remaining two elements

    #     are the translation

    # Output:

    # C - normalized cross-corrleation between I and T(Im)

    # Im_t - transformed moving image T(Im)

    NUM_BINS = 64

    SCALING = 100

    #------------------------------------------------------------------#

    # TODO: Implement the missing functionality

    T_rotate = reg.rotate(x[0])  #make rotation matrix (2x2 matrix)

    T_scaled = reg.scale(x[1], x[2])  #make scale matrix (2x2 matrix)

    T_shear = reg.shear(x[3], x[4])  # make shear matrix (2x2 matrix)

    t = np.array(x[5:]) * SCALING  #scale translation vector

    T_total = T_shear.dot(
        (T_scaled).dot(T_rotate)
    )  #multiply the matrices to get the transformation matrix (2x2)

    Th = util.t2h(
        T_total, t)  #convert to homogeneous transformation matrix (3x3 matrix)

    Im_t, Xt = reg.image_transform(Im,
                                   Th)  #apply transformation to moving image

    C = reg.correlation(
        Im, Im_t
    )  #determine the correlation between the moving and transformed moving image

    #------------------------------------------------------------------#

    return C
def rigid_corr_adapted(I, Im, x):

    #ADAPTED: In order to determine the gradient of the parameters, you only

    #need the correlation value. So, the outputs: Th and Im_t are removed.

    #Nothing else is changed.

    #Attention this function will be used for ngradient in the function:

    #intensity_based_registration_rigid_adapted.

    # Computes normalized cross-correlation between a fixed and

    # a moving image transformed with a rigid transformation.

    # Input:

    # I - fixed image

    # Im - moving image

    # x - parameters of the rigid transform: the first element

    #     is the rotation angle and the remaining two elements

    #     are the translation

    # Output:

    # C - normalized cross-correlation between I and T(Im)

    # Im_t - transformed moving image T(Im)

    SCALING = 100

    # the first element is the rotation angle

    T = reg.rotate(x[0])

    # the remaining two element are the translation

    #

    # the gradient ascent/descent method work best when all parameters

    # of the function have approximately the same range of values

    # this is  not the case for the parameters of rigid registration

    # where the transformation matrix usually takes  much smaller

    # values compared to the translation vector this is why we pass a

    # scaled down version of the translation vector to this function

    # and then scale it up when computing the transformation matrix

    Th = util.t2h(T, x[1:] * SCALING)

    # transform the moving image

    Im_t, Xt = reg.image_transform(Im, Th)

    # compute the similarity between the fixed and transformed

    # moving image

    C = reg.correlation(I, Im_t)

    return C