Ejemplo n.º 1
0
def test_cc_2d():
    r""" Test 2D SyN with CC metric

    Register a coronal slice from a T1w brain MRI before and after warping
    it under a synthetic invertible map. We verify that the final
    registration is of good quality.
    """
    fname = get_fnames('t1_coronal_slice')
    nslices = 1
    b = 0.1
    m = 4

    image = np.load(fname)
    moving, static = get_warped_stacked_image(image, nslices, b, m)

    # Configure the metric
    sigma_diff = 3.0
    radius = 4
    metric = metrics.CCMetric(2, sigma_diff, radius)

    # Configure and run the Optimizer
    level_iters = [15, 5]
    optimizer = imwarp.SymmetricDiffeomorphicRegistration(metric, level_iters)
    optimizer.verbosity = VerbosityLevels.DEBUG
    mapping = optimizer.optimize(static, moving, None)
    m = optimizer.get_map()
    assert_equal(mapping, m)

    warped = mapping.transform(moving)
    starting_energy = np.sum((static - moving)**2)
    final_energy = np.sum((static - warped)**2)
    reduced = 1.0 - final_energy / starting_energy

    assert (reduced > 0.9)
Ejemplo n.º 2
0
def test_ssd_2d_gauss_newton():
    r""" Test 2D SyN with SSD metric, Gauss-Newton optimizer

    Classical Circle-To-C experiment for 2D monomodal registration. We
    verify that the final registration is of good quality.
    """
    fname_moving = get_fnames('reg_o')
    fname_static = get_fnames('reg_c')

    moving = np.load(fname_moving)
    static = np.load(fname_static)
    moving = np.array(moving, dtype=floating)
    static = np.array(static, dtype=floating)
    moving = (moving - moving.min()) / (moving.max() - moving.min())
    static = (static - static.min()) / (static.max() - static.min())
    # Create the SSD metric
    smooth = 4
    inner_iter = 5
    step_type = 'gauss_newton'
    similarity_metric = metrics.SSDMetric(2, smooth, inner_iter, step_type)

    # Configure and run the Optimizer
    level_iters = [200, 100, 50, 25]
    step_length = 0.5
    opt_tol = 1e-4
    inv_iter = 40
    inv_tol = 1e-3
    ss_sigma_factor = 0.2
    optimizer = imwarp.SymmetricDiffeomorphicRegistration(
        similarity_metric, level_iters, step_length, ss_sigma_factor, opt_tol,
        inv_iter, inv_tol)

    # test callback not being called
    optimizer.INIT_START_CALLED = 0
    optimizer.INIT_END_CALLED = 0
    optimizer.OPT_START_CALLED = 0
    optimizer.OPT_END_CALLED = 0
    optimizer.SCALE_START_CALLED = 0
    optimizer.SCALE_END_CALLED = 0
    optimizer.ITER_START_CALLED = 0
    optimizer.ITER_END_CALLED = 0

    optimizer.verbosity = VerbosityLevels.DEBUG
    id = np.eye(3)
    mapping = optimizer.optimize(static, moving, id, id, id)
    m = optimizer.get_map()
    assert_equal(mapping, m)

    warped = mapping.transform(moving)
    starting_energy = np.sum((static - moving)**2)
    final_energy = np.sum((static - warped)**2)
    reduced = 1.0 - final_energy / starting_energy

    assert (reduced > 0.9)
    assert_equal(optimizer.OPT_START_CALLED, 0)
    assert_equal(optimizer.OPT_END_CALLED, 0)
    assert_equal(optimizer.SCALE_START_CALLED, 0)
    assert_equal(optimizer.SCALE_END_CALLED, 0)
    assert_equal(optimizer.ITER_START_CALLED, 0)
    assert_equal(optimizer.ITER_END_CALLED, 0)
Ejemplo n.º 3
0
def test_em_3d_demons():
    r'''
    Register a stack of circles ('cylinder') before and after warping them with
    a synthetic diffeomorphism. This test
    is intended to detect regressions only: we saved the energy profile (the
    sequence of energy values at each iteration) of a working version of EM in
    3D, and this test checks that the current energy profile matches the saved
    one. The validation of the "working version" was
    done by registering the 18 manually annotated T1 brain MRI database IBSR
    with each other and computing the jaccard index for all 31 common anatomical
    regions. The "working version" of EM in 3D obtains very similar results as
    those reported for ANTS on the same database. Any modification that produces
    a change in the energy profile should be carefully validated to ensure no
    accuracy loss.
    '''
    moving, static = get_synthetic_warped_circle(30)
    moving[...,:8] = 0
    moving[...,-1:-9:-1] = 0
    static[...,:8] = 0
    static[...,-1:-9:-1] = 0

    #Create the EM metric
    smooth=25.0
    inner_iter=20
    step_length=0.25
    q_levels=256
    double_gradient=True
    iter_type='demons'
    similarity_metric = metrics.EMMetric(
        3, smooth, inner_iter, q_levels, double_gradient, iter_type)

    #Create the optimizer
    level_iters = [10, 5]
    opt_tol = 1e-4
    inv_iter = 20
    inv_tol = 1e-3
    ss_sigma_factor = 0.5
    optimizer = imwarp.SymmetricDiffeomorphicRegistration(similarity_metric,
        level_iters, step_length, ss_sigma_factor, opt_tol, inv_iter, inv_tol)
    optimizer.verbosity = VerbosityLevels.DEBUG
    mapping = optimizer.optimize(static, moving, None)
    m = optimizer.get_map()
    assert_equal(mapping, m)
    energy_profile = np.array(optimizer.full_energy_profile)
    if floating is np.float32:
        expected_profile = \
            np.array([144.0369470764622, 122.39543007604394, 112.43783718421119,
                      85.46819602604248, 101.15549228031932, 119.62429965589826,
                      124.00100190950647, 118.94404608675168, 112.57666071129853,
                      117.84424645441413, 4470.2719430621, 4138.201850019068,
                      4007.225585554024, 4074.8853855654797, 3833.6272345908865])
    else:
        expected_profile = \
            np.array([144.03695786872666, 121.73922862297613, 107.41132697303448,
                      90.70731102557508, 97.4295175632117, 112.78404966709469,
                      103.29910157963684, 111.83865866152108, 121.26265581989485,
                      118.19913094423933, 4222.003181977351, 4418.042311441615,
                      4508.671160627819, 4761.251133428944, 4292.8507317299245])
    assert_array_almost_equal(energy_profile, expected_profile, decimal=6)
Ejemplo n.º 4
0
def test_em_3d_gauss_newton():
    r'''
    Register a stack of circles ('cylinder') before and after warping them with
    a synthetic diffeomorphism. This test
    is intended to detect regressions only: we saved the energy profile (the
    sequence of energy values at each iteration) of a working version of EM in
    3D, and this test checks that the current energy profile matches the saved
    one. The validation of the "working version" was
    done by registering the 18 manually annotated T1 brain MRI database IBSR
    with each other and computing the jaccard index for all 31 common
    anatomical regions. The "working version" of EM in 3D obtains very similar
    results as those reported for ANTS on the same database. Any modification
    that produces a change in the energy profile should be carefully validated
    to ensure no accuracy loss.
    '''
    moving, static = get_synthetic_warped_circle(30)
    moving[...,:8] = 0
    moving[...,-1:-9:-1] = 0
    static[...,:8] = 0
    static[...,-1:-9:-1] = 0

    #Create the EM metric
    smooth=25.0
    inner_iter=20
    step_length=0.25
    q_levels=256
    double_gradient=True
    iter_type='gauss_newton'
    similarity_metric = metrics.EMMetric(
        3, smooth, inner_iter, q_levels, double_gradient, iter_type)

    #Create the optimizer
    level_iters = [10, 5]
    opt_tol = 1e-4
    inv_iter = 20
    inv_tol = 1e-3
    ss_sigma_factor = 0.5
    optimizer = imwarp.SymmetricDiffeomorphicRegistration(similarity_metric,
        level_iters, step_length, ss_sigma_factor, opt_tol, inv_iter, inv_tol)
    optimizer.verbosity = VerbosityLevels.DEBUG
    mapping = optimizer.optimize(static, moving, None)
    m = optimizer.get_map()
    assert_equal(mapping, m)
    energy_profile = subsample_profile(
        optimizer.full_energy_profile, 10)
    print(energy_profile)

    if USING_VC_SSE2:
        expected_profile = \
            np.array([144.03694724, 63.06874155, 51.84694887, 39.6374044,
                      31.84981429, 44.3778833, 37.84961761, 38.00509734,
                      38.67423812, 38.47003306])
    elif USING_GCC_SSE2:
        expected_profile = \
            np.array([144.03694724, 63.06874148, 51.84694881, 39.63740417,
                      31.84981481, 44.37788414, 37.84961844, 38.00509881,
                      38.67423954, 38.47003339])

    assert_array_almost_equal(energy_profile, expected_profile, decimal=4)
