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"))
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.
• shape_description_2d family guide
• 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.
• poc_one_stroke_epicycles — py -3.11 examples/poc_one_stroke_epicycles.py
matrix as input)contour_epicycle_chain · contour_fourier_truncation_energy
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.