mirror of
https://github.com/visioncortex/vtracer.git
synced 2026-09-26 05:51:21 -07:00
Make filter_speckle a finish-phase filter, tunable without re-clustering
Speckle removal moves out of the frontends into Segmentation::filter_speckle, applied in the finish phase. The color frontend now clusters with good_min_area = 0 and the binary frontend emits every cluster, so the cached segmentation retains all regions and the speckle threshold can be retuned via finish() with no re-clustering. Pipeline gains a speckle_area field (Config sets it from filter_speckle^2). Frontend structs drop their filter_speckle_area field. Output on clean images is unchanged (golden/equivalence pass unblessed); noisy images are filtered downstream instead of during clustering. Adds a test tuning filter_speckle on one cached segmentation. Add finish-phase thin-strand filter (restores thread-like rejection) good_min_area = 0 disabled visioncortex's thread-like rejection (which was gated on good_min_area > 0). Reintroduce it in our repo as a finish-phase step: Segmentation::filter_thin drops regions whose perimeter >= area (average thickness under ~2px), using the same Shape::image_boundary_list metric so the heuristic matches. It's toggleable on a cached segmentation (Config::filter_thin, on by default), unlike the clustering-time version. Exposed via CLI --keep-thin, Python filter_thin, and Node filterThin. Adds RegionMask::perimeter/is_thin and a reuse test toggling it on one cached segmentation. Clean-image goldens are unaffected (large regions aren't thin). README: document binary thresholding, --keep-thin, and finish-phase filters Add the new CLI flags (--threshold, --adaptive, --adaptive-window, --adaptive-t, --keep-thin) to the options block and "New in 1.0"; note that --optimize is encoding-only (precision is --path-precision) and that speckle/ thin filtering run after clustering. Add adaptive-threshold examples for CLI, Python, and Node. Return speckle/thin filtering to clustering (fix gum-tree regression) good_min_area is visioncortex's clustering `deepen` gate, not a speckle post-filter: it decides whether a small or thread-like patch is absorbed into its nearest-color neighbour or kept as its own layer, and it enables the thread-like rejection (perimeter < area). An earlier change set it to 0 to make filter_speckle "retunable downstream", which disabled the thin check and reshaped the whole hierarchy — dissolving gradient-boundary structure that clustering is meant to absorb. The Gum Tree preset's central trunk vanished at gradient-step ~26 where the pre-1.0 path held it to 128. Clean-logo goldens couldn't exercise it, so it shipped green. Follow the proven webapp model instead: speckle lives inside clustering (good_min_area = filter_speckle^2 for the colour frontend; a post-cluster size gate for the binary frontend). The segment/finish split stays — it is the progressive model (cluster once, re-run colour/curve/optimize cheaply); clustering params (speckle, colour precision, layer difference, binary threshold) re-segment. Remove the downstream band-aids: Segmentation::filter_speckle/filter_thin, RegionMask::perimeter/is_thin, the pipeline speckle_area/filter_thin fields, Config::filter_thin, CLI --keep-thin, Python filter_thin, Node filterThin. Update the two reuse tests that encoded the wrong contract and the binary threshold test to use BinaryFrontend::min_area. All goldens, equivalence, progress, and reuse tests pass.
This commit is contained in:
+1
-1
@@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
||||
### Added
|
||||
|
||||
* Progress reporting and cancellation: `Pipeline::run_with_progress` with a `CancelToken` and a per-phase progress callback (for driving desktop UIs from a worker thread).
|
||||
* Two-phase conversion for interactive tuning: `Pipeline::segment` caches the expensive clustering result as a reusable `Segmentation`, and `Pipeline::finish` re-runs only the cheap color-fitting / curve-fitting / optimization stages — so tuning those parameters no longer repays the clustering cost. Both have `*_with_progress` variants.
|
||||
* Two-phase conversion for interactive tuning: `Pipeline::segment` caches the expensive clustering result as a reusable `Segmentation`, and `Pipeline::finish` re-runs only the cheap color-fitting / curve-fitting / optimization stages — so tuning those parameters no longer repays the clustering cost. (Speckle, color precision, and layer difference are clustering parameters and require a fresh `segment`.) Both have `*_with_progress` variants.
|
||||
* Binary thresholding methods: a tunable fixed threshold and Bradley–Roth adaptive thresholding (via visioncortex's summed-area table) for images with uneven lighting. Exposed on `Config` (`binary_threshold`, `binary_adaptive`, `binary_adaptive_window`, `binary_adaptive_t`), the CLI (`--threshold`, `--adaptive`, `--adaptive-window`, `--adaptive-t`), Python, and the Node package (`binaryThreshold`, `adaptive`, `adaptiveWindow`, `adaptiveT`).
|
||||
|
||||
## 1.0.0-alpha.1 - 2026-07-24
|
||||
|
||||
Reference in New Issue
Block a user