Mask Line Cleanup
Fixing the doubled-up mess before you vectorize
- mask
- cleaned_mask
- preview
If you've ever vectorized a line-art mask and gotten two parallel lines for every stroke instead of one, this is the node you were missing. Mask Line Cleanup sits between Line Region Detector and Centerline to SVG, and it exists because extracted line masks are almost never clean: thick strokes produce doubled edges, nearby lines cross into each other, and specks show up as tiny blobs. Centerline to SVG will happily trace all of that - and you'll regret it.
What it does, by mode
The cleanup_mode input picks your poison:
merge_close_lines- the one you'll use most. It dilates the mask so parallel lines withinmerge_distancepixels fuse into one, then re-thins with skeletonization. This is the fix for the double-edge problem: two edges of a thick stroke become one centerline.remove_duplicates- compares contours against each other (scipycdistover sampled points) and drops lines that are effectively the same shape at the same spot.thin_only- just skeletonizes everything down to single-pixel lines, no merging.distance_based- removes lines that sit within a distance threshold of each other, with the threshold scaled bystrength(default 1.0, range 0.1–3).
Two knobs apply regardless of mode: merge_distance (1–20px, default 3) is the threshold that decides "these are the same line" for the merging/duplicate modes, and min_component_size (default 10, 0 = off) deletes any connected blob smaller than that - your spec-killer.
Outputs: cleaned_mask (MASK, feed it to Centerline to SVG) and preview (IMAGE, look before you leap).
Where it fits in the graph
The flow the README pushes is: Line Region Detector → (Mask Line Cleanup) → Centerline to SVG → SVG Path Cleanup → File Saver. Mask cleanup is the pixel-side version of SVG Path Cleanup - same philosophy, one works on the mask before tracing, the other on the paths after. You don't always need both, but doubled-up lines are so common in real extractions that it's the first thing I'd try when centerline output looks dense or "hairy." It's cheap to run and it saves you from fighting the SVG output later.
Install
Same pack, same story - no models, no API, pure local image processing:
cd ComfyUI/custom_nodes
git clone https://github.com/TJ16th/TJ_ComfyUI_Lineart2Vector.git
# restart ComfyUI
or ComfyUI Manager → search TJ_ComfyUI_Lineart2Vector. Dependencies come from requirements.txt; the ones beyond stock ComfyUI are opencv-contrib-python and scikit-image (this node literally imports skeletonize and remove_small_objects from skimage). If you cloned by hand, run pip install -r requirements.txt - most of it's already there.
Where people get burned
The classic mistake is setting merge_distance too high and watching genuinely separate lines weld together into a grid. Start at 3, bump it one pixel at a time, and check preview after every change. Same with min_component_size: it's per connected component, so on fine art, a value that kills noise can also delete thin legitimate strokes like eyelashes or hair strands. And remember that strength only applies to remove_duplicates and distance_based modes - bumping it does nothing in merge_close_lines. If your output still looks doubled, your source mask may be the problem - go back to Line Region Detector's line_detection_method before you fight it here.
Inputs (5)
| Name | Type | Default | Description |
|---|---|---|---|
| mask | MASK | — | |
| cleanup_mode | COMBO | 4 options: merge_close_lines, remove_duplicates, thin_only, distance_based | |
| merge_distance | INT | 31–20 | Distance threshold for merging parallel lines |
| min_component_size | INT | 100–1000 | Remove components smaller than this (0=disabled) |
| strengthopt | FLOAT | 1.00.1–3 | Cleanup strength |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| cleaned_mask | MASK | — |
| preview | IMAGE | — |