Ejemplo n.º 5
0
def test_em_3d_demons():
    r'''
    Register a stack of circles ('cylinder') before and after warping them with
    a synthetic diffeomorphism. This test
    is intended to detect regressions only: we saved the energy profile (the
    sequence of energy values at each iteration) of a working version of EM in
    3D, and this test checks that the current energy profile matches the saved
    one. The validation of the "working version" was
    done by registering the 18 manually annotated T1 brain MRI database IBSR
    with each other and computing the jaccard index for all 31 common
    anatomical regions. The "working version" of EM in 3D obtains very similar
    results as those reported for ANTS on the same database. Any modification
    that produces a change in the energy profile should be carefully validated
    to ensure no accuracy loss.
    '''
    moving, static = get_synthetic_warped_circle(30)
    moving[...,:8] = 0
    moving[...,-1:-9:-1] = 0
    static[...,:8] = 0
    static[...,-1:-9:-1] = 0

    #Create the EM metric
    smooth=25.0
    inner_iter=20
    step_length=0.25
    q_levels=256
    double_gradient=True
    iter_type='demons'
    similarity_metric = metrics.EMMetric(
        3, smooth, inner_iter, q_levels, double_gradient, iter_type)

    #Create the optimizer
    level_iters = [10, 5]
    opt_tol = 1e-4
    inv_iter = 20
    inv_tol = 1e-3
    ss_sigma_factor = 0.5
    optimizer = imwarp.SymmetricDiffeomorphicRegistration(similarity_metric,
        level_iters, step_length, ss_sigma_factor, opt_tol, inv_iter, inv_tol)
    optimizer.verbosity = VerbosityLevels.DEBUG
    mapping = optimizer.optimize(static, moving, None)
    m = optimizer.get_map()
    assert_equal(mapping, m)
    energy_profile = subsample_profile(
        optimizer.full_energy_profile, 10)
    print(energy_profile)

    if USING_VC_SSE2:
        expected_profile = \
            np.array([144.03694708, 122.39512307, 111.31925381, 90.9100989,
                      93.93705232, 104.22993997, 110.57817867, 140.45262039,
                      133.87804571, 119.20794977])
    elif USING_GCC_SSE2:
        expected_profile = \
            np.array([144.03694708, 122.39512227, 111.31924572, 90.91010482,
                      93.93707059, 104.22996918, 110.57822649, 140.45298465,
                      133.87831302, 119.20826433])

    assert_array_almost_equal(energy_profile, expected_profile, decimal=4)
Ejemplo n.º 6
0
def test_em_3d_gauss_newton():
    r'''
    Register a stack of circles ('cylinder') before and after warping them with
    a synthetic diffeomorphism. This test
    is intended to detect regressions only: we saved the energy profile (the
    sequence of energy values at each iteration) of a working version of EM in
    3D, and this test checks that the current energy profile matches the saved
    one. The validation of the "working version" was
    done by registering the 18 manually annotated T1 brain MRI database IBSR
    with each other and computing the jaccard index for all 31 common anatomical
    regions. The "working version" of EM in 3D obtains very similar results as
    those reported for ANTS on the same database. Any modification that produces
    a change in the energy profile should be carefully validated to ensure no
    accuracy loss.
    '''
    moving, static = get_synthetic_warped_circle(30)
    moving[...,:8] = 0
    moving[...,-1:-9:-1] = 0
    static[...,:8] = 0
    static[...,-1:-9:-1] = 0

    #Create the EM metric
    smooth=25.0
    inner_iter=20
    step_length=0.25
    q_levels=256
    double_gradient=True
    iter_type='gauss_newton'
    similarity_metric = metrics.EMMetric(
        3, smooth, inner_iter, q_levels, double_gradient, iter_type)

    #Create the optimizer
    level_iters = [10, 5]
    opt_tol = 1e-4
    inv_iter = 20
    inv_tol = 1e-3
    ss_sigma_factor = 0.5
    optimizer = imwarp.SymmetricDiffeomorphicRegistration(similarity_metric,
        level_iters, step_length, ss_sigma_factor, opt_tol, inv_iter, inv_tol)
    optimizer.verbosity = VerbosityLevels.DEBUG
    mapping = optimizer.optimize(static, moving, None)
    m = optimizer.get_map()
    assert_equal(mapping, m)
    energy_profile = np.array(optimizer.full_energy_profile)
    if floating is np.float32:
        expected_profile = \
            np.array([144.03694724, 63.06898905, 51.84577681, 39.75409677,
                      32.10342869, 44.84663951, 38.48587153, 36.64351228, 
                      37.14853803, 40.07766093, 1686.24351443, 1500.19633766,
                      1302.04852831, 1148.19549508, 1032.820053])
    else:
        expected_profile = \
            np.array([144.03695787, 63.06894122, 51.84575143, 39.75308705,
                      32.13062096, 44.15214831, 40.71952511, 37.26523679,
                      37.86654915, 34.92844873, 1644.56890565, 1408.15872151,
                      1274.1339093, 1131.38037004, 1004.71854514])
    assert_array_almost_equal(energy_profile, expected_profile, decimal=6)
Ejemplo n.º 7
0
def test_cc_3d():
    r'''
    Register a stack of circles ('cylinder') before and after warping them with
    a synthetic diffeomorphism. This test
    is intended to detect regressions only: we saved the energy profile (the
    sequence of energy values at each iteration) of a working version of CC in
    3D, and this test checks that the current energy profile matches the saved
    one. The validation of the "working version" was
    done by registering the 18 manually annotated T1 brain MRI database IBSR
    with each other and computing the jaccard index for all 31 common anatomical
    regions. The "working version" of CC in 3D obtains very similar results as
    those reported for ANTS on the same database with the same number of
    iterations. Any modification that produces a change in the energy profile
    should be carefully validated to ensure no accuracy loss.
    '''
    moving, static = moving, static = get_synthetic_warped_circle(20)

    #Create the CC metric
    sigma_diff = 2.0
    radius = 4
    similarity_metric = metrics.CCMetric(3, sigma_diff, radius)

    #Create the optimizer
    level_iters = [20, 10]
    step_length = 0.25
    opt_tol = 1e-4
    inv_iter = 20
    inv_tol = 1e-3
    ss_sigma_factor = 0.5
    optimizer = imwarp.SymmetricDiffeomorphicRegistration(similarity_metric,
        level_iters, step_length, ss_sigma_factor, opt_tol, inv_iter, inv_tol)
    optimizer.verbosity = VerbosityLevels.DEBUG

    mapping = optimizer.optimize(static, moving, None, None, None)
    m = optimizer.get_map()
    assert_equal(mapping, m)
    energy_profile = np.array(optimizer.full_energy_profile)*1e-4
    if floating is np.float32:
        expected_profile = \
            [-0.17136006, -0.1927569, -0.20436096, -0.20785162, -0.20389074,
             -0.20924245, -0.20703476, -0.20914331, -0.20797673, -0.20894931,
             -0.20861396, -0.20884857, -0.20867266, -0.20892447, -0.20721796,
             -0.20964756, -3.03669258, -3.08002058, -3.07073973, -3.06754953,
             -3.06459596, -3.08409787, -3.08325558, -3.08083075, -3.08227744,
             -3.08802501]
    else:
        expected_profile = \
            [-0.17416006, -0.1937569, -0.20776097, -0.21125163, -0.20709075,
             -0.21184246, -0.21003478, -0.21214333, -0.21117674, -0.21194933,
             -0.21141397, -0.21184858, -0.21147268, -0.21232447, -0.211618,
             -0.21264758, -3.13589338, -3.29324761, -3.3906351, -3.46849833,
             -3.51429254, -3.51747425, -3.5175145, -3.52346059, -3.51608344,
             -3.53157882]
    expected_profile = np.asarray(expected_profile)
    assert_array_almost_equal(energy_profile, expected_profile, decimal=6)
