tb_monogenic_orientation — 2D typed op

Data kinds: qimageimage

Call: fullseye.apply(img, "tb_monogenic_orientation", a=0.5, b=0.5) (the 2-D model is one image plus two scalar knobs a,b∈[0,1])

tb_monogenic_orientation: input → output

*The figure is the actual output on a synthetic 128×128 input. Left: input, right: output. Point clouds are drawn as a top-down scatter (brightness = z), 1-D series as a line plot, volumes as the maximum-intensity projection along z, videos as the middle frame, complex images as magnitude; return values that are not pictures are shown as the values themselves.*

*The output is shown in a viridis-like pseudo-colour (dark purple = low, yellow = high) so that a field of quantities — distance, phase, orientation, depth — can be read.*

*Knob a does not change the output (measured: identical at 0.1 / 0.5 / 0.9).*

*Knob b does not change the output (measured: identical at 0.1 / 0.5 / 0.9).*

Stages (the ops that come before → this op, left to right):

tb_monogenic_orientation: stages (docs site)

On other images (synthetic scene / photo / coins. Top row: inputs, bottom row: their outputs. Knobs at default):

tb_monogenic_orientation: other inputs (docs site)

Usage

Local orientation `atan2(R2, R1)` of a monogenic signal. → (H, W).

Radians in `[0, pi): an orientation is defined modulo pi` (a grating at

10 degrees and one at 190 degrees are the same grating), and the value is

folded into that range rather than left in `(-pi, pi]` where the same

structure would read as two different numbers on either side of a contrast

reversal. `display=True maps it to [0, 1]`.

Continuous, not quantised — the angle is read directly from two filters,

for any angle, where a steerable bank with `K` orientations interpolates

between its `K`. Measured against eight grid-exact grating orientations the

error is at most 3.6e-15 rad, including the obliques. (Whether that

buys anything downstream is a separate question, and the measured answer is

mostly *no* — see :func:riesz_displacement.)

Where it is undefined, and the mask is not the one you expect. The

orientation dies where the *Riesz vector* dies, which is at every

even-symmetric point — local phase 0 or pi, the crest of a bright or dark

line — and the amplitude is at full strength there. Measured on a 45-degree

grating, the worst orientation error over the whole frame is 0.2764 rad, at a

pixel where `|R| = 6.8e-16 and :func:monogenic_amplitude` reads

`1.0000`. So masking on the amplitude does not protect you; mask on

`hypot(q[..., 1], q[..., 2])`, the Riesz magnitude. With that mask the

error over the same eight orientations is at most 3.6e-15 rad.

Where the Riesz vector is exactly zero, `atan2(0, 0) = 0` is returned —

a *value*, not a measurement.

Raises `ValueError`: the input is not a valid quaternion field, or its

`k` component is non-zero; *display* is not a bool.

Typed bridge of the quat op `monogenic_orientation into the 2-D evolution registry: the same implementation, called under the op(v, a, b) convention. This op has no tunable parameter; a and b` are unused.

References (sample data, literature)

• 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.

Try it in Studio

The program below has been verified to run (same input as the figure). In Studio's help this block becomes buttons that load and run it on the spot.

img_to_monogenic 0.50 0.50
tb_monogenic_orientation 0.50 0.50

▸ Load this pipeline  ·  Load & run

Runnable examples (verified samples that actually call this op)

The examples below call the underlying ledger op monogenic_orientation. This bridge op is the same implementation adapted to the fn(v, a, b) convention, so the behaviour carries over unchanged (only the call form differs).

quaternion_monogenicpy -3.11 examples/quaternion_monogenic.py

Ops the type connects to (they accept image as input)

identity · gaussian · mean_box · bilateral · unsharp · median · min_filter · max_filter

Same category (typed)

tb_points_to_voxel · tb_estimate_point_normals · tb_iss_keypoints · tb_project_points · tb_render_point_depth · tb_statistical_outlier_removal · tb_radius_outlier_removal · tb_voxel_grid_downsample


*Provenance: ops.py — 2D 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.