Onion Peeling (Dasch)


The “Dasch onion peeling” deconvolution algorithm is one of several described in the Dasch paper [1]. See also the two_point and three_point descriptions.

How it works

In the onion-peeling method the projection is approximated by rings of constant property between \(r_j - \Delta r/2\) and \(r_j + \Delta r/2\) for each data point \(r_j\).

The projection data is given by \(P(r_i) = \Delta r \sum_{j=i}^\infty W_{ij} F(r_j)\)


\[ \begin{align}\begin{aligned}W_{ij} = 0 \, \, (j < i)\\\sqrt{(2j+1)^2 - 4i^2} \, \, (j=i)\\\sqrt{(2j+1)^2 - 4i^2} - \sqrt{(2j-1)^2 - 4i^2} \, \, (j > i)\end{aligned}\end{align} \]

The onion-peeling deconvolution function is: \(D_{ij} = (W^{-1})_{ij}\).

When to use it

This method is simple and computationally very efficient. The article states that it has less smoothing that other methods (discussed in Dasch).

How to use it

To complete the inverse transform of a full image with the onion_dasch method, simply use the abel.Transform class:

abel.Transform(myImage, method='onion_peeling').transform

If you would like to access the onion_peeling algorithm directly (to transform a right-side half-image), you can use abel.dasch.onion_peeling_transform().


# -*- coding: utf-8 -*-
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals


import numpy as np
import abel
import matplotlib.pyplot as plt

# Dribinski sample image size 501x501
n = 501
IM = abel.tools.analytical.SampleImage(n).image

# split into quadrants
origQ = abel.tools.symmetry.get_image_quadrants(IM)

# speed distribution of original image
orig_speed = abel.tools.vmi.angular_integration_3D(origQ[0], origin=(-1, 0))
scale_factor = orig_speed[1].max()

plt.plot(orig_speed[0], orig_speed[1]/scale_factor, linestyle='dashed', 
         label="Dribinski sample")

# forward Abel projection
fIM = abel.Transform(IM, direction="forward", method="hansenlaw").transform

# split projected image into quadrants
Q = abel.tools.symmetry.get_image_quadrants(fIM)

dasch_transform = {\
"two_point": abel.dasch.two_point_transform,
"three_point": abel.dasch.three_point_transform, 
"onion_peeling": abel.dasch.onion_peeling_transform}

for method in dasch_transform.keys():
    Q0 = Q[0].copy()
# method inverse Abel transform
    AQ0 = dasch_transform[method](Q0, basis_dir='bases')
# speed distribution
    speed = abel.tools.vmi.angular_integration_3D(AQ0, origin=(-1, 0))

    plt.plot(speed[0], speed[1]*orig_speed[1][14]/speed[1][14]/scale_factor, 

plt.title("Dasch methods for Dribinski sample image $n={:d}$".format(n))
plt.axis(xmax=250, ymin=-0.1)
plt.legend(loc=0, frameon=False, labelspacing=0.1, fontsize='small')

or more information on the PyAbel implementation of the onion_peeling algorithm, please see PR #155.


[1]C. J. Dasch, “One-dimensional tomography: a comparison of Abel, onion-peeling, and filtered backprojection methods”, Appl. Opt. 31, 1146–1152 (1992).