s (np.ndarray) – Slope map.
It is reshaped to video-shape (frames T, height Y, width X, color channels C) before processing.
center (bool, default=False) – If this flag is set to True, the curvature values get centered around zero using the median.
normalize (bool, default=False) – Flag indicating whether to use the arc-tangent function
to non-linearly map the codomain of c from [-inf, inf] to [-1, 1].
lessbits (bool, default=True) – Irec rcorded by tha camera may contain fewer bits of information than its data type can hold,
e.g. 12 bits for dtype uint16.
If this flag is activated, it looks for the maximal value in I
and sets Imax to the same or next power of two which is divisible by two.
Example: If I.max() is 3500, Imax is set to 4095 (the maximal value a 12bit camera can deliver).
Configure, encode and decode fringe patterns using phase shifting algorithms.
Note
All parameters are implemented as properties
(managed attributes) and are parsed when set.
Note that some attributes have sub-dependencies,
hence dependent attributes might change as well.
Circular dependencies are resolved automatically.
Parameters:
*args (iterable) – Non-keyword arguments are explicitly discarded.
Only keyword arguments are considered.
X (int, default=1920) – Width of fringe patterns.
Y (int, default=1200) – Height of fringe patterns.
D (int, default=2) – Number of directions.
K (int, default=2) – Number of sets (number of fringe patterns with different spatial frequencies).
N (array_like, default=((4, 4), (4, 4))) – Number of (equally distributed) phase shifts.
v (array_like, default=((13.0, 7.0), (13.0, 7.0))) – Spatial frequencies (number of fringe periods across extended coding length Lext).
f (array_like, default=((1.0, 1.0), (1.0, 1.0))) – Temporal frequency (number of periods to shift over).
h (array_like, default=((255, 255, 255),)) – Hues i.e. colors of fringe patterns.
The directions ‘D’ and the sets K are multiplexed, resulting in a crossed fringe pattern if ‘D’ ≡ 2.
It can only be activated if ‘D’ ∨ ‘K’ > 1 i.e. ‘D’ * ‘K’ > 1.
The amplitude ‘b’ is reduced by the factor ‘D’ * ‘K’.
Usually ‘f’ equals 1 and is essentially only changed if frequency division multiplexing (‘FDM’) is activated:
Each set per direction receives an individual temporal frequency ‘f’,
which is used in temporal demodulation to distinguish the individual sets.
A minimal number of shifts Nmin ≥ ⌈ 2 * fmax + 1 ⌉ is required
to satisfy the sampling theorem and N is updated automatically if necessary.
If one wants a static pattern, i.e. one that remains congruent when shifted, set ‘static’ to True.
The directions ‘D’ are multiplexed, resulting in a crossed fringe pattern.
The amplitude ‘B’ is halved.
It can only be activated if we have two directions, i.e. ‘D’ ≡ 2.
The number of frames ‘T’ is reduced by the factor 2.
The shifts are multiplexed into the color channel, resulting in an RGB fringe pattern.
It can only be activated if all shifts equal 3, i.e. ‘N’ ≡ 3.
The number of frames ‘T’ is reduced by the factor 3.
b (np.ndarray) – Modulation: amplitude of the cosine signal.
x (np.ndarray) – Registration: decoded screen coordinates.
p (np.ndarray, optional) – Local phase.
k (np.ndarray, optional) – Fringe order.
r (np.ndarray, optional) – Residuals from the optimization-based unwrapping process.
u (np.ndarray, optional) – Uncertainty of positional decoding in pixel units
Raises:
ValueError – If the number of frames of I and the attribute T of the Fringes instance don’t match.
If WDM is active but I does not have 3 color channels.
References
Examples
>>> fromfringesimportFringes>>> f=Fringes()>>> I=f.encode()>>> Irec=I# todo: replace this line with the recorded data as in 'record.py'
frames (int or Sequence of ints, optional) – Indices of the frames to be encoded.
The default, frames=None, will encode all frames at once.
Else, frames is used as an index into the fringe pattern sequence
(negative indexes are allowed; indexes with magnitude larger than T are wrapped around).
Returns:
I – Fringe pattern sequence.
Return type:
np.ndarray
Notes
To receive the frames iteratively (i.e. in a lazy manner),
simply iterate over the Fringes instance.
Examples
>>> fromfringesimportFringes>>> f=Fringes()
Encode the complete fringe pattern sequence.
>>> I=f.encode()
Create a generator to receive the frames iteratively, i.e. in a lazy manner.
>>> I=(frameforframeinf)
Call the instance to encode the complete fringe pattern sequence.
Cartesian indexing xy (the default) will index the row first,
while matrix indexing ij will index the colum first.
This equivalent to the argument ‘indexing’ in numpy.meshgrid().
Load parameters from a config file to the Fringes instance.
Warning
The parameters are only loaded if the config file provides the section fringes.
Parameters:
fname (str, optional) – File name of the file to load.
Supported file formats are: *.json, *.yaml.
If fname is not provided, the file .fringes.yaml within the user home directory is loaded.
v (array_like) – Spatial frequencies at which to determine the normalized modulation.
PSF (float, default=0) – Standard deviation of the point spread function.
Returns:
b – Relative modulation, at spatial frequencies ‘v’.
‘b’ is in the same shape as ‘v’.
Return type:
np.ndarray
Raises:
ValueError – If ‘v’ contains negative numbers.
Notes
If the private attribute _mtf of the Fringes instance is not None, the MTF is interpolated from previous measurements.
Else, if PSF is larger than zero, the MTF is computed from the optical transfer function of the optical system,
i.e. as the magnitude of the Fourier-transformed ‘Point Spread Function’ (PSF).
Save the parameters of the Fringes instance to a config file.
Within the file, the parameters are written to the section fringes.
Parameters:
fname (str, optional) – File name of the file to save.
Supported file formats are: *.json, *.yaml.
If fname is not provided, the parameters are saved to
the file .fringes.yaml within the user home directory.
The normalized modulation transfer function is a cubic spline interpolator.
It is set to the private attribute ‘_mtf’ and used when the method ‘mtf()’ is called.
Uncertainty of positional decoding, in pixel units.
Using inverse variance weighting in unwrapping
and assuming no fringe order errors.
Parameters:
ui (float | np.ndarray, default=np.sqrt(1 / 12)) – Standard deviation of intensity noise.
The default assumes only quantization noise.
If np.ndarray, it must have image shape (Y, X, C).
b (float | np.ndarray, optional) – Modulation.
If np.ndarray, it must have video shape (T, Y, X, C).
a (float | np.ndarray, optional) – Offset (mean number of gray values).
If np.ndarray, it must have video shape (T, Y, X, C).
K (float, optional) – System gain of used camera, in units DN/electron.
dark_noise (float, optional) – Dark noise of used camera, in units electrons.
Returns:
u – Uncertainty of positional decoding, in pixel units.
Return type:
np.ndarray
Note
If a, K and dark_noise are given, ui is ignored and calculated from them.
In any case, if either ui, b or a is a numpy.ndarray,
they must be broadcastable and hence their shape must end in the same (Y, X, C) values
(the function takes care of those who are in front).
Examples
>>> fromfringesimportFringes>>> f=Fringes()
Assuming only quantization noise and using f.B as b (both by default):
>>> u=f.uncertainty()
Setting ui and b with floats:
>>> u=f.uncertainty(ui=2.28,b=100)
Using decoded values (numpy.ndarrays) and camera parameters:
>>> I=f.encode()>>> Irec=I# todo: replace this line with the recorded data as in 'record.py'>>> a,b,x=f.decode(Irec)
This includes the modulation transfer function
(computed from the imaging system’s point spread function),
and intensity noise added by the camera.
Parameters:
I (np.ndarray) – Image (sequence) with values within [0, 1].
I0 (float | np.ndarray, default=0.0) – Offset with values within [0, 2**`b`-1].
T (float | np.ndarray, default=1.0) – Transmission factor with values within [0, 1].
M (int, default=1) – Optical magnification >= 1.
PSF (float, default=0.0) – Standard deviation of the point spread function, in pixel units.
K (float, default=0.038 (@ bits = 8).) – System gain of the digital camera, in units of DN (digital numbers) / electron.
dark_noise (float, default=13.7) – Dark noise of the digital camera, in units of electrons.
dark_current (float, default=14.2) – Dark current of the digital camera, in units of electrons.
bits (int, default=8) – Number of bits to store information of one pixel.
This is used to determine the output dtype.
If e.g. bits equals 8, Imax will be 2 ** 8 - 1 = 255 and dtype will be uint8.
If e.g. bits equals 0, Imax will be 1 and dtype will be float.
clip (bool, default=True) – If True (default), the output will be clipped after noise is applied.
This is needed to maintain the proper image data range.
rng ({numpy.random.Generator, int}, optional) – Pseudo-random number generator.
By default, a PCG64 generator is used (see numpy.random.default_rng()).
If rng is an int, it is used to seed the generator.
This applies for pattern sequences
recorded with a line scan camera,
where each frame has been displayed and captured
as the object moved by one pixel.
Parameters:
I (np.ndarray) – Pattern sequence.
It is reshaped to video-shape (frames T, height Y, width X, color channels C) before processing.
T (int) – Number of frames of the pattern sequence.
Returns:
I – Unzipped pattern sequence.
Return type:
np.ndarray
Raises:
ValueError – If the number of frames of I and the number of frames of the pattern sequence T don’t match.
Examples
>>> fromfringesimportFringes>>> fromfringes.utilimportunzip>>> f=Fringes()>>> I=f.encode()>>> Irec=I.swapaxes(0,1).reshape(-1,f.T,f.X,f.C)# zip; this is how a line camera would record>>> Irec=unzip(Irec,f.T)
Transforms video data into the standardized shape (T, Y, X, C), where
T is number of frames, Y is height, X is width, and C is number of color channels.
channels (set of ints, default = {1, 3, 4}) – Allowed number of color channels.
Returns:
videodata – Standardized version of data, in shape (T, Y, X, C), where
T is number of frames, Y is height, X is width, and C is number of color channels.
Return type:
ndarray
Notes
Ensures that the array becomes 4-dimensional
and that the length of the last dimension is in channels.
To do this, leading dimensions may be flattened.