An artistic tomographic image filter
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
.
To use the filter, download tomographic_filter.py and execute it like so:
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
.