Nodes/comfyui-minimax-h3-audio-T8/MiniMax H3 Skin Finish Multi-Person Profile Semantic Mask / 多人侧脸语义皮肤遮罩 (Advanced EXP)
ComfyUI Node

MiniMax H3 Skin Finish Multi-Person Profile Semantic Mask / 多人侧脸语义皮肤遮罩 (Advanced EXP)

The node that doesn't frontalize faces

By T8mars·Created about a month ago·Updated a day ago· 1,031
MiniMax H3 Skin Finish Multi-Person Profile Semantic Mask / 多人侧脸语义皮肤遮罩 (Advanced EXP)
  • frames
  • track_plan
  • identity_assignment
  • semantic_skin_mask
  • mask_preview
  • report_json
parser_modelfacexlib_parsenet_v0.2.2_pinned
detection_threshold0.45
minimum_face_height_px32
minimum_detail0.010
minimum_person_overlap0.20
minimum_track_quality0.10
minimum_class_probability0.55
feature_protection_px3
include_neckfalse
minimum_skin_area_per_face0.0001
maximum_skin_area_per_frame0.35
maximum_alignment_rms0.080
profile_crop_expansion1.45
minimum_ready_frame_fraction0.50
preview_count6

Faces in profile are the worst case for semantic skin masking. Most face parsers are trained on near-frontal faces, and the standard trick - warp everything to a frontal template - either breaks on a 90-degree pose or quietly hallucinates structure that isn't there. The Multi-Person Profile Semantic Mask node is T8's careful answer: it tries the strict YuNet five-point FFHQ alignment first, and only when that alignment is rejected does it fall back to parsing an expanded square crop in the original profile pose, then projects the mask back and intersects it with the exact SAM3.1 person track. It never frontalizes a face, and it never loosens the five-point residual gate to make the frontal route work.

How it works

The pipeline, from the source: for each frame and shot-local person mask, the node picks one unique pinned YuNet detection, sorts the viewpoint-dependent eye/mouth pairs by x-coordinate, and estimates an OpenCV LMEDS similarity transform from the five landmarks to the standard FFHQ 512 template. The aligned crop gets parsed by the pinned CPU ParseNet, and the skin/protected-feature masks are inverse-warped and intersected with that exact person track. A single YuNet detection can't be shared between tracks, and missing landmarks are never copied from another frame.

Key inputs:

  • frames, track_plan (from the SAM3.1 multi-face tracking nodes), and parser_model (pinned facexlib_parsenet_v0.2.2_pinned - the only accepted checkpoint, models/facedetection/parsing_parsenet.pth, exactly 85,331,193 bytes).
  • maximum_alignment_rms (0.08) - the strict five-landmark residual. This node doesn't raise it; a rejected pose takes the profile-crop fallback instead.
  • profile_crop_expansion (1.45) - the square-crop fallback's expansion factor; the author's bounded six-frame profile probe passed at 1.45.
  • include_neck (false) - neck stays excluded by default, clothing always protected.
  • minimum_ready_frame_fraction (0.5) - if fewer than half the frames contain at least one reliable tracked face, the whole batch returns an empty mask rather than processing intermittently. That's the fail-closed contract: empty mask + ABSTAIN beats a half-usable mask.

Outputs: semantic_skin_mask (MASK), mask_preview (IMAGE), report_json (STRING). Optional identity_assignment adds Character labels to the report - manual/SFace suggestions, not identity proof, and they never alter the mask.

Why you'd reach for it

Any scene where people are shot from the side - conversations, two-shots, walking shots - and you want skin-only treatment that doesn't drag the nose, hair, or clothing into the mask. The "don't frontalize, don't loosen the gate" stance is exactly right for preserving profile geometry.

Installing it and gotchas

Standard pack install (ComfyUI Manager "MiniMax H3 Audio T8", or clone https://github.com/T8mars/comfyui-minimax-h3-audio-T8.git into custom_nodes, update ComfyUI core, restart), plus two upstream pieces: SAM3.1 for the track plan and the pinned ParseNet checkpoint in models/facedetection/. Missing or mismatched weights, malformed plans, excessive alignment residual, or low ready-frame coverage all return an empty mask with ABSTAIN/REJECT - never a full-screen fallback.

Where people get burned: treating a rejected alignment as a bug and raising maximum_alignment_rms to force the frontal route through - that's the exact looseness this node refuses. And the checkpoint is pinned: the ParseNet/CelebAMask-HQ class order differs from FaceXLib's BiSeNet list, so don't substitute a differently-ordered model file. When in doubt, read report_json; it tells you which route each frame took.

CategoryT8/MiniMax H3/Post FX/Experimental

Inputs (18)

NameTypeDefaultDescription
framesIMAGE
track_planH3_T8_SAM31_MULTIFACE_TRACK_PLAN
parser_modelCOMBOfacexlib_parsenet_v0.2.2_pinned1 options: facexlib_parsenet_v0.2.2_pinned
detection_thresholdFLOAT0.450.05–0.99
minimum_face_height_pxFLOAT328–1024
minimum_detailFLOAT0.0100–0.2
minimum_person_overlapFLOAT0.200–1
minimum_track_qualityFLOAT0.100–1
minimum_class_probabilityFLOAT0.550–1
feature_protection_pxINT30–32
include_neckBOOLEANfalseNeck remains excluded by default; clothing is always protected.
minimum_skin_area_per_faceFLOAT0.00010–0.1
maximum_skin_area_per_frameFLOAT0.350.01–1
maximum_alignment_rmsFLOAT0.0800.005–0.25Strict five-landmark residual. This node does not raise it; a rejected pose may use the profile-crop fallback instead.
profile_crop_expansionFLOAT1.451–3Square face crop used only after strict five-point alignment rejects the pose. 1.45 passed the bounded six-frame profile probe.
minimum_ready_frame_fractionFLOAT0.500–1If fewer frames contain at least one reliable tracked face, the whole batch returns an empty mask instead of intermittent processing.
preview_countINT61–8
identity_assignmentoptH3_T8_MULTIFACE_IDENTITY_ASSIGNMENT

Outputs (3)

NameTypeDescription
semantic_skin_maskMASK
mask_previewIMAGE
report_jsonSTRING