Nodes/comfyui-fvmtools/Person Data Refiner
ComfyUI Node

Person Data Refiner

Upscale, then re-detail without losing who's who — the hi-res pass fixer

By ping1979ping·Created 5 months ago·Updated about a month ago· 0
Person Data Refiner
  • person_data
  • images
  • sam_model
  • sam3_model
  • depth_map
  • person_data
  • aux_masks
  • report
mask_fill_holestrue
mask_blur0
det_size640
depth_edge_threshold0.05
depth_carve_strength0.80
depth_grow_pixels30
aux_model
aux_confidence0.35
aux_label
aux_fill_holesfalse
aux_expand_pixels0
aux_blend_pixels0
aux_yolo_sam_refinetrue
aux_yolo_sam_bbox_expansion0

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) or sam3_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_label pair runs a YOLO segm model to pull hands, feet, or any class you name into aux_masks, and aux_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.

CategoryFVM Tools/Face

Inputs (19)

NameTypeDefaultDescription
person_dataPERSON_DATAOriginal PERSON_DATA from Person Selector Multi / SAM3
imagesIMAGENew images (batch size must match original person_data)
mask_fill_holesBOOLEANtrue
mask_blurINT00–100
det_sizeCOMBO640Face detection resolution
sam_modeloptSAM_MODELSAM2 model for body mask generation (fallback when sam3_model not connected)
sam3_modeloptSAM3_MODEL_CONFIGSAM3 model from LoadSAM3Model. Takes priority over sam_model when both connected.
depth_mapoptIMAGEDepth map batch for depth-guided mask refinement
depth_edge_thresholdoptFLOAT0.050.01–0.3Depth gradient threshold for edge detection
depth_carve_strengthoptFLOAT0.800–1How strongly depth edges cut masks
depth_grow_pixelsoptINT300–200Gap filling between depth edges
aux_modeloptCOMBOYOLO 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_confidenceoptFLOAT0.350.05–1Detection confidence threshold. YOLO path: per-detection score gate. SAM3-text-aux path: passed as the SAM3 grounding threshold (lower = more permissive).
aux_labeloptSTRINGYOLO 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_holesoptBOOLEANfalseFill holes inside YOLO aux masks
aux_expand_pixelsoptINT00–100Dilate YOLO aux masks by N pixels
aux_blend_pixelsoptINT00–100Gaussian blur radius for YOLO aux mask edges
aux_yolo_sam_refineoptBOOLEANtrueOn (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_expansionoptINT00–64Pixels to expand bbox before SAM refinement (helps thin objects).

Outputs (3)

NameTypeDescription
person_dataPERSON_DATA
aux_masksMASK
reportSTRING