fringes package

Submodules

fringes.fringes module

class fringes.fringes.Fringes(*args, Y: int = 1200, X: int = 1920, H: int = 1, M: float = 1.0, D: int = 2, K: int = 3, T: int = 24, N: tuple | ndarray = array([[4, 4, 4], [4, 4, 4]]), l: tuple | ndarray = array([[147.69230769, 274.28571429, 21.57303371], [147.69230769, 274.28571429, 21.57303371]]), v: tuple | ndarray = array([[13., 7., 89.], [13., 7., 89.]]), f: tuple | ndarray = array([[1., 1., 1.], [1., 1., 1.]]), h: tuple | ndarray = array([[255, 255, 255]]), p0: float = 3.141592653589793, gamma: float = 1.0, A: float = 127.5, B: float = 127.5, beta: float = 0.5, V: float = 1.0, Vmin: float = 0.0, umax: float = 0.5, alpha: float = 1.0, dtype: str | dtype = 'uint8', grid: str = 'image', angle: float = 0.0, axis: int = 0, SDM: bool = False, WDM: bool = False, FDM: bool = False, static: bool = False, lmin: float = 8.0, indexing: str = 'xy', reverse: bool = False, verbose: bool = False, Bv: tuple | ndarray = None, PSF: float = 0.0, dark: float = 0.0, gain: float = 0.0, y0: float = 0.0, mode: str = 'fast')[source]

Bases: object

Easy-to-use class to configure, encode and decode customized fringe patterns using phase shifting algorithms.

Parameters:
  • *args (iterable) – Non-keyword arguments are explicitly discarded. Only keyword arguments are considered.

  • Y (<class 'int'>, default = 1200) – Height of fringe patterns.

  • X (<class 'int'>, default = 1920) – Width of fringe patterns.

  • H (<class 'int'>, default = 1) – Number of hues.

  • M (<class 'float'>, default = 1.0) – Number of averaged intensity samples.

  • D (<class 'int'>, default = 2) – Number of directions.

  • K (<class 'int'>, default = 3) – Number of sets (number of fringe patterns with different spatial frequencies).

  • T (<class 'int'>, default = 24) – Number of frames.

  • N (tuple | numpy.ndarray, default = [[4 4 4]) –

    [4 4 4]]

    Number of phase shifts.

  • l (tuple | numpy.ndarray, default = [[147.69230769 274.28571429 21.57303371]) –

    [147.69230769 274.28571429 21.57303371]]

    Wavelengths of fringe periods.

  • v (tuple | numpy.ndarray, default = [[13. 7. 89.]) –

    [13. 7. 89.]]

    Spatial frequencies (number of periods/fringes across maximum coding length).

  • f (tuple | numpy.ndarray, default = [[1. 1. 1.]) –

    [1. 1. 1.]]

    Temporal frequency (number of periods to shift over).

  • h (tuple | numpy.ndarray, default = [[255 255 255]]) – Hues i.e. colors of fringe patterns.

  • p0 (<class 'float'>, default = 3.141592653589793) – Phase offset within interval (-2pi, +2pi).

  • gamma (<class 'float'>, default = 1.0) – Gamma correction factor used to compensate nonlinearities of the display response curve.

  • A (<class 'float'>, default = 127.5) – Bias.

  • B (<class 'float'>, default = 127.5) – Amplitude.

  • beta (<class 'float'>, default = 0.5) – Relative bias (exposure), i.e. relative mean intensity ∈ [0, 1].

  • V (<class 'float'>, default = 1.0) – Fringe visibility (fringe contrast) ∈ [0, 1].

  • Vmin (<class 'float'>, default = 0.0) – Minimum visibility for measurement to be valid.

  • umax (<class 'float'>, default = 0.5) – Standard deviation of maximum uncertainty for measurement to be valid.

  • alpha (<class 'float'>, default = 1.0) – Factor for extending the coding range L.

  • dtype (str | numpy.dtype, default = uint8) – Data type.

  • grid (<class 'str'>, default = image) – Coordinate system of the fringe patterns.

  • angle (<class 'float'>, default = 0.0) – Angle of the coordinate system’s principal axis.

  • axis (<class 'int'>, default = 0) – Axis along which to shift if number of directions equals one.

  • SDM (<class 'bool'>, default = False) – Spatial division multiplexing.

  • WDM (<class 'bool'>, default = False) – Wavelength division multiplexing.

  • FDM (<class 'bool'>, default = False) – Frequency division multiplexing.

  • static (<class 'bool'>, default = False) – Flag for creating static fringes (so they remain congruent when shifted).

  • lmin (<class 'float'>, default = 8.0) – Minimum resolvable wavelength.

  • indexing (<class 'str'>, default = xy) – Indexing convention.

  • reverse (<class 'bool'>, default = False) – Flag for shifting fringes in reverse direction.

  • verbose (<class 'bool'>, default = False) – Flag for additionally returning intermediate and verbose results:

  • Bv (tuple | numpy.ndarray, default = None) – Modulation at spatial frequencies v.

  • PSF (<class 'float'>, default = 0.0) – Standard deviation of Point Spread Function for defocus.

  • dark (<class 'float'>, default = 0.0) – Dark noise of the digital camera (standard deviation).

  • gain (<class 'float'>, default = 0.0) – Overall system gain of digital camera.

  • y0 (<class 'float'>, default = 0.0) – Dark signal.

  • mode (<class 'str'>, default = fast) – Mode for remapping.