Ejemplo n.º 8
0
def test_ssd_3d_gauss_newton():
    r'''
    Register a stack of circles ('cylinder') before and after warping them with
    a synthetic diffeomorphism. This test is intended to detect regressions
    only: we saved the energy profile (the sequence of energy values at each
    iteration) of a working version of SSD in 3D using the Gauss-Newton step,
    and this test checks that the current energy profile matches the saved
    one. The validation of the "working version" was
    done by registering the 18 manually annotated T1 brain MRI database IBSR
    with each other and computing the jaccard index for all 31 common
    anatomical regions.
    '''
    moving, static = get_synthetic_warped_circle(35)
    moving[...,:10] = 0
    moving[...,-1:-11:-1] = 0
    static[...,:10] = 0
    static[...,-1:-11:-1] = 0

    #Create the SSD metric
    smooth = 4
    inner_iter = 5
    step_type = 'gauss_newton'
    similarity_metric = metrics.SSDMetric(3, smooth, inner_iter, step_type)

    #Create the optimizer
    level_iters = [10, 5]
    step_length = 0.25
    opt_tol = 1e-4
    inv_iter = 20
    inv_tol = 1e-3
    ss_sigma_factor = 0.5
    optimizer = imwarp.SymmetricDiffeomorphicRegistration(similarity_metric,
        level_iters, step_length, ss_sigma_factor, opt_tol, inv_iter, inv_tol)
    optimizer.verbosity = VerbosityLevels.DEBUG
    mapping = optimizer.optimize(static, moving, None)
    m = optimizer.get_map()
    assert_equal(mapping, m)
    energy_profile = subsample_profile(
        optimizer.full_energy_profile, 10)
    print(energy_profile)

    if USING_VC_SSE2:
        expected_profile = \
            np.array([348.3204721, 143.480757, 44.30003405, 8.73624842,
                      3.13227203, 14.70806563, 6.48360268, 23.52491883,
                      17.25669088, 48.99709064])
    elif USING_GCC_SSE2:
        expected_profile = \
            np.array([348.3204721, 143.48075646, 44.30003413, 8.73624841,
                      3.13227181, 14.70806845, 6.48360884, 23.52499421,
                      17.25667176, 48.997691])

    assert_array_almost_equal(energy_profile, expected_profile, decimal=4)
Ejemplo n.º 9
0
def test_ssd_3d_demons():
    r'''
    Register a stack of circles ('cylinder') before and after warping them
    with a synthetic diffeomorphism. This test is intended to detect
    regressions only: we saved the energy profile (the sequence of energy
    values at each iteration) of a working version of SSD in 3D using the
    Demons step, and this test checks that the current energy profile matches
    the saved one. The validation of the "working version" was done by
    registering the 18 manually annotated T1 brain MRI database IBSR with each
    other and computing the jaccard index for all 31 common anatomical regions.
    '''
    moving, static = get_synthetic_warped_circle(30)
    moving[..., :8] = 0
    moving[..., -1:-9:-1] = 0
    static[..., :8] = 0
    static[..., -1:-9:-1] = 0

    #Create the SSD metric
    smooth = 4
    step_type = 'demons'
    similarity_metric = metrics.SSDMetric(3,
                                          smooth=smooth,
                                          step_type=step_type)

    #Create the optimizer
    level_iters = [10, 5]
    step_length = 0.25
    opt_tol = 1e-4
    inv_iter = 20
    inv_tol = 1e-3
    ss_sigma_factor = 0.5
    optimizer = imwarp.SymmetricDiffeomorphicRegistration(
        similarity_metric, level_iters, step_length, ss_sigma_factor, opt_tol,
        inv_iter, inv_tol)
    optimizer.verbosity = VerbosityLevels.DEBUG
    mapping = optimizer.optimize(static, moving, None)
    m = optimizer.get_map()
    assert_equal(mapping, m)
    energy_profile = subsample_profile(optimizer.full_energy_profile, 10)
    print(energy_profile)

    if USING_VC_SSE2:
        expected_profile = \
            np.array([312.22706987, 154.65556884, 53.88543188, 9.11484007,
                      36.46592407, 13.20522299, 48.65663399, 14.91579802,
                      49.82954704, 14.92646254])
    elif USING_GCC_SSE2:
        expected_profile = \
            np.array([312.22706987, 154.65556885, 53.88455398, 9.11770682,
                      36.48642824, 13.21706748, 48.67710635, 14.91782047,
                      49.84142899, 14.92531294])

    assert_array_almost_equal(energy_profile, expected_profile, decimal=4)
Ejemplo n.º 10
0
def test_ssd_3d_gauss_newton():
    r'''
    Register a stack of circles ('cylinder') before and after warping them with
    a synthetic diffeomorphism. This test is intended to detect regressions
    only: we saved the energy profile (the sequence of energy values at each
    iteration) of a working version of SSD in 3D using the Gauss-Newton step,
    and this test checks that the current energy profile matches the saved
    one. The validation of the "working version" was
    done by registering the 18 manually annotated T1 brain MRI database IBSR
    with each other and computing the jaccard index for all 31 common anatomical
    regions.
    '''
    moving, static = get_synthetic_warped_circle(35)
    moving[...,:10] = 0
    moving[...,-1:-11:-1] = 0
    static[...,:10] = 0
    static[...,-1:-11:-1] = 0

    #Create the SSD metric
    smooth = 4
    inner_iter = 5
    step_type = 'gauss_newton'
    similarity_metric = metrics.SSDMetric(3, smooth, inner_iter, step_type)

    #Create the optimizer
    level_iters = [10, 5]
    step_length = 0.25
    opt_tol = 1e-4
    inv_iter = 20
    inv_tol = 1e-3
    ss_sigma_factor = 0.5
    optimizer = imwarp.SymmetricDiffeomorphicRegistration(similarity_metric,
        level_iters, step_length, ss_sigma_factor, opt_tol, inv_iter, inv_tol)
    optimizer.verbosity = VerbosityLevels.DEBUG
    mapping = optimizer.optimize(static, moving, None)
    m = optimizer.get_map()
    assert_equal(mapping, m)
    energy_profile = np.array(optimizer.full_energy_profile)
    if floating is np.float32:
        expected_profile = \
            np.array([348.32047209927373, 143.49111863234222, 44.328151771258206,
                      8.759564367010988, 3.1378191742723662, 14.846951961939153,
                      6.405154727081836, 20.437036950018083, 17.399044912417597,
                      49.072929423423496, 269.2553956858318, 80.72079256138973,
                      200.242742072974, 68.21238489882822, 208.28730597575378])
    else:
        expected_profile = \
            np.array([348.32049916992855, 143.49111631974688, 44.328145727486174,
                      8.759562612294948, 3.137819214539283, 14.846929648490525,
                      6.405154001052728, 20.437123731745928, 17.39892098642616,
                      49.07339619667625, 269.2533380585498, 80.72162511785703,
                      200.24505477294477, 68.21183884286609, 208.29025925025073])
    assert_array_almost_equal(energy_profile, expected_profile, decimal=6)
Ejemplo n.º 11
0
def test_cc_3d():
    r'''
    Register a stack of circles ('cylinder') before and after warping them with
    a synthetic diffeomorphism. This test
    is intended to detect regressions only: we saved the energy profile (the
    sequence of energy values at each iteration) of a working version of CC in
    3D, and this test checks that the current energy profile matches the saved
    one. The validation of the "working version" was done by registering the
    18 manually annotated T1 brain MRI database IBSR with each other and
    computing the jaccard index for all 31 common anatomical regions. The
    "working version" of CC in 3D obtains very similar results as
    those reported for ANTS on the same database with the same number of
    iterations. Any modification that produces a change in the energy profile
    should be carefully validated to ensure no accuracy loss.
    '''
    moving, static = moving, static = get_synthetic_warped_circle(20)

    #Create the CC metric
    sigma_diff = 2.0
    radius = 4
    similarity_metric = metrics.CCMetric(3, sigma_diff, radius)

    #Create the optimizer
    level_iters = [20, 10]
    step_length = 0.25
    opt_tol = 1e-4
    inv_iter = 20
    inv_tol = 1e-3
    ss_sigma_factor = 0.5
    optimizer = imwarp.SymmetricDiffeomorphicRegistration(
        similarity_metric, level_iters, step_length, ss_sigma_factor, opt_tol,
        inv_iter, inv_tol)
    optimizer.verbosity = VerbosityLevels.DEBUG

    mapping = optimizer.optimize(static, moving, None, None, None)
    m = optimizer.get_map()
    assert_equal(mapping, m)
    energy_profile = subsample_profile(optimizer.full_energy_profile,
                                       10) * 1e-4
    print(energy_profile)

    if USING_VC_SSE2:
        expected_profile = \
            [-0.17336006, -0.20516197, -0.20448353, -0.20630727, -0.20652892,
             -0.2073403, -3.0046531, -3.43771429, -3.47262116, -3.51383381]
    elif USING_GCC_SSE2:
        expected_profile = \
            [-0.17136006, -0.20632291, -0.2038927, -0.20688352, -0.20821154,
             -0.20909298, -0.20872891, -0.20933514, -3.06861497, -3.07851062]

    expected_profile = np.asarray(expected_profile)
    assert_array_almost_equal(energy_profile, expected_profile, decimal=4)
