Computerized tomography (CT) and related techniques such as PET or MRI are very common tools in medical imaging. They allow to resolve the 3D structure of living tissues. Tomography itself is divided into two processing steps. First, projection images are recorded for several angles, the result of which is called a sinogram. Second, this sinogram is used to reconstruct a 3D representation of the original object. In the most simple case, the object (or detector) rotation is performed only about one axis, which means that the 3D reconstruction from 2D images can be broken down to several 2D slice reconstructions from 1D line scans. For CT, the sinogram consists of x-ray absorption images: Bone tissue absorbs x-ray radiation and thus bones appear white on the developed photographic x-ray film. A PET image visualizes the radiation of radioactive tracers linked to biological molecules that accumulate in the targeted tissue. In MRI, image contrast is computed from the time-dependent magnetic response of tissues to strong dynamic magnetic fields. The main problem to solve in tomographic imaging is the reconstruction step, i.e. the ill-posed inversion of the Radon transform. While nowadays there exist iterative approaches that take into account prior knowledge about the imaged sample, the most beautiful reconstruction artifacts can be achieved with the classical backpropagation algorithm. In general, the quality of the 3D reconstruction in CT-like imaging depends on the number of recorded images (the more the better) and on the angular coverage (below 180° only partial coverage can be achieved). The artistic tomographic image filter enforces low reconstruction quality by addressing such aspects.

Filter operation

The basic mode of operation of the artistic tomographic filter is to simulate the sinogram acquisition process and to reconstruct the original image from the simulated sinogram. Here is an example that illustrates the steps from original image to sinogram image to reconstructed image with 256 angles (deliberately matching the image dimensions 256x256 px for visualization purposes):

original sinogram reconstruction

As mentioned above, the actual artistic potential of the filter will only be released, if the number of angles in the sinogram used for the reconstruction is reduced:

5 angles 10 angles 20 angles

The resulting artifacts consist of streaks through the image that, when many of them intersect, reproduce the original image content. The filter can be modified in several different ways, some of which are covered further below.

Python setup

The artistic tomographic filter uses the backprojection algorithm I implemented in the Python library radontea. Radontea also comes with an implementation of the Radon transform which is used to compute the sinogram from the input image. For loading and writing images, imageio is used. For Python 3, imageio and radontea can be installed from the Python package index via pip install imageio radontea.

python tomographic_filter.py input_image.jpg

This will produce a new image input_image_tf.jpg, generated with the standard filtering parameters.

Tweak and tune

The tomographic_filter.py script comes with a convenient command line interface that allows to tune several parameters, from Radon transform to backprojection, affecting the artistic character of the filter.

By default, the filter uses 37 equally spaced angles with a full angular coverage (from 0° to 180°).

original [highres] filter with defaults [highres]

The angular coverage can be modified with the arguments --cov-min (default 0) and --cov-max (default 180), leading to so-called missing-angle artifacts.

original [highres] defaults [highres] --cov-max 120 [highres]

To achieve a more chaotic behavior, the angles can be distributed randomly using the --randomness argument. To improve the recognizability of the object, --weight-angles can be combined with randomly distributed angles.

original [highres] --randomness 47 [highres] --randomness 47 and --weight-angles [highres]

Random distribution of angles can also be combined with partial angular coverage. The choice of angles affects the angular positions of the streaks, sometimes resulting in exaggerated edge contrast.

original [highres] --randomness 8472, --cov-min 20, and --cov-max 160 [highres] --randomness 8472 and --cov-min 70 [highres]

For bright images (black images would have to be inverted first), it might also be worthwhile to disable the color normalization prior to computing the sinogram. This produces a ring-shaped artifact around the image.

--no-normalize and --num-angles 20 --no-normalize [highres] --no-normalize, --randomness 42 and --weight-angles [highres]

Video generation

The --offset option allows to change the offset of the angles used. The following script imports tomographic_filter.py as a module and generates a series of 180 filtered images at a 1°-spacing.

import tomographic_filter

path_in = "crow.jpg"

for ii in range(0, 180):
path_out = "crow_tf_{:03d}.png".format(ii)
tomographic_filter.tomographic_filter(path_in=path_in,
path_out=path_out,
angle_offset=ii,
randomness=42,
num_angles=47,
weight_angles=True)


The resulting png files can be converted to a browser-compatible video using avconv/ffmpeg:

avconv -r 15 -i crow_tf_%03d.png -c:v vp8 -b:v 10M crow.webm

original offset series video

Angular offsets are also a nice way of visualizing missing-angle artifacts. Recognizability of the original image often depends on the angular range covered by the sinogram. In the next example, the keyword arguments ival_coverage=(0,100) and normalize=False were used.

original offset series video

Play!

The examples shown here do not exhaust the full capability of the tomographic filter. Besides the various combinations of the filter parameters given, other parameters could be used, such as padding or filtering. In addition, a different reconstruction algorithm, such as Fourier domain mapping could be used. A qualitative comparison of the available algorithms can be found at the radontea docs.

TL;DR

Install Python 3, pip install imageio radontea, download tomographic_filter.py, and execute it, passing an image path as an argument.

python tomographic_filter.py /path/to/image.jpg

For a list of possible command-line arguments, use --help.

python tomographic_filter.py --help.