property A: float

Bias.

property B: float

Amplitude.

property Bv: ndarray

Modulation at spatial frequencies v.

The modulation values are determined from a measurement.

property C: int

Number of color channels.

property D: int

Number of directions.

property DR: ndarray

Dynamic range of the phase shift coding.

It is a measure of how many points can be distinguished within the unambiguousmeasurement range [0, UMR).

property DRdB: ndarray

Dynamic range. [DRdB] = dB.

property FDM: bool

Frequency division multiplexing.

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.

property H: int

Number of hues.

property Imax: int

Maximum gray value.

property K: int

Number of sets (number of fringe patterns with different spatial frequencies).

property L: float

Coding range. [L] = px.

property M: float

Number of averaged intensity samples.

MTF(v: float | ndarray) ndarray[source]

Modulation Transfer Function.

Returns the relative modulation at spatial frequencies v.

Parameters:

v (np.ndarray) – Spatial frequencies at which to determine the normalized modulation.

Returns:

B – Relative modulation, in the same shape as v.

Return type:

np.ndarray

Notes

  • If the attribute Bv of the Fringes instance is not None, the MTF is interpolated from previous measurements.

  • Else, if the attribute PSF of the Fringes instance 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).

  • Else, it returns ones.

property N: ndarray

Number of phase shifts.

property PSF: float

Standard deviation of Point Spread Function for defocus. [PSF] = px.

property R: ndarray

Lengths of fringe patterns for each direction. [R] = px.

property SDM: bool

Spatial division multiplexing.

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.

property SNR: ndarray

Signal-to-noise ratio of the phase shift coding.

It is a masure of how many points can be distinguished within the screen length [0, R)

property SNRdB: ndarray

Signal-to-noise ratio. [SNRdB] = dB.

property T: int

Number of frames.

property TDM: bool

Temporal division multiplexing.

property UMR: ndarray

Unambiguous measurement range. [UMR] = px

The coding is only unique within the interval [0, UMR); after that it repeats itself.

The UMR is derived from l and v:

  • If l ∈ ℕ, UMR = lcm(l), with lcm being the least common multiple.

  • Else, if v ∈ ℕ, UMR = L / gcd(v), with gcd being the greatest common divisor.

  • Else, if l ∨ v ∈ ℚ, lcm resp. gcd are extended to rational numbers.

  • Else, if l ∧ v ∈ ℝ ∖ ℚ, UMR = prod(l), with prod being the product operator.

property V: float

Fringe visibility (fringe contrast) ∈ [0, 1].

property Vmin: float

Minimum visibility for measurement to be valid.

property WDM: bool

Wavelength division multiplexing.

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.

property X: int

Width of fringe patterns. [X] = px.

property Y: int

Height of fringe patterns. [Y] = px.

property alpha: float

Factor for extending the coding range L.

property angle: float

Angle of the coordinate system’s principal axis.

property axis: int

Axis along which to shift if number of directions equals one.

Either 0 or 1.

property beta: float

Relative bias (exposure), i.e. relative mean intensity ∈ [0, 1].

brightfield(src: ndarray, t: float = 0.1, k: int = 3) ndarray[source]

Bright-field.

Parameters:
  • src (np.ndarray) – Source activation heatmap.

  • t (float) – Threshold within [0, 1].

Returns:

bf

Return type:

Bright-field.

brightfield_inverse(src: ndarray, t: float = 0.1, k: int = 3) ndarray[source]

Inverse bright-field

with radiomatric compensation assuming a linear response function for display/projector and camera.

Parameters:
  • src (np.ndarray) – Source activation heatmap.

  • t (float) – Threshold within [0, 1].

  • k (int) – Edge ength of morphological operator.

Returns:

bfi

Return type:

Inverse bright-field.

coordinates() ndarray[source]

Generate the coordinate matrices of the coordinate system defined in grid.

Returns:

