Examples

CT Pre-processing

Flat field correction

To remove fixed pattern noise that stems from the optical system caused by imperfections in the scintillator screen or an inhomogeneous beam and thermal noise from the detector sensor, you can use flat field correction. This assumes that you have a set of dark fields acquired with the shutter closed, a set of flat fields acquired without the sample in the beam and the projections with samples. If the beam intensity shifts over time it can be beneficial to acquire flat fields before and after the projections and interpolate between them.

In the simplest case you connect the projection stream to input 0, the dark field to input 1 and the flat field to input 2 of flat-field-correct:

ufo-launch \
    [ \
        read path=projections*.tif, \
        read path=dark.tif, \
        read path=flat.tif \
    ] ! \
    flat-field-correct !
    write filename=corrected-%05i.tif

If you have a stream of flats and darks you have to reduce them either by connection them to average or stackflatten with the mode set to median. Suppose, we want to average the darks and remove extreme outliers from the flats, we would call

ufo-launch \
    [ \
        read path=projections*.tif, \
        read path=darks/ ! average, \
        read path=flats/ ! stack number=11 ! flatten mode=median \
    ] ! \
    flat-field-correct !
    write filename=corrected-%05i.tif

If you have to interpolate between the flats taken before and after the sample scan, you would connect the first flat to input 0 and the second to input 1 of interpolate and set the number property to the number of expected projections:

ufo-launch \
    [ \
        read path=projections*.tif, \
        read path=darks/ ! average, \
        [ \
            read path=flat-before.tif, \
            read path=flat-after.tif \
        ] ! interpolate number=2000
    ] ! \
    flat-field-correct !
    write filename=corrected-%05i.tif

If you want to avoid the automatic absorption correction you have to set absorption-correct to FALSE and if you want to ignore NaN and Inf values in the data, set fix-nan-and-inf to FALSE.

Sinograms

The reconstruction pipelines presented in the following section assume sinograms as input in order to parallelize along slices. To transpose a stream of (corrected) projections connect it to transpose-projections and set number to the number of expected projections. Note, that the transposition happens in main memory and thus may exhaust your system resources for a larger number of big projections. For example, to transpose 2048 projections, each at a size of 2048 by 2048 pixels requires 32 GB of RAM.

CT Reconstruction

Filtered backprojection

To reconstruct from sinograms using the analytical filtered backproject method [KaSl01], you have to feed the sinograms into fftfilterifftbackproject to obtain slices one by one:

ufo-launch \
    dummy-data width=$DETECTOR_WIDTH height=$N_PROJECTIONS number=$N_SLICES ! \
    fft dimensions=1 ! \
    filter ! \
    ifft dimensions=! ! \
    backproject axis-pos=$AXIS ! \
    null

Direct Fourier inversion

In this example we use the Fourier slice theorem to obtain slices directly from projection data [KaSl01] and use a sinc kernel to interpolate in the Fourier space. To reconstruct, you have to feed the sinograms into zeropadfftdfi-sincswap-quadrantsifftswap-quadrants

ufo-launch \
    dummy-data width=$DETECTOR_WIDTH height=$N_PROJECTIONS number=$N_SLICES ! \
    zeropad center-of-rotation=$AXIS ! \
    fft dimensions=1 auto-zeropadding=0 ! \
    dfi-sinc ! \
    swap-quadrants ! \
    ifft dimensions=2 ! \
    swap-quadrants ! \
    null

Data distribution

To distribute data in a compute network you can use the zmq-pub sink and zmq-sub generator. For example, to read data on machine A and store it on machine B, you would run

ufo-launch read path=/data ! zmq-pub

on machine A and

ufo-launch zmq-sub address=tcp://hostname-of-machine-a ! write

on machine B. Note that by default zmq-pub publishes data as soon as it receives it, thus some of the data will get lost if the zmq-sub is run after zmq-pub. You can prevent this by telling the zmq-pub task to wait for a certain number of subscribers to subscribe:

ufo-launch read path=/data ! zmq-pub expected-subscribers=1

References

KaSl01(1,2)

Kak, A. C., & Slaney, M. (2001). Principles of Computerized Tomographic Imaging (Philadelphia, PA: SIAM).