Ejemplo n.º 12
0
def test_em_3d_demons():
    r""" Test 3D SyN with EM metric, demons-like optimizer

    Register a volume created by stacking copies of a coronal slice from
    a T1w brain MRI before and after warping it under a synthetic
    invertible map. We verify that the final registration is of good
    quality.
    """
    fname = get_fnames('t1_coronal_slice')
    nslices = 21
    b = 0.1
    m = 4

    image = np.load(fname)
    moving, static = get_warped_stacked_image(image, nslices, b, m)

    # Create the EM metric
    smooth = 2.0
    inner_iter = 20
    step_length = 0.25
    q_levels = 256
    double_gradient = True
    iter_type = 'demons'
    similarity_metric = metrics.EMMetric(
        3, smooth, inner_iter, q_levels, double_gradient, iter_type)

    # Create the optimizer
    level_iters = [20, 5]
    opt_tol = 1e-4
    inv_iter = 20
    inv_tol = 1e-3
    ss_sigma_factor = 1.0
    optimizer = imwarp.SymmetricDiffeomorphicRegistration(
        similarity_metric,
        level_iters,
        step_length,
        ss_sigma_factor,
        opt_tol,
        inv_iter,
        inv_tol)
    optimizer.verbosity = VerbosityLevels.DEBUG
    mapping = optimizer.optimize(static, moving, None)
    m = optimizer.get_map()
    assert_equal(mapping, m)

    warped = mapping.transform(moving)
    starting_energy = np.sum((static - moving)**2)
    final_energy = np.sum((static - warped)**2)
    reduced = 1.0 - final_energy / starting_energy

    assert(reduced > 0.9)
Ejemplo n.º 13
0
def test_optimizer_exceptions():
    #An arbitrary valid metric
    metric = metrics.SSDMetric(2)
    # The metric must not be None
    assert_raises(ValueError, imwarp.SymmetricDiffeomorphicRegistration, None)
    # The iterations list must not be empty
    assert_raises(ValueError, imwarp.SymmetricDiffeomorphicRegistration, metric, [])

    optimizer = imwarp.SymmetricDiffeomorphicRegistration(metric, None)
    #Verify the default iterations list
    assert_array_equal(optimizer.level_iters, [100,100,25])

    #Verify exception thrown when attepting to fit the energy profile without enough data
    assert_raises(ValueError, optimizer._get_energy_derivative)
Ejemplo n.º 14
0
def test_ssd_3d_demons():
    r'''
    Register a stack of circles ('cylinder') before and after warping them with
    a synthetic diffeomorphism. This test is intended to detect regressions
    only: we saved the energy profile (the sequence of energy values at each
    iteration) of a working version of SSD in 3D using the Demons step, and this
    test checks that the current energy profile matches the saved one. The
    validation of the "working version" was done by registering the 18 manually
    annotated T1 brain MRI database IBSR with each other and computing the
    jaccard index for all 31 common anatomical regions.
    '''
    moving, static = get_synthetic_warped_circle(30)
    moving[...,:8] = 0
    moving[...,-1:-9:-1] = 0
    static[...,:8] = 0
    static[...,-1:-9:-1] = 0

    #Create the SSD metric
    smooth = 4
    step_type = 'demons'
    similarity_metric = metrics.SSDMetric(3, smooth=smooth, step_type=step_type)

    #Create the optimizer
    level_iters = [10, 5]
    step_length = 0.25
    opt_tol = 1e-4
    inv_iter = 20
    inv_tol = 1e-3
    ss_sigma_factor = 0.5
    optimizer = imwarp.SymmetricDiffeomorphicRegistration(similarity_metric,
        level_iters, step_length, ss_sigma_factor, opt_tol, inv_iter, inv_tol)
    optimizer.verbosity = VerbosityLevels.DEBUG
    mapping = optimizer.optimize(static, moving, None)
    m = optimizer.get_map()
    assert_equal(mapping, m)
    energy_profile = np.array(optimizer.full_energy_profile)
    if floating is np.float32:
        expected_profile = \
            np.array([312.22706987, 154.65556885, 53.88594419, 9.22626825,
                      36.50370933, 13.54829978, 49.57619437, 15.71122527,
                      53.45897119, 15.62018739, 521.95785712, 158.16217928,
                      182.49116432, 144.91081752, 176.6810387])
    else:
        expected_profile = \
            np.array([312.22709468, 154.65706498, 53.8856324, 8.90160898,
                      34.91911552, 12.66043296, 49.61341791, 15.14198327,
                      52.25467529, 18.88243845, 490.48088231, 149.29027701,
                      192.26219053, 137.5291187, 187.2795753])
    assert_array_almost_equal(energy_profile, expected_profile, decimal=6)
Ejemplo n.º 15
0
def test_cc_3d():
    r""" Test 3D SyN with CC metric

    Register a volume created by stacking copies of a coronal slice from
    a T1w brain MRI before and after warping it under a synthetic
    invertible map. We verify that the final registration is of good
    quality.
    """
    fname = get_fnames('t1_coronal_slice')
    nslices = 21
    b = 0.1
    m = 4

    image = np.load(fname)
    moving, static = get_warped_stacked_image(image, nslices, b, m)

    # Create the CC metric
    sigma_diff = 2.0
    radius = 2
    similarity_metric = metrics.CCMetric(3, sigma_diff, radius)

    # Create the optimizer
    level_iters = [20, 5]
    step_length = 0.25
    opt_tol = 1e-4
    inv_iter = 20
    inv_tol = 1e-3
    ss_sigma_factor = 0.2
    optimizer = imwarp.SymmetricDiffeomorphicRegistration(
        similarity_metric,
        level_iters,
        step_length,
        ss_sigma_factor,
        opt_tol,
        inv_iter,
        inv_tol)
    optimizer.verbosity = VerbosityLevels.DEBUG

    mapping = optimizer.optimize(static, moving, None, None, None)
    m = optimizer.get_map()
    assert_equal(mapping, m)

    warped = mapping.transform(moving)
    starting_energy = np.sum((static - moving)**2)
    final_energy = np.sum((static - warped)**2)
    reduced = 1.0 - final_energy / starting_energy

    assert(reduced > 0.9)
Ejemplo n.º 16
0
def test_ssd_3d_gauss_newton():
    r""" Test 3D SyN with SSD metric, Gauss-Newton optimizer

    Register a stack of circles ('cylinder') before and after warping them
    with a synthetic diffeomorphism. We verify that the final registration
    is of good quality.
    """
    moving, static = get_synthetic_warped_circle(35)
    moving[..., :10] = 0
    moving[..., -1:-11:-1] = 0
    static[..., :10] = 0
    static[..., -1:-11:-1] = 0

    # Create the SSD metric
    smooth = 4
    inner_iter = 5
    step_type = 'gauss_newton'
    similarity_metric = metrics.SSDMetric(3, smooth, inner_iter, step_type)

    # Create the optimizer
    level_iters = [10, 10]
    step_length = 0.1
    opt_tol = 1e-4
    inv_iter = 20
    inv_tol = 1e-3
    ss_sigma_factor = 0.5
    optimizer = imwarp.SymmetricDiffeomorphicRegistration(
        similarity_metric,
        level_iters,
        step_length,
        ss_sigma_factor,
        opt_tol,
        inv_iter,
        inv_tol)
    optimizer.verbosity = VerbosityLevels.DEBUG
    mapping = optimizer.optimize(static, moving, None)
    m = optimizer.get_map()
    assert_equal(mapping, m)

    warped = mapping.transform(moving)
    starting_energy = np.sum((static - moving)**2)
    final_energy = np.sum((static - warped)**2)
    reduced = 1.0 - final_energy / starting_energy

    assert(reduced > 0.9)