xi – Coordinate matrices.

Return type:

np.ndarray

property dark: float

Dark noise of the digital camera (standard deviation). [dark] = electrons.

darkfield(src: ndarray, t: float = 0.1, k: int = 3) ndarray[source]

Dark-field.

Parameters:
  • src (np.ndarray) – Source activation heatmap.

  • t (float) – Threshold within [0, 1].

Returns:

df

Return type:

Dark-field.

decode(I: ndarray, verbose: bool = False, despike: bool = False, denoise: bool = False) namedtuple[source]

Decode fringe patterns.

Parameters:
  • I (np.ndarray) –

    Fringe pattern sequence. It is reshaped to videoshape (frames T, height Y, width X, color channels C) before processing.

    Note

    It must have been encoded with the same parameters set to the Fringes instance as the encoded one.

  • verbose (bool, optional) – If this or the argument verbose of the Fringes instance is set to True, additional infomation is computed and retuned. This includes: phase, residuals, orders, uncertainty, visibility and exposure.

  • despike (bool, optional) – If this is set to true, single pixel outliers in the unwrapped phase map are replaced by their local neighborhood using a median filter.

  • denoise (bool, optional) – If this is set to True, the unwrapped phase map is smoothened by a bilateral filter which is edge-preserving.

Returns:

  • brightness (np.ndarray) – Local background signal.

  • modulation (np.ndarray) – Local amplitude of the cosine signal.

  • registration (np.ndarray) – Decoded coordinates.

    Note

    The registration is a mapping in the same pixel grid as the camera sensor and contains the information where each camera pixel, i.e. each camera sightray, was looking at during the fringe pattern acquisition.

  • phase (np.ndarray, optional) – Local phase.

  • orders (np.ndarray, optional) – Fringe orders.

  • residuals (np.ndarray, optional) – Residuals from the optimization-based unwrapping process.

  • uncertainty (np.ndarray, optional) – uncertainty of positional decoding in pixel units

  • visibility (np.ndarray, optional) – Local visibility (fringe contrast).

  • exposure (np.ndarray, optional) – Local exposure (relative average intensity).

Raises:

AssertionError – If the number of frames of I and the attribute T of the Fringes instance don’t match.

Examples

>>> import fringes as frng
>>> f = frng.Fringes()
>>> I = f.encode()
>>> A, B, x = f.decode(I)
>>> A, B, x, p, k, r, u, V, H = f.decode(I, verbose=True)
defaults: dict = {'A': 127.5, 'B': 127.5, 'Bv': None, 'D': 2, 'FDM': False, 'H': 1, 'K': 3, 'M': 1.0, 'N': array([[4, 4, 4],        [4, 4, 4]]), 'PSF': 0.0, 'SDM': False, 'T': 24, 'V': 1.0, 'Vmin': 0.0, 'WDM': False, 'X': 1920, 'Y': 1200, 'alpha': 1.0, 'angle': 0.0, 'axis': 0, 'beta': 0.5, 'dark': 0.0, 'dtype': 'uint8', 'f': array([[1., 1., 1.],        [1., 1., 1.]]), 'gain': 0.0, 'gamma': 1.0, 'grid': 'image', 'h': array([[255, 255, 255]]), 'indexing': 'xy', 'l': array([[147.69230769, 274.28571429,  21.57303371],        [147.69230769, 274.28571429,  21.57303371]]), 'lmin': 8.0, 'mode': 'fast', 'p0': 3.141592653589793, 'reverse': False, 'static': False, 'umax': 0.5, 'v': array([[13.,  7., 89.],        [13.,  7., 89.]]), 'verbose': False, 'y0': 0.0}

Default values for params.

deinterlace(I: ndarray) ndarray[source]

Deinterlace fringe patterns.

This for fringe patterns which were acquired with a line scan camera while each frame has been displayed and captured while the object was moving by one pixel.

Parameters:

I (np.ndarray) – Fringe pattern sequence. It is reshaped to videoshape (frames T, height Y, width X, color channels C) before processing.

Returns:

I – Deinterlaced fringe pattern sequence.

Return type:

np.ndarray

Raises:

AssertionError – If the number of frames of I and the attribute T of the Fringes instance don’t match.

Examples

>>> import fringes as frng
>>> f = frng.Fringes()
>>> I = f.deinterlace(I)
property dtype: dtype

Data type.

The following values can be set:

  • ‘bool’

  • ‘uint8’

  • ‘uint16’

  • ‘float32’

  • ‘float64’

property efficiency: ndarray

Coding efficiency.

encode(xi: list | ndarray = None, frames: int | tuple = None, rint: bool = True, simulate: bool = False) ndarray[source]

