0.5 was too conservative for the sensitive_detect models in practice -
real footage frequently has the target region detected at 0.3-0.4, and
users had to manually drop the slider every run. Match the value the
extract_segments.py CLI already used as its default.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
When the node receives a multi-frame IMAGE batch and video_mode is on,
run detection across the whole sequence and fill in frames where the
mosaic target was missed, so a brief detection dropout in the middle of
a clip does not surface as an unmasked frame.
Detection-gap policy is controlled by buffer_frames (max 120):
- Gap <= buffer_frames between two detected frames: interpolate per
morph_method.
- "simple" linearly blends the two end masks and thresholds.
- "optical_flow" extracts contour polygons, forward-tracks from the
earlier detection and backward-tracks from the later one with
Lucas-Kanade pyramids, then blends by temporal distance.
- Gap > buffer_frames: track buffer_frames frames forward from the
preceding detection and buffer_frames frames backward from the next
one (optical flow). The unreachable middle stays unmasked.
- Leading and trailing undetected frames are filled by the same
optical-flow chain tracker, again capped at buffer_frames.
Implementation lives in extract_segments.py (morph_masks_simple,
track_mask_optical_flow, _chain_track, fill_video_gaps). node.py adds
video_mode/buffer_frames/morph_method INPUT_TYPES and an _process_video
branch that runs detection per frame, calls fill_video_gaps, then
renders each frame through the existing render_processed_layer helper
(re-used from the prior refactor). PSD output is preserved with one
layer per filled class per frame. README documents the new params and
the gap-filling policy.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Introduce a user-controlled mask dilation parameter so the mosaic area
can be padded beyond the segmentation footprint without changing the
mosaic block size. The expansion is expressed as a percent of the long
edge (0.0-20.0, step 0.1) and is applied on top of the existing
block-size-driven dilation.
Refactor extract_segments.py to pull out reusable helpers that the
following commit will share with the video pipeline:
- _dilate_mask: single elliptical-kernel dilation pass.
- detect_frame: run YOLO, return per-class combined mask + raw segments,
apply both the block-size dilation and the new user-controlled one.
- _make_rgba_from_mask / render_processed_layer / compose_frame: pull
the masked-image construction and per-mode rendering out of the main
loop.
extract_and_save_segments now delegates to those helpers and accepts a
mask_expand keyword that is threaded through from the ComfyUI node.
node.py extracts _ensure_model and _resolve_mosaic_mode out of
process_image so the upcoming video branch can share them. mask_expand
is exposed as a FLOAT INPUT_TYPE and a Gradio slider in app.py. README
documents the new parameter.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>