Ejemplo n.º 17
0
def test_em_2d_demons():
    r'''
    Register a circle to itself after warping it under a synthetic invertible
    map. This test is intended to detect regressions only: we saved the energy
    profile (the sequence of energy values at each iteration) of a working
    version of EM in 2D, and this test checks that the current energy profile
    matches the saved one.
    '''

    moving, static = get_synthetic_warped_circle(1)

    #Configure the metric
    smooth=25.0
    inner_iter=20
    q_levels=256
    double_gradient=False
    iter_type='demons'
    metric = metrics.EMMetric(
        2, smooth, inner_iter, q_levels, double_gradient, iter_type)

    #Configure and run the Optimizer
    level_iters = [40, 20, 10]
    optimizer = imwarp.SymmetricDiffeomorphicRegistration(metric, level_iters)
    optimizer.verbosity = VerbosityLevels.DEBUG
    mapping = optimizer.optimize(static, moving, None)
    m = optimizer.get_map()
    assert_equal(mapping, m)
    energy_profile = subsample_profile(
        optimizer.full_energy_profile, 10)
    print(energy_profile)

    if USING_VC_SSE2:
        expected_profile = \
            [2.50773393, 3.26942324, 1.81684393, 5.44878881, 40.0195918,
             31.87030788, 25.15710409, 29.82206485, 196.33114499, 213.86419995]
    elif USING_GCC_SSE2:
        expected_profile = \
            [2.50773393, 3.26942352, 1.8168445, 5.44879264, 40.01956373,
             31.65616398, 32.43115903, 35.24130742, 192.89072697, 195.456909]

    assert_array_almost_equal(energy_profile, np.array(expected_profile),
                              decimal=5)
Ejemplo n.º 18
0
def test_em_2d_gauss_newton():
    r'''
    Register a circle to itself after warping it under a synthetic invertible
    map. This test is intended to detect regressions only: we saved the energy
    profile (the sequence of energy values at each iteration) of a working
    version of EM in 2D, and this test checks that the current energy profile
    matches the saved one.
    '''

    moving, static = get_synthetic_warped_circle(1)

    #Configure the metric
    smooth=25.0
    inner_iter=20
    q_levels=256
    double_gradient=False
    iter_type='gauss_newton'
    metric = metrics.EMMetric(
        2, smooth, inner_iter, q_levels, double_gradient, iter_type)

    #Configure and run the Optimizer
    level_iters = [40, 20, 10]
    optimizer = imwarp.SymmetricDiffeomorphicRegistration(metric, level_iters)
    optimizer.verbosity = VerbosityLevels.DEBUG
    mapping = optimizer.optimize(static, moving, None)
    m = optimizer.get_map()
    assert_equal(mapping, m)
    energy_profile = subsample_profile(
        optimizer.full_energy_profile, 10)
    print(energy_profile)

    if USING_VC_SSE2:
        expected_profile = \
            [2.50773392, 0.41762978, 0.30900322, 0.14818498, 0.44620725,
             1.53134054, 1.42115728, 1.66358267, 1.184265, 46.13635772]
    elif USING_GCC_SSE2:
        expected_profile = \
            [2.50773392, 0.41763383, 0.30908578, 0.06241115, 0.11573476,
             2.48475885, 1.10053769, 0.9270271, 49.37186785, 44.72643467]

    assert_array_almost_equal(energy_profile, np.array(expected_profile),
                              decimal=5)
Ejemplo n.º 19
0
def test_em_2d_demons():
    r'''
    Register a circle to itself after warping it under a synthetic invertible
    map. This test is intended to detect regressions only: we saved the energy
    profile (the sequence of energy values at each iteration) of a working
    version of EM in 2D, and this test checks that the current energy profile
    matches the saved one.
    '''

    moving, static = get_synthetic_warped_circle(1)

    #Configure the metric
    smooth=25.0
    inner_iter=20
    q_levels=256
    double_gradient=False
    iter_type='demons'
    metric = metrics.EMMetric(
        2, smooth, inner_iter, q_levels, double_gradient, iter_type)

    #Configure and run the Optimizer
    level_iters = [40, 20, 10]
    optimizer = imwarp.SymmetricDiffeomorphicRegistration(metric, level_iters)
    optimizer.verbosity = VerbosityLevels.DEBUG
    mapping = optimizer.optimize(static, moving, None)
    m = optimizer.get_map()
    assert_equal(mapping, m)
    energy_profile = np.array(optimizer.full_energy_profile)[::2]
    if floating is np.float32:
        expected_profile = \
            [2.50773393, 4.59842633, 3.94307794, 3.09777134, 2.57982865,
             3.24937725, 0.42507437, 2.59523238, 29.8114103, 34.94621044,
             27.49480758, 38.64567224, 28.14442977, 25.34123425, 36.95076494,
             192.36444764, 202.90168694, 188.44310016, 199.73662253, 193.81159141]
    else:
        expected_profile = \
            [2.50773436, 4.59843299, 3.94307817, 3.09777401, 2.57983375,
             3.24936765, 0.42506361, 2.5952175, 29.81143768, 33.42148555,
             29.04341476, 29.44541313, 27.39435491, 27.62029669, 187.34889413,
             206.57998934, 198.48724278, 188.65410869, 177.83943006]
    assert_array_almost_equal(energy_profile, np.array(expected_profile))
Ejemplo n.º 20
0
def test_em_2d_gauss_newton():
    r'''
    Register a circle to itself after warping it under a synthetic invertible
    map. This test is intended to detect regressions only: we saved the energy
    profile (the sequence of energy values at each iteration) of a working
    version of EM in 2D, and this test checks that the current energy profile
    matches the saved one.
    '''

    moving, static = get_synthetic_warped_circle(1)

    #Configure the metric
    smooth=25.0
    inner_iter=20
    q_levels=256
    double_gradient=False
    iter_type='gauss_newton'
    metric = metrics.EMMetric(
        2, smooth, inner_iter, q_levels, double_gradient, iter_type)

    #Configure and run the Optimizer
    level_iters = [40, 20, 10]
    optimizer = imwarp.SymmetricDiffeomorphicRegistration(metric, level_iters)
    optimizer.verbosity = VerbosityLevels.DEBUG
    mapping = optimizer.optimize(static, moving, None)
    m = optimizer.get_map()
    assert_equal(mapping, m)
    energy_profile = np.array(optimizer.full_energy_profile)[::4]
    if floating is np.float32:
        expected_profile = \
            [2.50773392e+00, 1.19082175e+00, 3.44192871e-01, 4.26320783e-01,
             3.77910892e-02, 3.34404847e-01, 3.00400618e+00, 2.56292691e+00,
             2.10458398e+00, 2.45479897e+00, 6.14513257e+01, 5.38091115e+01,
             5.27868250e+01]
    else:
        expected_profile = \
            [2.50773436, 1.19082577, 0.34422934, 0.19543193, 0.23659461,
             0.41145348, 3.56414698, 3.02325691, 1.74649377, 1.8172007,
             2.09930208, 53.06513917, 49.4088898 ]
    assert_array_almost_equal(energy_profile, np.array(expected_profile))
Ejemplo n.º 21
0
def test_em_2d_gauss_newton():
    r""" Test 2D SyN with EM metric, Gauss-Newton optimizer

    Register a coronal slice from a T1w brain MRI before and after warping
    it under a synthetic invertible map. We verify that the final
    registration is of good quality.
    """

    fname = get_fnames('t1_coronal_slice')
    nslices = 1
    b = 0.1
    m = 4

    image = np.load(fname)
    moving, static = get_warped_stacked_image(image, nslices, b, m)

    # Configure the metric
    smooth = 5.0
    inner_iter = 20
    q_levels = 256
    double_gradient = False
    iter_type = 'gauss_newton'
    metric = metrics.EMMetric(2, smooth, inner_iter, q_levels, double_gradient,
                              iter_type)

    # Configure and run the Optimizer
    level_iters = [40, 20, 10]
    optimizer = imwarp.SymmetricDiffeomorphicRegistration(metric, level_iters)
    optimizer.verbosity = VerbosityLevels.DEBUG
    mapping = optimizer.optimize(static, moving, None)
    m = optimizer.get_map()
    assert_equal(mapping, m)

    warped = mapping.transform(moving)
    starting_energy = np.sum((static - moving)**2)
    final_energy = np.sum((static - warped)**2)
    reduced = 1.0 - final_energy / starting_energy

    assert (reduced > 0.9)