Encode fringe patterns.

Parameters:
  • xi (None or list of arrays or one array of grid indices, optional) – List of coordinate matrices from coordinate vectors in Cartesian (‘xy’) indexing (e.g. from numpy.meshgrid). The default is equal to ‘numpy.indices((self.Y, self.X))’.

  • frames (None or int or tuple of ints, optional) – Indices of the frames to be encoded. The default, frames=None, will encode all frames at once. If frames is negative, it counts from the last to the first frame. If frames contains numbers whose magnitude is larger than the total number of frames (as specified by the attribute T of the Fringes instance), it is wrapped around. If frames is a tuple of ints, only the frames specified in the tuple are encoded. If indices occur more than once, only the first occurence is encoded.

  • rint (bool, optional) – If this is set to True (the default) and the used dtype (attribute dtype of the Fringes instance) is of type interger, the encoded patterns will be rounded to the nearest integer. If this is set False and the used dtype is of type interger, the fractional part of the encoded patterns will be discarded.

  • simulate (bool, optional) – If this is set to True, the acquisition, i.e. the transmission channel, will be simulated. This includes the modulation transfer function (computed from the imaging system’s point spread function) and intensity noise added by the camera. The required parameters for this are the instance’s attributes PSF, gain, dark_current, dark, quant and ‘shot’ . Default is False.

Returns:

I – Fringe pattern sequence.

Return type:

np.ndarray

Raises:

Value Error – The length of the list/number of coordinate matrices doesn’t match the Fringes instance’s parameter D, the smallest contained coodrinate is smaller than zero or the largest contained coodinate is equal to or exceeds the Fringes instance’s width X resp. height Y.

Notes

To receive the frames iteratively (i.e. in a lazy manner), simply iterate over the Fringes instance. Alternatively, to receive arbitrary frames, index the Fringes instance directly, either with an integer, a tuple or a slice.

Examples

>>> import fringes as frng
>>> f = frng.Fringes()

Encode the complete fringe pattern sequence.

>>> I = f.encode()

Encode the first frame of the fringe pattern sequence.

>>> I = f.encode(frames=0)
>>> I = f[0]
>>> I = next(iter(f))

Encode the last frame of the fringe pattern sequence.

>>> I = f.encode(frames=-1)
>>> I = f[-1]

Encode the first two frames of the fringe pattern sequence.

>>> I = f.encode(frames=(0, 1))
>>> I = f[0, 1]
>>> I = f[:2]

Create a generator to receive the frames iteratively, i.e. in a lazy manner.

>>> I = (frame for frame in f)
property eta: float

Coding efficiency.

property f: ndarray

Temporal frequency (number of periods to shift over).

property gain: float

Overall system gain of digital camera. [gain] = DN / electrons.

property gamma: float

Gamma correction factor used to compensate nonlinearities of the display response curve.

static gamma_auto_correct(I: ndarray) ndarray[source]

Automatically estimate and apply the gamma correction factor to linearize the display/camera response curve.

Parameters:

I (np.ndarray) – Recorded data.

Returns:

J – Linearized data.

Return type:

np.ndarray

