contour_fourier_complex — SHAPE2D descriptor op

• Data kinds: pairs → matrix

• Call: import fullseye as fs; fs.ledger.contour_fourier_complex(points, n_harmonics=None, parametrisation='index') (to call the implementation directly, import fourierdesc; fourierdesc.contour_fourier_complex(points, n_harmonics=None, parametrisation='index'); from the registry, opsshape2d.get("contour_fourier_complex"))

Usage

Turns a closed contour into the coefficients of a complex Fourier series — z(t) = Σ c_k exp(2πi k t).

Arguments:

points: (N,2) closed-contour vertices. (row, col) order (same as fourierdesc).

n_harmonics: order K to keep (|k| <= K). None keeps up to the representable limit.

parametrisation: "index" = use the point index as an equally spaced parameter /

"arclength" = resample to equal arc length first, then transform.

Returns: real array of (2K+1, 3) (matrix). Rows are [k, Re c_k, Im c_k], with k being 0, 1, -1, 2, -2, … (from low frequency).

★Not silently deciding the parametrisation by default is the crux of this op. If a non-uniformly sampled contour is read with "index", extra time is allotted where points are dense, and the picture looks similar but the coefficients are something else (measured: the k=3 coefficient differed by a factor of 47). The default is "index" (the plain meaning of the FFT), but if you use it as a description of shape, choose "arclength".

★★Choosing "arclength" resamples the contour inside the op, so the returned coefficients describe the resampled contour, not the array you passed. Hence the prediction of contour_fourier_truncation_energy is exact "for the resampled contour", and if the caller measures the error on their own array, it does not match (measured: off by 1.15 at 512 points). When you want an exact prediction for your own array, resample by arc length first and then call with "index".

★Arc-length resampling is not idempotent: samples are joined by chords, so applying it 1 more time to a contour that is already equal-arc-length moves points by up to 3.73 px (mean 0.84 px), and the length shrinks by a further 3.25 %. Do not apply it twice.

Detailed usage guide

• shape_description_2d family guide

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.

• The canonical algorithm (author, year) and its uses are named in the family usage guide above.

Runnable examples (verified samples that actually call this op)

• poc_one_stroke_epicycles — py -3.11 examples/poc_one_stroke_epicycles.py

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

contour_epicycle_chain · contour_fourier_truncation_energy

Same category (descriptor)

elliptic_fourier · reconstruct · invariants · normalize · descriptor_distance · fourier_smooth · from_xld · contour_epicycle_chain


*Provenance: fourierdesc.py — SHAPE2D 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.