structured_light op• Data kinds: images → depth
• Call: import fullseye as fs; fs.ledger.decode_fringe(phase_shift_images, ref_phase=None, k=1.0, mask=None, min_modulation=None) -> 'np.ndarray' (to call the implementation directly, import fringe; fringe.decode_fringe(phase_shift_images, ref_phase=None, k=1.0, mask=None, min_modulation=None) -> 'np.ndarray'; from the registry, ops3d.get("decode_fringe"))
Decode a phase-shift image series in one go: wrapped → unwrap → (subtract the reference to get) height.
phase_shift_images: N-step phase-shifted fringe image sequence ((N,H,W) or a sequence of length N).
ref_phase: unwrapped phase of the reference plane (height 0). With None, height = k·(unwrapped).
k: phase→height calibration constant.
mask: optional. True=valid pixel. Invalid pixels are NaN.
min_modulation: optional. If given, pixels with modulation < this value are invalidated as low-confidence.
Returns: height map (2D float). With ref_phase=None, returns the continuous phase multiplied by k. Invalid pixels are NaN.
Procedure (as implemented): wrapped_phase → build the confidence mask (if min_modulation is given, modulation(stack) >= min_modulation; if mask is given, AND with it) → unwrap_phase_2d(wrapped, mask=confidence mask) → if ref_phase is None, k * unwrapped, otherwise phase_to_height (k * (unwrapped - ref_phase)).
Arguments:
• phase_shift_images: (N, H, W), N >= 3, equally spaced phase shifts.
• ref_phase: scalar or (H, W). Pass the phase of the reference plane unwrapped by the same procedure (so that the global offset of unwrap_phase_2d is treated the same in both, it is safest to use for the reference the result of decoding it with this op with ref_phase=None).
• k: phase→height calibration constant (unit/rad). Corresponds to the reciprocal of phase_gain of synthesize_fringes.
• mask: (H, W) bool, True = valid. min_modulation: lower bound of the modulation depth (around [0, 1]; drops shadowed and saturated pixels).
Validation (ValueError): image sequence not 3-D, N < 3, non-finite / mask of a different shape / ref_phase of a different shape / zero valid pixels. Without scikit-image, RuntimeError.
Returns: (H, W) float64. Invalid pixels are NaN. The unit is the unit of k.
Caution: it relies on spatial unwrapping, so in scenes split into islands by steps or occlusion, each island may keep a height offset of 2πm k. When absolute height is needed, the path is graycode_decode → absolute_phase → triangulate_column.
• depth_sensors — Depth sensors — ranging principles, real-device figures, how dropouts appear
• Sample-data catalog (download URLs / licences) — 2-D uses skimage.data (BSD/public domain) plus synthetic images; 3-D lists download URLs for real data sources (Stanford, PDS, …).
• Operator provenance and references — the sources of the research/methods this op family came from.
• structured_light — py -3.11 examples_3d/structured_light.py
depth as input)depth_to_points · tsdf_from_depth · to_points · fuse_to_voxel · depth_to_organized_points · normals_from_depth · occlusion_edges · bearing_angle_image
structured_light)wrapped_phase · unwrap_phase_2d · graycode_decode · synthesize_fringes · absolute_phase · triangulate_column
*Provenance: fringe.py — 3D operator registry. This per-op note is generated by tools/opdocs.py md (do not hand-edit).*
© 2026 Kazufumi Furuse — Fullseye operator documentation. Licensed under Apache-2.0.