glossary: dict = {'A': 'Bias.', 'B': 'Amplitude.', 'Bv': 'Modulation at spatial frequencies `v`.\n\n        The modulation values are determined from a measurement.', 'C': 'Number of color channels.', 'D': 'Number of directions.', 'DR': 'Dynamic range of the phase shift coding.\n\n        It is a measure of how many points can be distinguished within the unambiguousmeasurement range [0, UMR).\n        ', 'DRdB': 'Dynamic range. [DRdB] = dB.', 'FDM': 'Frequency division multiplexing.\n\n        The directions D and the sets K are multiplexed, resulting in a crossed fringe pattern if D 2.\n        It can only be activated if D K > 1 i.e. D * K > 1.\n        The amplitude B is reduced by the factor D * K.\n        Usually f equals 1 and is essentially only changed if frequency division multiplexing (FDM) is activated:\n        Each set per direction receives an individual temporal frequency f,\n        which is used in temporal demodulation to distinguish the individual sets.\n        A minimal number of shifts Nmin 2 * fmax + 1 is required\n        to satisfy the sampling theorem and N is updated automatically if necessary.\n        If one wants a static pattern, i.e. one that remains congruent when shifted, set static to True.\n        ', 'H': 'Number of hues.', 'Imax': 'Maximum gray value.', 'K': 'Number of sets (number of fringe patterns with different spatial frequencies).', 'L': 'Coding range.\n        [L] = px.', 'M': 'Number of averaged intensity samples.', 'N': 'Number of phase shifts.', 'PSF': 'Standard deviation of Point Spread Function for defocus.\n        [PSF] = px.', 'R': 'Lengths of fringe patterns for each direction.\n        [R] = px.', 'SDM': 'Spatial division multiplexing.\n\n        The directions D are multiplexed, resulting in a crossed fringe pattern.\n        The amplitude B is halved.\n        It can only be activated if we have two directions, i.e. D 2.\n        The number of frames T is reduced by the factor 2.', 'SNR': 'Signal-to-noise ratio of the phase shift coding.\n\n        It is a masure of how many points can be distinguished within the screen length [0, R)\n        ', 'SNRdB': 'Signal-to-noise ratio.\n        [SNRdB] = dB.', 'T': 'Number of frames.', 'TDM': 'Temporal division multiplexing.', 'UMR': 'Unambiguous measurement range.\n        [UMR] = px\n\n        The coding is only unique within the interval [0, UMR); after that it repeats itself.\n\n        The UMR is derived from l and v:\n\n        - If l ℕ, UMR = lcm(l), with lcm being the least common multiple.\n\n        - Else, if v ℕ, UMR = L / gcd(v), with gcd being the greatest common divisor.\n\n        - Else, if l v ℚ, lcm resp. gcd are extended to rational numbers.\n\n        - Else, if l v ℚ, UMR = prod(l), with prod being the product operator.\n        ', 'V': 'Fringe visibility (fringe contrast) [0, 1].', 'Vmin': 'Minimum visibility for measurement to be valid.', 'WDM': 'Wavelength division multiplexing.\n\n        The shifts are multiplexed into the color channel, resulting in an RGB fringe pattern.\n        It can only be activated if all shifts equal 3, i.e. N 3.\n        The number of frames T is reduced by the factor 3.', 'X': 'Width of fringe patterns.\n        [X] = px.', 'Y': 'Height of fringe patterns.\n        [Y] = px.', 'alpha': 'Factor for extending the coding range `L`.', 'angle': "Angle of the coordinate system's principal axis.", 'axis': 'Axis along which to shift if number of directions equals one.\n\n        Either `0` or `1`.', 'beta': 'Relative bias (exposure), i.e. relative mean intensity [0, 1].', 'dark': 'Dark noise of the digital camera (standard deviation).\n        [dark] = electrons.', 'dtype': "Data type.\n\n        The following values can be set:\n\n        - 'bool'\n\n        - 'uint8'\n\n        - 'uint16'\n\n        - 'float32'\n\n        - 'float64'\n\n        ", 'efficiency': 'Coding efficiency.', 'eta': 'Coding efficiency.', 'f': 'Temporal frequency (number of periods to shift over).', 'gain': 'Overall system gain of digital camera.\n        [gain] = DN / electrons.', 'gamma': 'Gamma correction factor used to compensate nonlinearities of the display response curve.', 'grid': "Coordinate system of the fringe patterns.\n\n        The following values can be set:\n\n        'image':     The top left corner pixel of the grid is the origin and positive directions are right- resp. downwards.\n\n        'Cartesian': The center of grid is the origin and positive directions are right- resp. upwards.\n\n        'polar':     The center of grid is the origin and positive directions are clockwise resp. outwards.\n\n        'log-polar': The center of grid is the origin and positive directions are clockwise resp. outwards.\n        ", 'h': "Hues i.e. colors of fringe patterns.\n\n        Possible values are any sequence of RGB color triples within the interval [0, 255].\n        However, black (0, 0, 0) is not allowed.\n\n        The hue values can also be set by assigning any combination of the following characters as a string:\n\n        - 'r': red \n\n        - 'g': green\n\n        - 'b': blue\n\n        - 'c': cyan\n\n        - 'm': magenta\n\n        - 'y': yellow\n\n        - 'w': white\n\n\n        Before decoding, repeating hues will be fused by averaging.", 'indexing': 'Indexing convention.\n\n        Cartesian indexing `xy` (the default) will index the row first,\n        while matrix indexing `ij` will index the colum first.\n        ', 'l': 'Wavelengths of fringe periods.\n        [l] = px.\n\n        When L changes, v is kept constant and only l is changed.', 'lmin': 'Minimum resolvable wavelength.\n        [lmin] = px.', 'lopt': 'Optimal wavelength for minimal decoding uncertainty.\n        [lopt] = px.', 'mode': "Mode for remapping.\n\n        The following values can be set:\n\n        - 'fast'\n\n        - 'precise'\n        ", 'nbytes': 'Total bytes consumed by fringe pattern sequence.\n\n        Does not include memory consumed by non-element attributes of the array object.\n        ', 'p0': 'Phase offset within interval (-2pi, +2pi).\n\n        It can be used to e.g. let the fringe patterns start (at the origin) with a gray value of zero.\n        ', 'params': 'Base parameters required for en- & decoding fringe patterns.\n\n        This contains all property objects of the class which have a setter method,\n        i.e. are (usually) not derived from others.\n        ', 'q': 'Quantization step size.', 'quant': 'Quantization noise (standard deviation).\n        [quant] = DN.', 'reverse': 'Flag for shifting fringes in reverse direction.', 'shape': 'Shape of fringe pattern sequence in video shape (frames, height, with, color channels).', 'shot': 'Shot noise of digital camera (standard deviation).\n        [shot] = DN.', 'size': 'Number of pixels of fringe pattern sequence (frames * height * width * color channels).', 'static': 'Flag for creating static fringes (so they remain congruent when shifted).', 'u': 'Uncertainty of measurement (standard deviation).\n        [u] = px.\n\n        It is based on the phase noise model\n        and propagated through the unwrapping process and the phase fusion.', 'ui': 'Intensity noise.', 'umax': 'Standard deviation of maximum uncertainty for measurement to be valid.\n        [umax] = px.', 'upi': 'Phase uncertainty.\n        [upi] = rad', 'uwr': 'Phase unwrapping method.', 'v': 'Spatial frequencies (number of periods/fringes across maximum coding length).', 'verbose': 'Flag for additionally returning intermediate and verbose results:\n\n        - phase maps\n\n        - residuals\n\n        - fringe orders\n\n        - visibility\n\n        - exposure\n        ', 'vmax': 'Maximum resolvable spatial frequency.', 'vopt': 'Optimal spatial frequency for minimal decoding uncertainty.', 'x0': 'Coordinate offset.', 'y0': 'Dark signal.\n        [y0] = DN'}

