File: register_binary_fuzzy.py

package info (click to toggle)
dipy 1.11.0-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 17,144 kB
  • sloc: python: 92,240; makefile: 272; pascal: 183; sh: 162; ansic: 106
file content (152 lines) | stat: -rw-r--r-- 5,203 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
"""
=======================================================
Diffeomorphic Registration with binary and fuzzy images
=======================================================

This example demonstrates registration of a binary and a fuzzy image.
This could be seen as aligning a fuzzy (sensed) image to a binary
(e.g., template) image.
"""

import matplotlib.pyplot as plt
import numpy as np
from skimage import draw, filters

from dipy.align.imwarp import SymmetricDiffeomorphicRegistration
from dipy.align.metrics import SSDMetric
from dipy.viz import regtools

###############################################################################
# Let's generate a sample template image as the combination of three ellipses.
# We will generate the fuzzy (sensed) version of the image by smoothing
# the reference image.


def draw_ellipse(img, center, axis):
    rr, cc = draw.ellipse(center[0], center[1], axis[0], axis[1], shape=img.shape)
    img[rr, cc] = 1
    return img


img_ref = np.zeros((64, 64))
img_ref = draw_ellipse(img_ref, (25, 15), (10, 5))
img_ref = draw_ellipse(img_ref, (20, 45), (15, 10))
img_ref = draw_ellipse(img_ref, (50, 40), (7, 15))

img_in = filters.gaussian(img_ref, sigma=3)

###############################################################################
# Let's define a small visualization function.


def show_images(img_ref, img_warp, fig_name):
    fig, axarr = plt.subplots(ncols=2, figsize=(12, 5))
    axarr[0].set_title("warped image & reference contour")
    axarr[0].imshow(img_warp)
    axarr[0].contour(img_ref, colors="r")
    ssd = np.sum((img_warp - img_ref) ** 2)
    axarr[1].set_title(f"difference, SSD={ssd:.02f}")
    im = axarr[1].imshow(img_warp - img_ref)
    plt.colorbar(im)
    fig.tight_layout()
    fig.savefig(fig_name + ".png")


show_images(img_ref, img_in, "input")

###############################################################################
# .. rst-class:: centered small fst-italic fw-semibold
#
# Input images before alignment.
#
#
#
# Let's use the general Registration function with some naive parameters,
# such as set `step_length` as 1 assuming maximal step 1 pixel and a
# reasonably small number of iterations since the deformation with already
# aligned images should be minimal.

sdr = SymmetricDiffeomorphicRegistration(
    metric=SSDMetric(img_ref.ndim),
    step_length=1.0,
    level_iters=[50, 100],
    inv_iter=50,
    ss_sigma_factor=0.1,
    opt_tol=1.0e-3,
)

###############################################################################
# Perform the registration with equal images.

mapping = sdr.optimize(img_ref.astype(float), img_ref.astype(float))
img_warp = mapping.transform(img_ref, interpolation="linear")
show_images(img_ref, img_warp, "output-0")
regtools.plot_2d_diffeomorphic_map(mapping, delta=5, fname="map-0.png")

###############################################################################
# .. rst-class:: centered small fst-italic fw-semibold
#
# Registration results for default parameters and equal images.
#
#
#
# Perform the registration with binary and fuzzy images.

mapping = sdr.optimize(img_ref.astype(float), img_in.astype(float))
img_warp = mapping.transform(img_in, interpolation="linear")
show_images(img_ref, img_warp, "output-1")
regtools.plot_2d_diffeomorphic_map(mapping, delta=5, fname="map-1.png")

###############################################################################
# .. rst-class:: centered small fst-italic fw-semibold
#
# Registration results for a naive parameter configuration.
#
#
#
# Note, we are still using a multi-scale approach which makes `step_length`
# in the upper level multiplicatively larger.
# What happens if we set `step_length` to a rather small value?

sdr.step_length = 0.1

###############################################################################
# Perform the registration and examine the output.

mapping = sdr.optimize(img_ref.astype(float), img_in.astype(float))
img_warp = mapping.transform(img_in, interpolation="linear")
show_images(img_ref, img_warp, "output-2")
regtools.plot_2d_diffeomorphic_map(mapping, delta=5, fname="map-2.png")

###############################################################################
# .. rst-class:: centered small fst-italic fw-semibold
#
# Registration results for decreased step size.
#
#
#
# An alternative scenario is to use just a single-scale level.
# Even though the warped image may look fine, the estimated deformations show
# that it is off the mark.

sdr = SymmetricDiffeomorphicRegistration(
    metric=SSDMetric(img_ref.ndim),
    step_length=1.0,
    level_iters=[100],
    inv_iter=50,
    ss_sigma_factor=0.1,
    opt_tol=1.0e-3,
)

###############################################################################
# Perform the registration.

mapping = sdr.optimize(img_ref.astype(float), img_in.astype(float))
img_warp = mapping.transform(img_in, interpolation="linear")
show_images(img_ref, img_warp, "output-3")
regtools.plot_2d_diffeomorphic_map(mapping, delta=5, fname="map-3.png")

###############################################################################
# .. rst-class:: centered small fst-italic fw-semibold
#
# Registration results for single level.