Inline Holography Using Holo Class
Inline Holography can be performed using the Holo Class of PyHoloscope by setting mode = pyholoscope.INLINE. This allows
numerical refocusing using the angular spectrum or Fresnel propagator methods, as well as optional background subtraction, normalisation, windowing and autofocusing.
See the Holo class documentation for a full list of methods and arguments. For code examples see the Inline Holography Example
or Inline Holography Advanced Example on github.
Alternatively, for more customisability, the low-level functions can be used directly as described in Inline Holography Using Lower-Level Functions .
Getting Started using the Holo class
Begin by importing the PyHoloscope package:
import pyholoscope as pyh
and create an instance of the Holo Class. At a minimum we need to set the mode to inline holography and provide the physical pixel size and the wavelength:
holo = pyh.Holo(mode = pyh.INLINE, pixel_size = 2e-6, wavelength = 0.5e-6)
The pixel size and wavelength should be specified in the same units (e.g. metres). Subsequently, the refocus depth should be specified in the same units.
Better quality inline holography refocusing can be achieved if we first
subtract a background image, acquired with no object in the field-of-view, forming
what is known as a contrast hologram. Assuming the background image is stored in the 2D numpy array background_img,
a background can be specified using:
holo.background = background_img
or by passing background = background_img as an argument when creating the Holo object:
holo = pyh.Holo(mode = pyh.INLINE, pixel_size = 2e-6, wavelength = 0.5e-6, background = background_img)
If we would like to divide through by a flat-field image stored as a 2D numpy array flat_img, to correct for
intensity variations, we can pass normalise = flat_img or call
holo.normalise = flat_img.
We can now numerically refocus a hologram hologram, again a 2D numpy array,
using the angular spectrum method by first setting the depth to refocus to, for example:
holo.depth = 0.005
(or by passing depth = 0.005 when instantiating Holo) and then calling:
refocused_img = holo.process(hologram)
The output, refocused_img, is a 2D complex numpy array; we can obtain the amplitude as a 2D float numpy array using:
refocused_amp = pyh.amp(refocused_img)
Note that the first time a hologram is refocused to a particular depth the process will be slower due to the need to create a propagator for that depth. This is particularly noticeable when using GPU acceleration as the propagator creation will often be the rate-limiting step. Subsequent refocusing to the same depth will be faster providing no parameters are changed that force a new propagator to be created (depth, pixel size, wavelength or grid size).
The angular spectrum propagator and the window are both created the first time
process is called for a particular set of parameters. If we prefer to pre-generate these, we can call:
holo.update_propagator(img)
holo.update_auto_window(img)
where img is a 2D numpy array of the size of the hologram to be processed.
Windowing
If we would like to smooth the edges of the hologram, we can apply a window before refocusing by calling:
holo.auto_window = True
By default the window will be a rectangular cosine window. Options for the window size and shape
are set using the window_shape, window_radius and window_thickness attributes
of Holo Class.
Propagation Models and Geometric Magnification Correction
If required, the wavefront propagation model can be switched by changing propagation_method from "angular_spectrum" (default) to "fresnel".
For example:
holo.propagation_method = "fresnel"
While less accurate than the angular spectrum method in some cases, the Fresnel method is slightly faster to compute and may be sufficient for many applications.
When using a point source, the effective pixel size is not the physical pixel camera size,
as the hologram is magnified onto the camera due to projection effects. The depth value
for which focus is achieved will therefore not be the true distane to the sample plane.
Effective-magnification correction can be enabled by setting correct_pixel_size = True and
providing source_distance (source-to-camera distance), for example:
holo = pyh.Holo(mode = pyh.INLINE, pixel_size = 2e-6, wavelength = 0.5e-6, depth = 0.005,
source_distance = 0.01, correct_pixel_size = True)
Numba JIT acceleration
If the Numba package is installed, this will be employed for faster generation
of propagators by default when using the Holo class. Use of Numba can be
explicitly enabled/disabled using:
holo.use_numba = True/False
GPU acceleration
GPU acceleration is used by default when using the Holo class, it can be
explicitly enabled/disabled using:
holo.cuda = True/False
This requires the CuPy package and a compatible GPU, otherwise Holo will
revert to CPU processing.