Ejemplo n.º 22
0
def test_cc_2d():
    r'''
    Register a circle to itself after warping it under a synthetic invertible
    map. This test is intended to detect regressions only: we saved the energy
    profile (the sequence of energy values at each iteration) of a working
    version of CC in 2D, and this test checks that the current energy profile
    matches the saved one.
    '''

    moving, static = get_synthetic_warped_circle(1)
    #Configure the metric
    sigma_diff = 3.0
    radius = 4
    metric = metrics.CCMetric(2, sigma_diff, radius)

    #Configure and run the Optimizer
    level_iters = [10, 5]
    optimizer = imwarp.SymmetricDiffeomorphicRegistration(metric, level_iters)
    optimizer.verbosity = VerbosityLevels.DEBUG
    mapping = optimizer.optimize(static, moving, None)
    m = optimizer.get_map()
    assert_equal(mapping, m)
    energy_profile = subsample_profile(
        optimizer.full_energy_profile, 10)
    print(energy_profile)

    if USING_VC_SSE2:
        expected_profile = \
            [-681.02276193, -910.57721051, -1012.76781394, -1021.24181308,
             -1016.97233745, -977.35458126, -1013.90114894, -989.04516449,
             -1021.72431465, -988.46698723]
    elif USING_GCC_SSE2:
        expected_profile = \
            [-681.02276236, -920.57714783, -1008.82241171, -1021.91021701,
             -994.86961164, -1026.52978164, -1015.83587405, -1020.02780802,
             -993.8576053, -1026.4369566 ]

    expected_profile = np.asarray(expected_profile)
    assert_array_almost_equal(energy_profile, expected_profile, decimal=5)
Ejemplo n.º 23
0
def test_cc_2d():
    r'''
    Register a circle to itself after warping it under a synthetic invertible
    map. This test is intended to detect regressions only: we saved the energy
    profile (the sequence of energy values at each iteration) of a working
    version of CC in 2D, and this test checks that the current energy profile
    matches the saved one.
    '''

    moving, static = get_synthetic_warped_circle(1)
    #Configure the metric
    sigma_diff = 3.0
    radius = 4
    metric = metrics.CCMetric(2, sigma_diff, radius)

    #Configure and run the Optimizer
    level_iters = [10, 5]
    optimizer = imwarp.SymmetricDiffeomorphicRegistration(metric, level_iters)
    optimizer.verbosity = VerbosityLevels.DEBUG
    mapping = optimizer.optimize(static, moving, None)
    m = optimizer.get_map()
    assert_equal(mapping, m)
    energy_profile = np.array(optimizer.full_energy_profile)
    if floating is np.float32:
        expected_profile = \
            [-681.02276236, -920.57714783, -1006.81657463, -1025.83920278,
             -1018.48108319, -1018.45000627, -1005.09703188, -1012.69584487,
             -1016.42673146, -998.88289898, -2788.28110913, -2829.93521983,
             -2823.50737329, -2840.70676978, -2805.36486487]
    else:
        expected_profile = \
            [-685.02275452, -928.57719958, -1018.81655195, -1025.39899865,
             -1002.72673624, -1009.50734392, -1017.17915308, -999.55456055,
             -1025.76154939, -994.94755395, -2784.70111646, -2820.40702267,
             -2801.45275665, -2822.69658715, -2813.39864684]
    expected_profile = np.asarray(expected_profile)
    assert_array_almost_equal(energy_profile, expected_profile)
Ejemplo n.º 24
0
def compute_morph_map(img_m, img_s=None, niter_affine=(100, 100, 10),
                      niter_sdr=(5, 5, 3)):
    # get Static to world transform
    img_s_grid2world = img_s.affine

    # output Static as ndarray
    img_s = img_s.dataobj[:, :, :]

    # normalize values
    img_s = img_s.astype('float') / img_s.max()

    # get Moving to world transform
    img_m_grid2world = img_m.affine

    # output Moving as ndarray
    img_m = img_m.dataobj[:, :, :]

    # normalize values
    img_m = img_m.astype('float') / img_m.max()

    # compute center of mass
    c_of_mass = imaffine.transform_centers_of_mass(img_s, img_s_grid2world,
                                                   img_m, img_m_grid2world)

    nbins = 32

    # set up Affine Registration
    affreg = imaffine.AffineRegistration(
        metric=imaffine.MutualInformationMetric(nbins, None),
        level_iters=list(niter_affine),
        sigmas=[3.0, 1.0, 0.0],
        factors=[4, 2, 1])

    # translation
    translation = affreg.optimize(img_s, img_m,
                                  transforms.TranslationTransform3D(), None,
                                  img_s_grid2world, img_m_grid2world,
                                  starting_affine=c_of_mass.affine)

    # rigid body transform (translation + rotation)
    rigid = affreg.optimize(img_s, img_m,
                            transforms.RigidTransform3D(), None,
                            img_s_grid2world, img_m_grid2world,
                            starting_affine=translation.affine)

    # affine transform (translation + rotation + scaling)
    affine = affreg.optimize(img_s, img_m,
                             transforms.AffineTransform3D(), None,
                             img_s_grid2world, img_m_grid2world,
                             starting_affine=rigid.affine)

    # apply affine transformation
    img_m_affine = affine.transform(img_m)

    # set up Symmetric Diffeomorphic Registration (metric, iterations)
    sdr = imwarp.SymmetricDiffeomorphicRegistration(
        metrics.CCMetric(3), list(niter_sdr))

    # compute mapping
    mapping = sdr.optimize(img_s, img_m_affine)

    return mapping, affine
Ejemplo n.º 25
0
def _compute_morph_sdr(mri_from, mri_to, niter_affine, niter_sdr, zooms):
    """Get a matrix that morphs data from one subject to another."""
    import nibabel as nib
    with np.testing.suppress_warnings():
        from dipy.align import imaffine, imwarp, metrics, transforms
    from dipy.align.reslice import reslice

    logger.info('Computing nonlinear Symmetric Diffeomorphic Registration...')

    # reslice mri_from
    mri_from_res, mri_from_res_affine = reslice(
        _get_img_fdata(mri_from), mri_from.affine,
        mri_from.header.get_zooms()[:3], zooms)

    with warnings.catch_warnings():  # nibabel<->numpy warning
        mri_from = nib.Nifti1Image(mri_from_res, mri_from_res_affine)

    # reslice mri_to
    mri_to_res, mri_to_res_affine = reslice(
        _get_img_fdata(mri_to), mri_to.affine, mri_to.header.get_zooms()[:3],
        zooms)

    with warnings.catch_warnings():  # nibabel<->numpy warning
        mri_to = nib.Nifti1Image(mri_to_res, mri_to_res_affine)

    affine = mri_to.affine
    mri_to = _get_img_fdata(mri_to)  # to ndarray
    mri_to /= mri_to.max()
    mri_from_affine = mri_from.affine  # get mri_from to world transform
    mri_from = _get_img_fdata(mri_from)  # to ndarray
    mri_from /= mri_from.max()  # normalize

    # compute center of mass
    c_of_mass = imaffine.transform_centers_of_mass(
        mri_to, affine, mri_from, mri_from_affine)

    # set up Affine Registration
    affreg = imaffine.AffineRegistration(
        metric=imaffine.MutualInformationMetric(nbins=32),
        level_iters=list(niter_affine),
        sigmas=[3.0, 1.0, 0.0],
        factors=[4, 2, 1])

    # translation
    logger.info('Optimizing translation:')
    with wrapped_stdout(indent='    '):
        translation = affreg.optimize(
            mri_to, mri_from, transforms.TranslationTransform3D(), None,
            affine, mri_from_affine, starting_affine=c_of_mass.affine)

    # rigid body transform (translation + rotation)
    logger.info('Optimizing rigid-body:')
    with wrapped_stdout(indent='    '):
        rigid = affreg.optimize(
            mri_to, mri_from, transforms.RigidTransform3D(), None,
            affine, mri_from_affine, starting_affine=translation.affine)

    # affine transform (translation + rotation + scaling)
    logger.info('Optimizing full affine:')
    with wrapped_stdout(indent='    '):
        pre_affine = affreg.optimize(
            mri_to, mri_from, transforms.AffineTransform3D(), None,
            affine, mri_from_affine, starting_affine=rigid.affine)

    # compute mapping
    sdr = imwarp.SymmetricDiffeomorphicRegistration(
        metrics.CCMetric(3), list(niter_sdr))
    logger.info('Optimizing SDR:')
    with wrapped_stdout(indent='    '):
        sdr_morph = sdr.optimize(mri_to, pre_affine.transform(mri_from))
    shape = tuple(sdr_morph.domain_shape)  # should be tuple of int
    return shape, zooms, affine, pre_affine, sdr_morph
