Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

stough 202-

Preview: Radon Dot Animation

This is a quick demonstration the Radon transform, or sinogram, of a dot. We animate to see how the sinogram changes as the dot moves.

Imports

Note we’ll just rely on skimage.transform for the transform itself.

Defining an image of a disk

Parameters include the image size, the disk radius, and the radius of the path of the disk as I animate it. Given the animation, we’ll also need the number of frames to make a cycle and the millisecond interval between frames.

<Figure size 400x300 with 1 Axes>

Visualize the Radon

The sinogram plot is ϕ\phi by ρ\rho. Any particular pixel in the plot represents a line in the image space. The sum of intensities along that line in the image is the value of the pixel in the sinogram. (See the forward example for the definition.)

Why does a single dot make a sinusoid? Put the dot at position (x0,y0)(x_0, y_0), a distance rr from the image center at angle φ\varphi, so x0=rcos⁡φx_0 = r\cos\varphi and y0=rsin⁡φy_0 = r\sin\varphi. The line at angle θ\theta passes through the dot exactly when

ρ=x0cos⁡θ+y0sin⁡θ=rcos⁡(θ−φ)\rho = x_0\cos\theta + y_0\sin\theta = r\cos(\theta - \varphi)

So as θ\theta sweeps from 0°0° to 180°180°, the dot appears in the projection at position ρ=rcos⁡(θ−φ)\rho = r\cos(\theta-\varphi): a cosine curve whose amplitude is the dot’s distance from the center and whose phase is its angle around the center. Our disk is 50 pixels from the center, so its sinusoid swings 50 pixels to either side of the middle row. Over 180°180° we see half of one full period.

<Figure size 800x300 with 2 Axes>

Animate the Dot

We’ve now also added button-clicking functionality to our interactive plotting skills.

/tmp/ipykernel_3674/1803367455.py:32: UserWarning: frames=None which we can infer the length of, did not pass an explicit *save_count* and passed cache_frame_data=True.  To avoid a possibly unbounded cache, frame data caching has been disabled. To suppress this warning either pass `cache_frame_data=False` or `save_count=MAX_FRAMES`.
  ani = animation.FuncAnimation(f, updateFig,
<Figure size 1000x400 with 2 Axes>

As the disk circles the center, its distance rr stays the same, but its angle φ\varphi advances, so the sinusoid keeps the same amplitude and slides along in phase. Click somewhere in the image to move the disk: the sinusoid’s amplitude jumps to the new distance from the center, and a disk right at the center makes a flat line. (A center point is at ρ=0\rho = 0 in every projection.)

About the code: rather than redraw the disk each frame, updateFig rotates the image a few degrees with skimage.transform.rotate. Each rotation resamples the image with bilinear interpolation (order=1), so the disk gets slightly blurrier every frame. That’s the accumulating cost of repeated interpolation we saw in coordinate operations. Clicking redraws a sharp disk.