Files
vtracer/CHANGELOG.md
T
Chris Tsang 46a1b90ccd Add watershed clustering: hierarchical watershed frontend
An alternative region-forming frontend selected by --clustering watershed
(the color_mode field is replaced by clustering: color-cluster | bw |
watershed across CLI, Rust, Python, and Node — it selects the algorithm,
not a color space).

The algorithm is the watershed hierarchy by volume on the 4-adjacency
pixel graph, implemented from the papers:

  Cousty, Bertrand, Najman, Couprie, "Watershed Cuts: Minimum Spanning
  Forests and the Drop of Water Principle", IEEE TPAMI 31(8), 2009.
  Najman, Cousty, Perret, "Playing with Kruskal", ISMM 2013.

Edge weights are the max per-channel color difference between adjacent
pixels (no gradient image); a counting-sorted Kruskal pass builds the
binary partition tree as a flat parents array; a leaves-to-root pass
computes subtree area and volume; each merge's persistence (the volume of
the smaller side, plateau-corrected) becomes its MST edge's saliency; and
cutting the hierarchy is single-linkage over MST edges below the cut
level. Watershed cuts label every pixel — no watershed-line pixel class —
so the output is a strict, gapless partition that drops straight into
both stacked and cutout modes. Integer arithmetic and flat u32 arrays
throughout; deterministic across platforms; ~66 ms on a 1400x775 photo.

The one dial, --watershed-detail (0..=255), maps exponentially to a
target region count (each +25.5 doubles it) since the persistence
distribution is far too skewed for a linear threshold. filter_speckle
absorbs undersized basins into their most color-similar neighbour rather
than dropping them, preserving the partition. The largest region is
emitted first as a solid full-canvas background layer so stacked mode
keeps its seam-free overdraw; the mosaic flatten is unaffected.

Tests: partition invariant (disjoint masks tiling the canvas), detail
monotonicity, min-area absorption, determinism, watershed cases in the
pipeline/golden suites, stacked-vs-cutout interior equivalence, a
watershed seam test, and SegmentKey coverage for the new params.
2026-07-27 14:45:25 +01:00

3.5 KiB
Raw Blame History

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog and this project adheres to Semantic Versioning.

Unreleased

Added

  • Binary thresholding: a tunable fixed threshold and BradleyRoth adaptive thresholding for uneven lighting — CLI --threshold / --adaptive (--adaptive-window, --adaptive-t), also on Config, Python, and Node.
  • Cutout mode merges neighbouring mosaic regions whose colors are within one gradient step — the flattened tessellation no longer keeps the near-identical faces that stacked gradient layering splits a smooth area into.
  • Watershed clustering (--clustering watershed): an alternative region-forming frontend — a hierarchical watershed by volume on the pixel graph (Cousty et al., TPAMI 2009; Najman, Cousty & Perret, ISMM 2013), cut at a single --watershed-detail dial (0..=255, each +25.5 roughly doubles the region count). Content-adaptive regions with no watershed-line pixels; the partition drops straight into both stacked and cutout modes.

Changed

  • color_mode is replaced by clustering (color-cluster | bw | watershed) across the CLI (--clustering), Rust (Config::clustering, enum Clustering), Python, and Node — the field selects the region-forming algorithm, not a color space.

1.0.0-alpha.1 - 2026-07-24

Ground-up rewrite of VTracer into a vectorization framework with pluggable stages.

Added

  • Pluggable pipeline: swappable frontend (segmentation), color fitting (incl. custom palettes), curve-fitting backend, and an optimizer pass phase.
  • Mosaic mode: true seam-free, gapless tessellation via shared boundary-graph tracing (pixel, polygon, and spline fitters), replacing the old "cutout" that produced seams.
  • SVG optimizer: relative path syntax, shorthand commands, and coordinate-precision reduction for smaller files.
  • @visioncortex/vtracer Node.js package (npm): wasm core with a native image reader.
  • Rewritten Python bindings (vtracer-py) with a richer API; pyo3 bumped to 0.26 (fixes CPython 3.14 segfaults, #124).
  • CLI accepts positional input/output arguments (#114).

Changed

  • Workspace restructured into crates/vtracer (core lib), crates/vtracer-cli, crates/vtracer-py, and nodejs/.
  • CLI upgraded from clap 2.x to 4.x (#118).
  • filter_speckle CLI cap raised from 16 to 128, matching the web app (#115).
  • Depends on visioncortex 0.9.
  • Python wheel CI now runs only on release tags and manual dispatch, not on every commit.

Removed

  • The pre-1.0 cmdapp crate and the demo webapp GUI.

0.6.12 - 2026-02-04

  • Python Binding

0.6.5 - 2025-10-17

  • Update fastrand to 2.3

0.6.4 - 2024-03-29

  • Update visioncortex version to 0.8.8

0.6.3 - 2023-11-21

0.6.1 - 2023-09-23

  • Fixed "The two lines are parallel!"

Python Binding

Thanks to the contribution of @etjones, we now have an official Python binding! https://github.com/visioncortex/vtracer/pull/55

https://pypi.org/project/vtracer/0.6.10/

0.5.0 - 2022-10-09

0.4.0 - 2021-07-23

  • SVG path string numeric precision

0.3.0 - 2021-01-24

  • Added cutout mode

0.2.0 - 2020-11-15

  • Use relative & closed paths

0.1.1 - 2020-11-01

  • SVG namespace

0.1.0 - 2020-10-31

  • Initial release