Ejemplo n.º 26
0
def test_ssd_2d_demons():
    r'''
    Classical Circle-To-C experiment for 2D Monomodal registration. This test
    is intended to detect regressions only: we saved the energy profile (the
    sequence of energy values at each iteration) of a working version of SSD in
    2D using the Demons step, and this test checks that the current energy
    profile matches the saved one.
    '''
    fname_moving = get_data('reg_o')
    fname_static = get_data('reg_c')

    moving = np.load(fname_moving)
    static = np.load(fname_static)
    moving = np.array(moving, dtype=floating)
    static = np.array(static, dtype=floating)
    moving = (moving-moving.min())/(moving.max() - moving.min())
    static = (static-static.min())/(static.max() - static.min())
    #Create the SSD metric
    smooth = 4
    step_type = 'demons'
    similarity_metric = metrics.SSDMetric(2, smooth=smooth, step_type=step_type)

    #Configure and run the Optimizer
    level_iters = [200, 100, 50, 25]
    step_length = 0.25
    opt_tol = 1e-4
    inv_iter = 40
    inv_tol = 1e-3
    ss_sigma_factor = 0.2
    optimizer = imwarp.SymmetricDiffeomorphicRegistration(similarity_metric,
        level_iters, step_length, ss_sigma_factor, opt_tol, inv_iter, inv_tol)

    #test callback being called
    optimizer.INIT_START_CALLED = 0
    optimizer.INIT_END_CALLED = 0
    optimizer.OPT_START_CALLED = 0
    optimizer.OPT_END_CALLED = 0
    optimizer.SCALE_START_CALLED = 0
    optimizer.SCALE_END_CALLED = 0
    optimizer.ITER_START_CALLED = 0
    optimizer.ITER_END_CALLED = 0

    optimizer.callback_counter_test = 0
    optimizer.callback = simple_callback

    optimizer.verbosity = VerbosityLevels.DEBUG
    mapping = optimizer.optimize(static, moving, None)
    m = optimizer.get_map()
    assert_equal(mapping, m)

    subsampled_energy_profile = np.array(optimizer.full_energy_profile[::10])
    if floating is np.float32:
        expected_profile = \
            np.array([312.6813333, 162.57756447, 99.2766679, 77.38698935,
                      61.75415204, 55.37420428, 46.36872571, 41.81811505,
                      36.38683617, 33.03952963, 30.91409901, 54.41447237,
                      23.40232241, 12.75092466, 10.19231733, 9.21058037,
                      57.4636143, 38.94004856, 36.26093212, 108.0136453,
                      81.35521049, 74.61956833])
    else:
        expected_profile = \
            np.array([312.68133361, 162.57744066, 99.27669798, 77.38683186,
                      61.75391429, 55.3740711, 46.36870776, 41.81809239,
                      36.3898153, 32.78365961, 30.69843811, 53.67073767,
                      21.74630524, 11.98102583, 11.51086685, 55.30707781,
                      39.88467545, 34.29444978, 33.10822964, 122.64743831,
                      84.18144073, 75.60088687])

    assert_array_almost_equal(subsampled_energy_profile, expected_profile)
    assert_equal(optimizer.OPT_START_CALLED, 1)
    assert_equal(optimizer.OPT_END_CALLED, 1)
    assert_equal(optimizer.SCALE_START_CALLED, 1)
    assert_equal(optimizer.SCALE_END_CALLED, 1)
    assert_equal(optimizer.ITER_START_CALLED, 1)
    assert_equal(optimizer.ITER_END_CALLED, 1)
Ejemplo n.º 27
0
def test_ssd_2d_gauss_newton():
    r'''
    Classical Circle-To-C experiment for 2D Monomodal registration. This test
    is intended to detect regressions only: we saved the energy profile (the
    sequence of energy values at each iteration) of a working version of SSD
    in 2D using the Gauss Newton step, and this test checks that the current
    energy profile matches the saved one.
    '''
    fname_moving = get_data('reg_o')
    fname_static = get_data('reg_c')

    moving = np.load(fname_moving)
    static = np.load(fname_static)
    moving = np.array(moving, dtype=floating)
    static = np.array(static, dtype=floating)
    moving = (moving-moving.min())/(moving.max() - moving.min())
    static = (static-static.min())/(static.max() - static.min())
    #Create the SSD metric
    smooth = 4
    inner_iter = 5
    step_type = 'gauss_newton'
    similarity_metric = metrics.SSDMetric(2, smooth, inner_iter, step_type)

    #Configure and run the Optimizer
    level_iters = [200, 100, 50, 25]
    step_length = 0.5
    opt_tol = 1e-4
    inv_iter = 40
    inv_tol = 1e-3
    ss_sigma_factor = 0.2
    optimizer = imwarp.SymmetricDiffeomorphicRegistration(similarity_metric,
        level_iters, step_length, ss_sigma_factor, opt_tol, inv_iter, inv_tol)

    #test callback not being called
    optimizer.INIT_START_CALLED = 0
    optimizer.INIT_END_CALLED = 0
    optimizer.OPT_START_CALLED = 0
    optimizer.OPT_END_CALLED = 0
    optimizer.SCALE_START_CALLED = 0
    optimizer.SCALE_END_CALLED = 0
    optimizer.ITER_START_CALLED = 0
    optimizer.ITER_END_CALLED = 0

    optimizer.verbosity = VerbosityLevels.DEBUG
    id = np.eye(3)
    mapping = optimizer.optimize(static, moving, id, id, id)
    m = optimizer.get_map()
    assert_equal(mapping, m)
    subsampled_energy_profile = subsample_profile(
        optimizer.full_energy_profile, 10)
    print(subsampled_energy_profile)

    if USING_VC_SSE2:
        expected_profile = \
            np.array([312.68133316, 70.17782995, 21.38508088, 96.41054776,
                      49.990781, 43.11867579, 24.53952718, 51.0786643,
                      143.24848252, 150.48349573])
    elif USING_GCC_SSE2:
        expected_profile = \
            np.array([312.68133316, 70.17782938, 21.26798507, 96.51765054,
                      51.1495088, 37.86204803, 21.62425293, 49.44868302,
                      121.6643917, 137.91427228])

    assert_array_almost_equal(subsampled_energy_profile, expected_profile,
                              decimal = 5)
    assert_equal(optimizer.OPT_START_CALLED, 0)
    assert_equal(optimizer.OPT_END_CALLED, 0)
    assert_equal(optimizer.SCALE_START_CALLED, 0)
    assert_equal(optimizer.SCALE_END_CALLED, 0)
    assert_equal(optimizer.ITER_START_CALLED, 0)
    assert_equal(optimizer.ITER_END_CALLED, 0)
