contour op• Data kinds: image2d × mask → table
• Call: import fullseye as fs; fs.ledger.chan_vese_evolve(image, init, *, method: 'str' = 'convex', mu: 'float' = 0.1, nu: 'float' = 0.0, lambda1: 'float' = 1.0, lambda2: 'float' = 1.0, eps: 'float' = 1.0, eta: 'float' = 0.1, dt: 'float' = 5.0, n_iter: 'int' = 200, n_inner: 'int' = 200, tol: 'float' = 0.0, record_every: 'int' = 0) -> 'Dict[str, object]' (to call the implementation directly, import segcontour; segcontour.chan_vese_evolve(image, init, *, method: 'str' = 'convex', mu: 'float' = 0.1, nu: 'float' = 0.0, lambda1: 'float' = 1.0, lambda2: 'float' = 1.0, eps: 'float' = 1.0, eta: 'float' = 0.1, dt: 'float' = 5.0, n_iter: 'int' = 200, n_inner: 'int' = 200, tol: 'float' = 0.0, record_every: 'int' = 0) -> 'Dict[str, object]'; from the registry, opssegmentation.get("chan_vese_evolve"))
Minimises the two-phase Chan–Vese 2001 energy (by default alternating minimisation of the convex relaxation; the level-set gradient descent can also be chosen) (chan_vese_evolve).
2 methods:
method="convex" (default) = alternating minimisation of updating c (inside/outside means = optimal) and updating the partition with c fixed. The partition update solves the convex relaxation min_(u∈[0,1]) μ TV(u) + Σ (ν + λ1 (I − c1)² − λ2 (I − c2)²) u of Chan–Esedoglu–Nikolova 2006 with Chambolle–Pock for n_inner iterations and makes it 2-valued at 1/2 (TV uses anisotropic forward differences = for a 2-valued image, the number of 4-neighbourhood cracks = perimeter_sharp of chan_vese_energy. By the discrete coarea formula, cutting the minimiser of the relaxation at any threshold gives a 2-valued minimiser). The sharp energy (energy = energy_sharp of chan_vese_energy) is monotonically non-increasing under the alternating minimisation — if an error of the inner solver looks set to increase it, the update is discarded and the run stops (n_guard, should be 0). method="level_set" = descends the smooth energy (energy of chan_vese_energy) along the exact gradient of the discrete energy.
Gradient = μ(δ_ε'(φ) |Dφ|_η + Dᵀ(δ_ε(φ) Dφ / |Dφ|_η)) − δ_ε(φ)(ν + λ1 (I − c1)² − λ2 (I − c2)²) (D = forward differences, Dᵀ = its adjoint. In the continuum limit it becomes the −δ_ε κ μ term, matching the sign-flipped right-hand side of eq. (9) of the paper). c1, c2 are optimal for each φ, so by the envelope theorem they do not enter the gradient. The step starts at dt and is halved until the Armijo condition E_new ≤ E − 10⁻⁴ dt |∇E|² holds (once it holds, the next iteration uses 1.1 times, capped at dt). Hence the energy is monotonically non-increasing (n_increase should be 0, the number of backtracks is n_rejected). Measured limitation: the exact gradient also descends by inflating |φ| to sharpen H_ε rather than moving the interface, so distant pixels (small δ_ε) effectively do not move and it stops in a local solution (ellipse + noise σ = 0.2: about 800 pixels wrong even after 300 iterations, convex:
a few tens of pixels). This is 1 of the reasons the paper lists reinitialisation as "optional". init = bool mask (inside) or φ (inside φ < 0).
Returns: mask (φ < 0), phi (for convex, the 2-valued signed distance), energy (first = initial), c1 / c2, n_rejected, n_guard, n_increase, duality_gap (primal-dual gap of convex's inner solver, per outer iteration), history (masks every record_every), n_iter, converged, method.
• halcon_segmentation family guide
• active_contours_and_level_sets — Variational and active contours, level sets — which contour stops where, and what it guarantees
• 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_active_contours — py -3.11 examples/poc_active_contours.py
table as input)contour)snake_evolve · gvf_field · chan_vese_energy · morph_chan_vese · morph_geodesic_ac · edge_stop_g · level_set_reinit · drle_evolve
*Provenance: segcontour.py — SEGMENTATION 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.