Glossary.

property grid: str

Coordinate system of the fringe patterns.

The following values can be set:

‘image’: The top left corner pixel of the grid is the origin and positive directions are right- resp. downwards.

‘Cartesian’: The center of grid is the origin and positive directions are right- resp. upwards.

‘polar’: The center of grid is the origin and positive directions are clockwise resp. outwards.

‘log-polar’: The center of grid is the origin and positive directions are clockwise resp. outwards.

property h: ndarray

Hues i.e. colors of fringe patterns.

Possible values are any sequence of RGB color triples within the interval [0, 255]. However, black (0, 0, 0) is not allowed.

The hue values can also be set by assigning any combination of the following characters as a string:

  • ‘r’: red

  • ‘g’: green

  • ‘b’: blue

  • ‘c’: cyan

  • ‘m’: magenta

  • ‘y’: yellow

  • ‘w’: white

Before decoding, repeating hues will be fused by averaging.

property indexing: str

Indexing convention.

Cartesian indexing xy (the default) will index the row first, while matrix indexing ij will index the colum first.

property l: ndarray

Wavelengths of fringe periods. [l] = px.

When L changes, v is kept constant and only l is changed.

property lmin: float

Minimum resolvable wavelength. [lmin] = px.

load(fname: str = None) dict[source]

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, *.toml. If fname is not provided, the file .fringes.yaml within the user home directory is loaded.

Returns:

params – The loaded parameters as a dictionary. params may be empty.

Return type:

dict

Examples

>>> import os
>>> fname = os.path.join(os.path.expanduser("~"), ".fringes.yaml")
>>> import fringes as frng
>>> f = frng.Fringes()
>>> f.load(fname)
logger
property lopt: float

Optimal wavelength for minimal decoding uncertainty. [lopt] = px.

property mode: str

Mode for remapping.

The following values can be set:

  • ‘fast’

  • ‘precise’

property nbytes: int

Total bytes consumed by fringe pattern sequence.

Does not include memory consumed by non-element attributes of the array object.

optimize(T: int = None, umax: float = None) None[source]

Optimize the parameters of the Fringes instance.

Parameters:
  • T (int, optional) – Number of frames. If T is not provided, the number of frames from the Fringes instance is used. Then, the Fringes instance’s number of shifts N is distributed optimally over the directions and sets.

  • umax (float, optional) – Maximum allowable uncertainty. Must be greater than zero.

Notes

If umax is specified, the parameters are determined that allow a maximal uncertainty of umax with a minimum number of frames.

Else, the parameters of the Fringes instance are optimized to yield the minimal uncertainty using the given number of frames T.

property p0: float

Phase offset within interval (-2pi, +2pi).

It can be used to e.g. let the fringe patterns start (at the origin) with a gray value of zero.

property params: dict

Base parameters required for en- & decoding fringe patterns.

This contains all property objects of the class which have a setter method, i.e. are (usually) not derived from others.

