Tuesday, August 28, 2012

Learning Tomography: Radon Transform

In the previous posts, I assume that the sinogram was already collected (or calculated) and we only focused on the process of reconstruction. Now, it is time to see how a sinogram can be computed from a given 2D slice (extracted from 3D data). 

1- From 2D-image to 1D-projection

From the clown image available in the Samples of ImageJ (I crop it to get a square and convert it into gray-levels), ...

Fig.1: Original image
... you can compute a plot profile (Analyze > Plot Profile) corresponding to the sum of all the horizontal lines contained in the rectangular area (by default, the whole image). Thus, what we obtain is exactly a 1D-projection along a vertical direction of the 2D-image.
Here is the corresponding plot, the two peaks correspond to the areas of white make-up.
Fig.2: Plot corresponding to the projection of clown image (Fig.xxx) along a vertical direction.
We can convert this plot into an image as shown in the following figure.

Fig.3: Plot conversion into a 1D-image. Each pixel corresponds to the sum of each of the pixels of a given column.
In ImageJ macro/script, this is done with the function getProfile(...) as shown in the following script. The values are put into an image using the setPixel(...) function.
+++ IJ snippet +++ +++End of IJ snippet +++

In JavaScript, we have to create an object ProfilePlot to use its getProfile(...) method. The principle is rigorously the same as above.
+++ IJ JavaScript snippet +++ +++End of IJ JavaScript snippet +++

2- Radon Transform (or Sinogram)

2-1- Principle
Radon transform also called sinogram is a collection of 1D projections calculated from different directions as shown in Fig. 4. Then, each 1D projection is stacked in an image (aka the sinogram).
Fig. 4: Principle of sinogram computation.
2-2- How to compute a sinogram?
The heart of the script is the chunk of previous code (section 1) with an additional loop to calculate the various projections. Rather than calculating oblique projections, the input image is rotated in such a way that the projection direction is always vertical. To summarize,
  • step #1: For a given angle θ
  • step #2: Duplicate and rotate the input image of  θ
  • step #3: Compute the projection using the Profile function (vertical direction)
  • step #4: Copy and paste the profile pixel values in the sinogram at row θ
  • step #5: the temporary rotated image is removed.

+++ IJ JavaScript snippet +++ +++End of IJ JavaScript snippet +++

Note: The two first lines of code allows to compute the angle stride depending of the sinogram height. By default, I use 180 projections leading to an angle stride of 1°.
2-3- And now, the result ...
Fig.5: Radon transform computed from image of Fig.1.

In conclusion, the sinogram often corresponds to input real data obtained from non-invasive devices like X-ray tomo-densitometer or electron microscope. Thus, the main purpose is to reconstruct data (a 2D slice of the sample) from the sinogram by inversing the Radon Transform. This operation (inverse Radon transform) is described in Section 2 of the Learning Tomography Series [Link] corresponding to this first post [Link].

Other crazybiocomputing posts

Further readings are available in ...
  • Learning Tomography Series  [Link]
  • Image Processing TOC [Link]


  1. Hey there !
    Awesome post, what I liked about is is that you explain the step by step code, which helped me a lot to understand the radon tr.
    Do you happen to have the same thing for the back transform, to get the scary clown back ?
    Cheers !

    1. Thank you for your comment. The back transform and its variants are described in the 'Learning Tomography Series' see the link above and the best is to begin with the 'Simple Back Projection' post and then to the 'Filtered Back-Projection'.