Nodes/HandFixer/MediapipeHandNode
ComfyUI Node

MediapipeHandNode

MediapipeHandNode

By Xiangyu-CAS·Created 2 years ago·Updated 2 years ago· 215
MediapipeHandNode
  • image
  • image
  • mask
  • preview

Bad hands are the most reliable failure mode in AI portraits - the fused fingers, the six-fingered wave, the hands that look like they were sketched from a memory of a memory. And the fix people actually settle on is boring in the best way: mask the mangled region and let an inpainting model rebuild it. MediapipeHandNode is the masking half of that fix. It ships in the Xiangyu-CAS/HandFixer pack, and despite the pack's name it does exactly one job: look at your image, find every hand in it, and hand you a mask that says "regenerate here." FLUX does the actual rebuilding; this node is the spotter.

That division of labor tells you when to reach for it. HandFixer targets the classic case: you generated a portrait in SDXL, a DiT model, or Midjourney and the hands came out mangled. Instead of re-rolling the whole image - and probably breaking a face you liked - you run a FLUX.1-Fill inpainting pass over just the hand regions. Flux handles hands far better than SDXL by default, so the model that's good at hands fixes the one that isn't.

How it works

Under the hood it's Google's MediaPipe Hand Landmarker - the same Apache 2.0 library Kijai swapped into LivePortrait when he wanted to dodge InsightFace's non-commercial model license. The node runs it in static_image_mode with max_num_hands=10 and a detection confidence of 0.5, grabs the 21 landmarks per detected hand, and draws a bounding box around each one. Then it loosens the box by about 15% plus a 30px pad and fills it white on a black mask.

Two things to notice here. First, no model file to download - MediaPipe bundles its hand model inside the pip package, which is a genuinely nice property compared to the YOLO checkpoints ADetailer expects. Second, the mask is a box, not a hand silhouette. That's a design choice, not a bug: you want the inpainting model to have some breathing room so it can redraw the whole hand rather than inherit its edges. Just don't expect a clean outline.

Inputs and outputs

The input side is minimal - a single image (IMAGE). That's it. The source has a confidence threshold input commented out, so the 0.5 you get is the 0.5 you get.

  • image - the original, passed through untouched. Wire it into InpaintModelConditioning.
  • mask - the hand boxes. This is the one that matters; feed it into the mask input of InpaintModelConditioning.
  • preview - the image with the masked regions blacked out. Wire it to a PreviewImage node and you'll see exactly what's about to be regenerated before you commit. Great sanity check.

The shipped workflow wires it the standard FLUX-Fill way: LoadImage → MediapipeHandNode → InpaintModelConditioning → DifferentialDiffusion → KSampler with fluxl-fill-dev as the UNet. DifferentialDiffusion makes the sampler touch only masked areas, so everything outside the boxes stays bit-identical - the one guarantee masked inpainting still owns over whole-frame edit models.

Install

ComfyUI Manager: search "HandFixer" and install. Or the manual route:

cd ComfyUI/custom_nodes
git clone https://github.com/Xiangyu-CAS/HandFixer
pip install -r requirements.txt

Then restart ComfyUI. The requirements list is inflated - mediapipe and opencv-python are what this node actually needs; diffusers, transformers, gradio, and streamlit exist for the pack's separate gradio/streamlit scripts. Torch, numpy, and PIL you already have.

The node itself needs nothing else, but the workflow does - this is where people stall. You need the FLUX-Fill stack: ae.safetensors into models/vae, clip_l.safetensors and t5xxl_fp16.safetensors into models/clip, and fluxl-fill-dev.safetensors into models/unet. Grab the fill model from the FLUX.1-Fill-dev release on Hugging Face. Then drag workflow/HandFixer-fill.json from the pack into ComfyUI.

Common issues

  • Boxy mask edges, or seams at the boundary. The README owns this one: FLUX-dev isn't a dedicated inpainting model, so the older pipeline can throw boundary artifacts. FLUX-Fill is the inpainting-tuned variant and blends far better - use the -fill workflow, and if seams still show, feather the mask before conditioning.
  • A hand got missed entirely. MediaPipe is fast and licence-clean but loses on extreme angles, and the fixed 0.5 threshold means small hands in low-res images can fail to trigger. If you must catch those, you'll need a different detector or a manual mask for the stragglers.
  • Feeding a batch and only one hand getting masked. The node processes image.numpy()[0] - the first frame only. It's built for single images; don't feed it a video batch.

It's a small, honest, single-purpose node. If you're already on a Qwen-Image-Edit or Klein workflow you may not need it at all. But if you've got a folder of SDXL portraits with six-fingered hands and a FLUX-Fill install, this is the fastest route from "ugh" to "done."

Categorymediapipe_hand

Inputs (1)

NameTypeDefaultDescription
imageIMAGE

Outputs (3)

NameTypeDescription
imageIMAGE
maskMASK
previewIMAGE