property q: float

Quantization step size.

property quant: float

Quantization noise (standard deviation). [quant] = DN.

reset() None[source]

Reset parameters of the Fringes instance to default values.

property reverse: bool

Flag for shifting fringes in reverse direction.

save(fname: str = None) None[source]

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, *.toml. If fname is not provided, the parameters are saved to the file .fringes.yaml within the user home directory.

Examples

>>> import os
>>> fname = os.path.join(os.path.expanduser("~"), ".fringes.yaml")
>>> import fringes as frng
>>> f = frng.Fringes()
>>> f.save(fname)
property shape: tuple[int]

Shape of fringe pattern sequence in video shape (frames, height, with, color channels).

property shot: float

Shot noise of digital camera (standard deviation). [shot] = DN.

property size: uint64

Number of pixels of fringe pattern sequence (frames * height * width * color channels).

source(xi: ndarray, B: ndarray = None, u: ndarray | float = 0, dx: float = 1, mode: str = 'fast') ndarray[source]

Source activation heatmap.

The decoded coordinates (having sub-pixel accuracy) are mapped from the camera grid to integer positions on the screen grid with weights from the modulation.

This yields the source activation heatmap: a grid representing the screen (light source) with the pixel values being a relative measure of how much a screen (light source) pixel contributed to the exposure of the camera sensor.

The dimensions of the screen are taken from the Fringes instance.

Parameters:
  • xi (np.ndarray) – Registration, i.e. the decoded screen coordinates as seen by the camera. It is reshaped to videoshape (frames T, height Y, width X, color channels C) before processing.

  • B (np.ndarray, optional) – Modulation. Used for weighting. It is reshaped to videoshape (frames T, height Y, width X, color channels C) before processing. If B is an array, it must have the same height Y, width X and color channels C as xi. If B is not given, equal weights are used.

  • u (np.ndarray | float, optional) – Uncertainty. It is reshaped to videoshape (frames T, height Y, width X, color channels C) before processing. If u is an array, it must have the same height Y, width X and color channels C as xi. Default is zero.

  • dx (float, optional) – Size of one camera pixel, projected onto the screen, in units of screen pixels. Default is one.

  • mode (str, optional) – By default, fast remapping is applied. Else, inverse distance weighted remapping is applied, which is more precise but also more time-consuming.

Returns:

src – Source activation heatmap.

Return type:

np.ndarray

Notes

In fact, this is the inverse function of OpenCV’s remap() [3].

References

Examples

>>> import fringes as frng
>>> f = frng.Fringes()
>>> I = f.encode()
>>> A, B, x = f.decode(I)
>>> src = f.remap(x, B)
property static: bool

Flag for creating static fringes (so they remain congruent when shifted).

types: dict = {'A': <class 'float'>, 'B': <class 'float'>, 'Bv': tuple | numpy.ndarray, 'D': <class 'int'>, 'FDM': <class 'bool'>, 'H': <class 'int'>, 'K': <class 'int'>, 'M': <class 'float'>, 'N': tuple | numpy.ndarray, 'PSF': <class 'float'>, 'SDM': <class 'bool'>, 'T': <class 'int'>, 'V': <class 'float'>, 'Vmin': <class 'float'>, 'WDM': <class 'bool'>, 'X': <class 'int'>, 'Y': <class 'int'>, 'alpha': <class 'float'>, 'angle': <class 'float'>, 'axis': <class 'int'>, 'beta': <class 'float'>, 'dark': <class 'float'>, 'dtype': str | numpy.dtype, 'f': tuple | numpy.ndarray, 'gain': <class 'float'>, 'gamma': <class 'float'>, 'grid': <class 'str'>, 'h': tuple | numpy.ndarray, 'indexing': <class 'str'>, 'l': tuple | numpy.ndarray, 'lmin': <class 'float'>, 'mode': <class 'str'>, 'p0': <class 'float'>, 'return': None, 'reverse': <class 'bool'>, 'static': <class 'bool'>, 'umax': <class 'float'>, 'v': tuple | numpy.ndarray, 'verbose': <class 'bool'>, 'y0': <class 'float'>}

Types of ‘params’ values.

property u: ndarray

Uncertainty of measurement (standard deviation). [u] = px.

It is based on the phase noise model and propagated through the unwrapping process and the phase fusion.

property ui: float

Intensity noise.

property umax: float

Standard deviation of maximum uncertainty for measurement to be valid. [umax] = px.

property upi: float

Phase uncertainty. [upi] = rad

property uwr: str

Phase unwrapping method.

property v: ndarray

Spatial frequencies (number of periods/fringes across maximum coding length).