Ejemplo n.º 28
0
def test_ssd_2d_demons():
    r'''
    Classical Circle-To-C experiment for 2D Monomodal registration. This test
    is intended to detect regressions only: we saved the energy profile (the
    sequence of energy values at each iteration) of a working version of SSD in
    2D using the Demons step, and this test checks that the current energy
    profile matches the saved one.
    '''
    fname_moving = get_data('reg_o')
    fname_static = get_data('reg_c')

    moving = np.load(fname_moving)
    static = np.load(fname_static)
    moving = np.array(moving, dtype=floating)
    static = np.array(static, dtype=floating)
    moving = (moving-moving.min())/(moving.max() - moving.min())
    static = (static-static.min())/(static.max() - static.min())
    #Create the SSD metric
    smooth = 4
    step_type = 'demons'
    similarity_metric = metrics.SSDMetric(2, smooth=smooth, step_type=step_type)

    #Configure and run the Optimizer
    level_iters = [200, 100, 50, 25]
    step_length = 0.25
    opt_tol = 1e-4
    inv_iter = 40
    inv_tol = 1e-3
    ss_sigma_factor = 0.2
    optimizer = imwarp.SymmetricDiffeomorphicRegistration(similarity_metric,
        level_iters, step_length, ss_sigma_factor, opt_tol, inv_iter, inv_tol)

    #test callback being called
    optimizer.INIT_START_CALLED = 0
    optimizer.INIT_END_CALLED = 0
    optimizer.OPT_START_CALLED = 0
    optimizer.OPT_END_CALLED = 0
    optimizer.SCALE_START_CALLED = 0
    optimizer.SCALE_END_CALLED = 0
    optimizer.ITER_START_CALLED = 0
    optimizer.ITER_END_CALLED = 0

    optimizer.callback_counter_test = 0
    optimizer.callback = simple_callback

    optimizer.verbosity = VerbosityLevels.DEBUG
    mapping = optimizer.optimize(static, moving, None)
    m = optimizer.get_map()
    assert_equal(mapping, m)
    subsampled_energy_profile = subsample_profile(
        optimizer.full_energy_profile, 10)
    print(subsampled_energy_profile)

    if USING_VC_SSE2:
        expected_profile = \
            np.array([312.6813333, 80.74625551, 49.43591374, 34.08871301,
                      25.18286981, 17.78955273, 25.91334939, 20.16932281,
                      43.86083145, 79.0966558 ])
    elif USING_GCC_SSE2:
        expected_profile = \
            np.array([312.6813333, 98.17321941, 60.98300837, 47.75387157,
                      34.11067498, 122.91901409, 19.75599298, 14.28763847,
                      36.33599718, 88.62426913])

    assert_array_almost_equal(subsampled_energy_profile,
                              expected_profile, decimal=5)
    assert_equal(optimizer.OPT_START_CALLED, 1)
    assert_equal(optimizer.OPT_END_CALLED, 1)
    assert_equal(optimizer.SCALE_START_CALLED, 1)
    assert_equal(optimizer.SCALE_END_CALLED, 1)
    assert_equal(optimizer.ITER_START_CALLED, 1)
    assert_equal(optimizer.ITER_END_CALLED, 1)
Ejemplo n.º 29
0
def test_ssd_2d_gauss_newton():
    r'''
    Classical Circle-To-C experiment for 2D Monomodal registration. This test
    is intended to detect regressions only: we saved the energy profile (the
    sequence of energy values at each iteration) of a working version of SSD in
    2D using the Gauss Newton step, and this test checks that the current energy
    profile matches the saved one.
    '''
    fname_moving = get_data('reg_o')
    fname_static = get_data('reg_c')

    moving = np.load(fname_moving)
    static = np.load(fname_static)
    moving = np.array(moving, dtype=floating)
    static = np.array(static, dtype=floating)
    moving = (moving-moving.min())/(moving.max() - moving.min())
    static = (static-static.min())/(static.max() - static.min())
    #Create the SSD metric
    smooth = 4
    inner_iter = 5
    step_type = 'gauss_newton'
    similarity_metric = metrics.SSDMetric(2, smooth, inner_iter, step_type)

    #Configure and run the Optimizer
    level_iters = [200, 100, 50, 25]
    step_length = 0.5
    opt_tol = 1e-4
    inv_iter = 40
    inv_tol = 1e-3
    ss_sigma_factor = 0.2
    optimizer = imwarp.SymmetricDiffeomorphicRegistration(similarity_metric,
        level_iters, step_length, ss_sigma_factor, opt_tol, inv_iter, inv_tol)

    #test callback not being called
    optimizer.INIT_START_CALLED = 0
    optimizer.INIT_END_CALLED = 0
    optimizer.OPT_START_CALLED = 0
    optimizer.OPT_END_CALLED = 0
    optimizer.SCALE_START_CALLED = 0
    optimizer.SCALE_END_CALLED = 0
    optimizer.ITER_START_CALLED = 0
    optimizer.ITER_END_CALLED = 0

    optimizer.verbosity = VerbosityLevels.DEBUG
    mapping = optimizer.optimize(static, moving, np.eye(3), np.eye(3), np.eye(3))
    m = optimizer.get_map()
    assert_equal(mapping, m)
    subsampled_energy_profile = np.array(optimizer.full_energy_profile[::10])
    if floating is np.float32:
        expected_profile = \
            np.array([312.68133316, 79.40404517, 23.3715698, 125.02700267,
                      59.79982213, 34.64971733, 23.37131446, 171.28250576,
                      62.22266377, 125.24392168])
    else:
        expected_profile = \
            np.array([312.68133361, 79.40404354, 23.34588446, 124.3247997,
                      61.69601973, 38.15047181, 23.53315113, 80.0791295,
                      57.21700113, 143.73270476])
    assert_array_almost_equal(subsampled_energy_profile, expected_profile)
    assert_equal(optimizer.OPT_START_CALLED, 0)
    assert_equal(optimizer.OPT_END_CALLED, 0)
    assert_equal(optimizer.SCALE_START_CALLED, 0)
    assert_equal(optimizer.SCALE_END_CALLED, 0)
    assert_equal(optimizer.ITER_START_CALLED, 0)
    assert_equal(optimizer.ITER_END_CALLED, 0)
Ejemplo n.º 30
0
def _compute_morph_sdr(mri_from, mri_to, niter_affine=(100, 100, 10),
                       niter_sdr=(5, 5, 3), zooms=(5., 5., 5.)):
    """Get a matrix that morphs data from one subject to another."""
    _check_dep(nibabel='2.1.0', dipy='0.10.1')
    import nibabel as nib
    with np.testing.suppress_warnings():
        from dipy.align import imaffine, imwarp, metrics, transforms
    from dipy.align.reslice import reslice

    logger.info('Computing nonlinear Symmetric Diffeomorphic Registration...')

    # use voxel size of mri_from
    if zooms is None:
        zooms = mri_from.header.get_zooms()[:3]
    zooms = np.atleast_1d(zooms).astype(float)
    if zooms.shape == (1,):
        zooms = np.repeat(zooms, 3)
    if zooms.shape != (3,):
        raise ValueError('zooms must be None, a singleton, or have shape (3,),'
                         ' got shape %s' % (zooms.shape,))

    # reslice mri_from
    mri_from_res, mri_from_res_affine = reslice(
        mri_from.get_data(), mri_from.affine, mri_from.header.get_zooms()[:3],
        zooms)

    with warnings.catch_warnings():  # nibabel<->numpy warning
        mri_from = nib.Nifti1Image(mri_from_res, mri_from_res_affine)

    # reslice mri_to
    mri_to_res, mri_to_res_affine = reslice(
        mri_to.get_data(), mri_to.affine, mri_to.header.get_zooms()[:3],
        zooms)

    with warnings.catch_warnings():  # nibabel<->numpy warning
        mri_to = nib.Nifti1Image(mri_to_res, mri_to_res_affine)

    affine = mri_to.affine
    mri_to = np.array(mri_to.dataobj, float)  # to ndarray
    mri_to /= mri_to.max()
    mri_from_affine = mri_from.affine  # get mri_from to world transform
    mri_from = np.array(mri_from.dataobj, float)  # to ndarray
    mri_from /= mri_from.max()  # normalize

    # compute center of mass
    c_of_mass = imaffine.transform_centers_of_mass(
        mri_to, affine, mri_from, affine)

    # set up Affine Registration
    affreg = imaffine.AffineRegistration(
        metric=imaffine.MutualInformationMetric(nbins=32),
        level_iters=list(niter_affine),
        sigmas=[3.0, 1.0, 0.0],
        factors=[4, 2, 1])

    # translation
    translation = affreg.optimize(
        mri_to, mri_from, transforms.TranslationTransform3D(), None, affine,
        mri_from_affine, starting_affine=c_of_mass.affine)

    # rigid body transform (translation + rotation)
    rigid = affreg.optimize(
        mri_to, mri_from, transforms.RigidTransform3D(), None,
        affine, mri_from_affine, starting_affine=translation.affine)

    # affine transform (translation + rotation + scaling)
    pre_affine = affreg.optimize(
        mri_to, mri_from, transforms.AffineTransform3D(), None,
        affine, mri_from_affine, starting_affine=rigid.affine)

    # compute mapping
    sdr = imwarp.SymmetricDiffeomorphicRegistration(
        metrics.CCMetric(3), list(niter_sdr))
    sdr_morph = sdr.optimize(mri_to, pre_affine.transform(mri_from))
    shape = tuple(sdr_morph.domain_shape)  # should be tuple of int
    logger.info('done.')
    return shape, zooms, affine, pre_affine, sdr_morph