Radon transform: Include boundary in reconstruction circle.

A test criterion needed to be relaxed slightly to have tests still
passing. This is ok, as the reconstruction circle is now larger, meaning
larger errors should be expected. Moreover, the test in question uses
random data, and changing the seed causes greater changes in accuracy
than the amount the test criterion was relaxed by.
This commit is contained in:
Jostein Bø Fløystad
2013-07-13 20:32:15 +02:00
parent 288ee69483
commit 462173a53a
2 changed files with 7 additions and 9 deletions
+4 -6
View File
@@ -64,7 +64,7 @@ def radon(image, theta=None, circle=False):
radius = min(image.shape) // 2
c0, c1 = np.ogrid[0:image.shape[0], 0:image.shape[1]]
reconstruction_circle = ((c0 - image.shape[0] // 2)**2
+ (c1 - image.shape[1] // 2)**2) < radius**2
+ (c1 - image.shape[1] // 2)**2) <= radius**2
if not np.all(reconstruction_circle | (image == 0)):
raise ValueError('Image must be zero outside the reconstruction'
' circle')
@@ -231,9 +231,7 @@ def iradon(radon_image, theta=None, output_size=None,
# Determine the center of the projections (= center of sinogram)
mid_index = radon_image.shape[0] // 2
x = output_size
y = output_size
[X, Y] = np.mgrid[0.0:x, 0.0:y]
[X, Y] = np.mgrid[0:output_size, 0:output_size]
xpr = X - int(output_size) // 2
ypr = Y - int(output_size) // 2
@@ -250,8 +248,8 @@ def iradon(radon_image, theta=None, output_size=None,
backprojected = interpolant(t)
reconstructed += backprojected
if circle:
radius = (output_size - 1) // 2
reconstruction_circle = (xpr**2 + ypr**2) < radius**2
radius = output_size // 2
reconstruction_circle = (xpr**2 + ypr**2) <= radius**2
reconstructed[~reconstruction_circle] = 0.
return reconstructed * np.pi / (2 * len(th))
@@ -210,7 +210,7 @@ def _random_circle(shape):
c0, c1 = np.ogrid[0:shape[0], 0:shape[1]]
r = np.sqrt((c0 - shape[0] // 2)**2 + (c1 - shape[1] // 2)**2)
radius = min(shape) // 2
image[r >= radius] = 0.
image[r > radius] = 0.
return image
@@ -236,7 +236,7 @@ def test_radon_circle():
average_mass = mass.mean()
relative_error = np.abs(mass - average_mass) / average_mass
print(relative_error.max(), relative_error.mean())
assert np.all(relative_error < 3e-3)
assert np.all(relative_error < 3.2e-3)
def check_sinogram_circle_to_square(size):
@@ -284,7 +284,7 @@ def check_radon_iradon_circle(interpolation, shape, output_size):
# Find the reconstruction circle, set reconstruction to zero outside
c0, c1 = np.ogrid[0:width, 0:width]
r = np.sqrt((c0 - width // 2)**2 + (c1 - width // 2)**2)
reconstruction_rectangle[r >= radius] = 0.
reconstruction_rectangle[r > radius] = 0.
print(reconstruction_circle.shape)
print(reconstruction_rectangle.shape)
np.allclose(reconstruction_rectangle, reconstruction_circle)