values = {'dtype': ('uint8', 'uint16', 'float32', 'float64'), 'grid': 'image', 'indexing': ('xy', 'ij'), 'mode': ('fast', 'precise')}
property verbose: bool

Flag for additionally returning intermediate and verbose results:

  • phase maps

  • residuals

  • fringe orders

  • visibility

  • exposure

property vmax: float

Maximum resolvable spatial frequency.

property vopt: float

Optimal spatial frequency for minimal decoding uncertainty.

property x0: float

Coordinate offset.

property y0: float

Dark signal. [y0] = DN

fringes.grid module

fringes.grid.cart(Y: int = 720, X: int = 720, a: float = 0)[source]
fringes.grid.img(Y: int = 720, X: int = 720, a: float = 0)[source]
fringes.grid.innercirc(Y: int = 720, X: int = 720)[source]

Boolean mask with True values inside inscribed circle.

fringes.grid.logpol(Y: int = 720, X: int = 720, a: float = 0)[source]
fringes.grid.pol(Y: int = 720, X: int = 720, a: float = 0)[source]
fringes.grid.rot(uu, vv, a)[source]

fringes.main module

fringes.util module

fringes.util.bilateral(I: ndarray, k: int = 7) ndarray[source]

Bilateral filter.

Edge-preserving, denoising filter.

Parameters:
  • I (np.ndarray) – Input data. It is reshaped to videoshape (frames ‘T’, height ‘Y’, width ‘X’, color channels ‘C’) before processing.

  • k (int, optional) – Size of the filter kernel. Default is 7.

Returns:

out – Filtered data.

Return type:

np.ndarray

fringes.util.circular_distance(a: ndarray, b: ndarray, c: float) ndarray[source]

Circular distance.

Parameters:
  • a (np.ndarray) – Start points.

  • b (np.ndarray) – End points.

  • c (float) – Circumference (distance) after which wrapping occurs.

Returns:

d – Circular distance from a to b.

Return type:

np.ndarray

Notes

For more details, see https://ieeexplore.ieee.org/document/9771407.

fringes.util.curvature(s: ndarray, calibrated: bool = False, normalize: bool = True) ndarray[source]

Mean curvature map.

Combuted by differentiating a slope map.

Parameters:
  • s (np.ndarray) – Slope map. It is reshaped to videoshape (frames ‘T’, height ‘Y’, width ‘X’, color channels ‘C’) before processing.

  • calibrated (bool, optional) – Flag indicating whether the input data ‘s’ originates from a calibrated measurement. Default is False. If this is False, the median value of the computed curvature map is added as an offset, so the median value of the final curvature map becomes zero.

  • normalize (bool) – Flag indicating whether to use the acrtangent function to nonlinearly map the codomain from [-inf, inf] to [-1, 1]. Default is True.

Returns:

c – Curvature map.

Return type:

np.ndarray

fringes.util.height(curv: ndarray, iterations: int = 3) ndarray[source]

Local height map.

It is computed by iterative local integration via an inverse laplace filter. Think of it as a relief, where height is only relative to the local neighborhood.

Parameters:
  • curv (np.ndarray) – Curvature map. It is reshaped to videoshape (frames ‘T’, height ‘Y’, width ‘X’, color channels ‘C’) before processing.

  • iterations (int, optional) – Number of iterations of the inverse Laplace filter kernel. Default is 3.

Returns:

z – Local height map.

Return type:

np.ndarray

fringes.util.vshape(data: ndarray) ndarray[source]

Standardizes the input data shape.

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.

Parameters:

data (ndarray) – Input data of arbitrary shape.

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 (1, 3, 4). To do this, leading dimensions may be flattened.

Examples

>>> import fringes as frng
>>> data = np.ones(100)
>>> videodata = frng.vshape(data)
>>> videodata.shape
(100, 1, 1, 1)
>>> data = np.ones(1200, 1920)
>>> videodata = frng.vshape(data)
>>> videodata.shape
(1, 1200, 1820, 1)
>>> data = np.ones(1200, 1920, 3)
>>> videodata = frng.vshape(data)
>>> videodata.shape
(1, 1200, 1820, 3)
>>> data = np.ones(100, 1200, 1920)
>>> videodata = frng.vshape(data)
>>> videodata.shape
(100, 1200, 1820, 1)
>>> data = np.ones(100, 1200, 1920, 3)
>>> videodata = frng.vshape(data)
>>> videodata.shape
(100, 1200, 1820, 3)
>>> data = np.ones(2, 3, 4, 1200, 1920)
>>> videodata = frng.vshape(data)
>>> videodata.shape
(24, 1200, 1820, 1)

Module contents

fringes.documentation()[source]
fringes.main()[source]