Reconstructing Data (Numerical Propagation)¶
A hologram contains information about the electric field amplitude and phase at the detector plane. Shining light back through a hologram allows reconstruction of the electric field at points upstream of the detector plane. HoloPy performs this function mathematically by numerically propagating a hologram (or electric field) to another position in space. This allows you to reconstruct 3D sample volumes from 2D images.
import numpy as np import holopy as hp from holopy.core.io import get_example_data_path, load_average from holopy.core.process import bg_correct imagepath = get_example_data_path('image01.jpg') raw_holo = hp.load_image(imagepath, spacing = 0.0851, medium_index = 1.33, illum_wavelen = 0.66, ) bgpath = get_example_data_path(['bg01.jpg','bg02.jpg','bg03.jpg']) bg = load_average(bgpath, refimg = raw_holo) holo = bg_correct(raw_holo, bg) zstack = np.linspace(1, 15, 8) rec_vol = hp.propagate(holo, zstack) hp.show(rec_vol)
We’ll examine each section of code in turn. The first block:
import numpy as np import holopy as hp from holopy.core.io import get_example_data_path, load_average from holopy.core.process import bg_correct
loads the relevant modules from HoloPy and NumPy. The second block:
imagepath = get_example_data_path('image01.jpg') raw_holo = hp.load_image(imagepath, spacing = 0.0851, medium_index = 1.33, illum_wavelen = 0.66) bgpath = get_example_data_path(['bg01.jpg','bg02.jpg','bg03.jpg']) bg = load_average(bgpath, refimg = raw_holo) holo = bg_correct(raw_holo, bg)
reads in a hologram and divides it by a corresponding background image. If this is unfamiliar to you, please review the Loading Data tutorial.
Next, we use numpy’s linspace to define a set of distances at 2-micron intervals to
propagate our image to. You can also propagate to a single distance
or to a set of distances obtained in some other fashion.
The actual propagation is accomplished with
zstack = np.linspace(1, 15, 8) rec_vol = hp.propagate(holo, zstack)
Here, HoloPy has projected the hologram image through space to each of the distances contained in
zstack by using the metadata that we
specified when loading the image. If we forgot to load optical metadata with the image,
we can explicitly indicate the parameters for propagation to obtain an identical object:
rec_vol = hp.propagate(holo, zstack, illum_wavelen = 0.660, medium_index = 1.33)
You can display the reconstruction with
Pressing the left and right arrow keys steps through volumes slices - propagation to different z-planes. (Don’t use the down arrow key; it will mess up the stepping due to a peculiarity of Matplotlib. If this happens, close your plot window and show it again. Sorry.). If the left and right arrow keys don’t do anything, you might need to set your matplotlib backend. Refer to usage for instructions.
Reconstructions are actually comprised of complex numbers.
defaults to showing you the amplitude of the image. You can get
different, and sometimes better, contrast by viewing the phase angle or
imaginary part of the reconstruction:
These phase sensitive visualizations will change contrast as you step through because you hit different places in the phase period. Such a reconstruction will work better if you use steps that are an integer number of wavelengths in medium:
med_wavelen = holo.illum_wavelen / holo.medium_index rec_vol = hp.propagate(holo, zstack*med_wavelen) hp.show(rec_vol.imag)
Cascaded Free Space Propagation¶
HoloPy calculates reconstructions by performing a convolution of the hologram with the reference wave over the distance to be propagated. By default, HoloPy calculates a single transfer function to perform the convolution over the specified distance. However, a better reconstruction can sometimes be obtained by iteratively propagating the hologram over short distances. This cascaded free space propagation is particularly useful when the reconstructions have fine features or when propagating over large distances. For further details, refer to Kreis 2002.
To implement cascaded free space propagation in HoloPy, simply pass a
propagate() indicating how many times the hologram should be iteratively
propagated. For example, to propagate in three steps over each distance, we write:
rec_vol = hp.propagate(holo, zstack, cfsp = 3)