Person Data Refiner
Upscale, then re-detail without losing who's who — the hi-res pass fixer
- person_data
- images
- sam_model
- sam3_model
- depth_map
- person_data
- aux_masks
- report
Here's the workflow shape this node exists for: you detail faces at low resolution because it's fast and you're iterating. You upscale. And now all those lovely masks from Person Selector Multi are wrong - they're for a 1024-wide image and you're looking at a 2048-wide one. Person Data Refiner is the bridge: it takes the original person_data plus your new hi-res images, re-detects the faces at the new resolution, re-matches them to the original references by spatial proximity (centroid distance, so person two stays person two), and regenerates every mask fresh. Then you feed the result into a second Person Detailer pass at full res.
It's the second half of the two-pass hi-res detailing pattern the pack's README calls "Pipeline 1b," and it exists because a face that was 80×80 in the low-res frame deserves a real mask at high res - a blurry upscaled mask inpaints like a blurry mask.
What it does beyond re-detection
- Depth-guided mask reconstruction - connect a
depth_map(e.g. from Depth Anything V2) and masks get rebuilt using depth coherence: gaps where the depth matches the person get filled, overlapping foreground objects with mismatched depth get removed. The three depth params (depth_edge_threshold,depth_carve_strength,depth_grow_pixels) control how aggressively depth edges carve into the masks. - SAM2 or SAM3 - pass a
sam_model(SAM2 from Impact Pack's SAMLoader) orsam3_model(from LoadSAM3Model, which takes priority when both are connected). Body masks come from whichever you give it. - Aux body-part masks - the
aux_model/aux_labelpair runs a YOLO segm model to pull hands, feet, or any class you name intoaux_masks, andaux_yolo_sam_refine(on by default) refines the bbox detections into proper pixel masks via SAM3 then SAM2. - Chainable - when the image resolution already matches the person_data, it skips face re-detection entirely and just runs the aux pass. That's how you build separate aux mask passes: chain two refiners with different models/labels (hands in one, feet in another).
Inputs and outputs worth knowing
Required: person_data (from Person Selector Multi), images (the new hi-res batch - batch size must match the original), plus mask_fill_holes, mask_blur, det_size. Outputs: fresh person_data, the new aux_masks, and a report string showing re-matching results and runtime - read the report once to confirm your assignments survived, that's the whole trust model of this node.
Installing
Same FVMtools clone as the rest:
cd ComfyUI/custom_nodes
git clone https://github.com/ping1979ping/comfyui-FVMtools
pip install insightface>=0.7.3 onnxruntime-gpu>=1.17.0 opencv-python>=4.8.0 numpy>=1.24.0
Model needs mirror the base pack: buffalo_l auto-downloads, parsing_bisenet.pth must be placed in ComfyUI/models/gfpgan/ manually, and SAM models only if you want body masks. The YOLO aux path needs a segm model plus (for the refine path) SAM.
The gotcha
The spatial-proximity rematch is positional, not facial. If your upscaler changes composition - crops, moves people, adds margins - centroid matching can swap identities, especially for two people standing close together. The report output exists precisely to catch this. Check it after your first hi-res pass; if assignments flipped, keep your upscaler's output dimensions and framing identical to the low-res input, or do the upscale with padding/letterboxing preserved. Also: if images is exactly the same resolution as the original person_data, nothing gets re-detected - that's by design (it's the chainable mode), and it means your second Person Detailer pass uses the old masks.
Inputs (19)
| Name | Type | Default | Description |
|---|---|---|---|
| person_data | PERSON_DATA | Original PERSON_DATA from Person Selector Multi / SAM3 | |
| images | IMAGE | New images (batch size must match original person_data) | |
| mask_fill_holes | BOOLEAN | true | — |
| mask_blur | INT | 00–100 | — |
| det_size | COMBO | 640 | Face detection resolution |
| sam_modelopt | SAM_MODEL | SAM2 model for body mask generation (fallback when sam3_model not connected) | |
| sam3_modelopt | SAM3_MODEL_CONFIG | SAM3 model from LoadSAM3Model. Takes priority over sam_model when both connected. | |
| depth_mapopt | IMAGE | Depth map batch for depth-guided mask refinement | |
| depth_edge_thresholdopt | FLOAT | 0.050.01–0.3 | Depth gradient threshold for edge detection |
| depth_carve_strengthopt | FLOAT | 0.800–1 | How strongly depth edges cut masks |
| depth_grow_pixelsopt | INT | 300–200 | Gap filling between depth edges |
| aux_modelopt | COMBO | YOLO segm model for body-part detection (hands, feet, etc.). Runs on the current images and injects results into person_data["aux_masks"]. Chainable: each refiner replaces aux_masks, so chain multiple refiners with different models/labels for separate aux passes. Set to 'none' to skip YOLO. If aux_label is non-empty AND a SAM3 model is connected, the refiner falls back to SAM3 text-grounded segmentation using aux_label as the prompt. | |
| aux_confidenceopt | FLOAT | 0.350.05–1 | Detection confidence threshold. YOLO path: per-detection score gate. SAM3-text-aux path: passed as the SAM3 grounding threshold (lower = more permissive). |
| aux_labelopt | STRING | YOLO path: filter detections by class label (substring match; comma-separated for multiple, e.g. 'hand,foot'). Empty = all classes. SAM3-text-aux path (when aux_model='none'): this is the SAM3 grounding prompt itself, e.g. 'legs', 'arms'. Comma-separated values are run as separate prompts and unioned. | |
| aux_fill_holesopt | BOOLEAN | false | Fill holes inside YOLO aux masks |
| aux_expand_pixelsopt | INT | 00–100 | Dilate YOLO aux masks by N pixels |
| aux_blend_pixelsopt | INT | 00–100 | Gaussian blur radius for YOLO aux mask edges |
| aux_yolo_sam_refineopt | BOOLEAN | true | On (default): refine bbox-only YOLO detections into pixel masks using SAM3 (priority) → SAM2 (fallback). Off: use raw bbox rectangles as aux masks (today's bbox-only behavior). |
| aux_yolo_sam_bbox_expansionopt | INT | 00–64 | Pixels to expand bbox before SAM refinement (helps thin objects). |
Outputs (3)
| Name | Type | Description |
|---|---|---|
| person_data | PERSON_DATA | — |
| aux_masks | MASK | — |
| report | STRING | — |