Nodes/ComfyUI-Flux-FaceIR/Flux FaceIR Detect And Align Face
ComfyUI Node

Flux FaceIR Detect And Align Face

Finding, straightening, and exporting the face so the restoration has something to work on

By cosmicrealm·Created 5 months ago·Updated 3 days ago· 63
Flux FaceIR Detect And Align Face
  • retinaface_model
  • image
  • aligned_face
  • align_params
  • align_params_json
face_selectionlargest
face_size512
crop_scale1.35
crop_shift_y0.00
conf_threshold0.60
pre_nms_topk5000
nms_threshold0.40
post_nms_topk750
resize_short_edge640
border_modeconstant

In the whole-image FaceIR workflow, this is the "detect" half of detect-restore-paste. Flux FaceIR Detect And Align Face finds faces in a full photo, picks one, and warps it into a clean, square, front-facing crop that Flux FaceIR Restore Face can actually fix. Then - this is the clever part - it hands you the parameters to put the fixed face back exactly where it came from.

The name is a lie in the fun way: nothing is being restored here, only located and straightened. But a restoration model is only as good as its crop, and this node is why the crop doesn't wreck the result.

How it works

Under the hood it's the classic detect-crop-paste loop from the detailing playbook, minus the inpainting. RetinaFace returns bounding boxes plus five facial landmarks (eyes, nose, mouth corners). The node estimates an affine transform that maps those landmarks onto a canonical template, then warps the photo so the face is centered and upright at a fixed square size - typically 512px. The template geometry, the transform, and the inverse transform are all bundled into align_params, which the paste-back node later inverts to drop the restored face onto the original pixels.

A detail worth knowing: if nothing's found at your confidence threshold, it doesn't just fail - it retries with progressively lower thresholds and larger resize scales before giving up. For a noisy old photo that barely registers as a face, that fallback chain is often the difference between "restored" and an error.

The inputs that matter

You'll touch maybe four of these:

  • face_selection - largest, center, or highest_score. largest is right for a single-subject portrait; center is the pick for group shots where you want the middle face.
  • face_size - the output crop resolution, default 512. Match it to the resolution on Restore Face and you avoid a resize round-trip.
  • crop_scale - default 1.35. This one's a subtle lever: it widens the crop beyond the pure landmark box to pull in forehead, chin, and shoulders. More context means a more natural restored face; too much and you're restoring background too.
  • conf_threshold - default 0.6. Drop it toward 0.3–0.4 if the fallback chain still misses and the image genuinely has a face in it.

The NMS and resize_short_edge knobs are detector plumbing. Leave them. crop_shift_y nudges the crop vertically - a positive value pushes the face lower in the frame, so you see more forehead and hair above it (and less chin); negative does the reverse. border_mode decides how out-of-frame edges fill - constant is a fine default.

The outputs, and where they go

  • aligned_face (IMAGE) - the straightened square crop → into Flux FaceIR Restore Face.
  • align_params (FACEIR_ALIGN_PARAMS) - the opaque geometry bundle → into Flux FaceIR Paste Restored Face. Keep this paired with the exact image that produced it.
  • align_params_json (STRING) - the same data as readable JSON, for debugging or export. You won't wire it into anything.

Installing and getting it running

The pack ships via ComfyUI Manager (search Flux FaceIR) or git clone https://github.com/cosmicrealm/ComfyUI-Flux-FaceIR into custom_nodes, then python install.py and a full restart. Before this node will run you need the detector weights:

mkdir -p ComfyUI/models/face_detectors
wget -O ComfyUI/models/face_detectors/retinaface_r34.pth \
  https://github.com/yakhyo/retinaface-pytorch/releases/download/v0.0.1/retinaface_r34.pth

The bundled full_image_restore.json workflow wires everything up (it runs a couple of detect nodes at different crop_scale values, so don't be surprised to see it twice in the graph).

Where people get burned

  • "No face detected" ValueError - it tried every fallback and found nothing. Either the face is too small/obscured for the defaults (lower conf_threshold), or you fed it a batch item that genuinely has no face in it. The node processes each image in the batch and will tell you exactly which one and what it tried.
  • Face comes back looking like a different person - that's usually not this node's fault; it's the restoration being blind (see the reference-guided option on Restore Face). What this node can cause is an awkward crop that the restorer then invents details for. Widen crop_scale and re-run before blaming the model.

One honest caveat: this is a per-face, per-image job. A batch of twenty photos is twenty detect-and-align passes, and each one downstream eats a full 50-step diffusion run. Batch accordingly.

CategoryFlux FaceIR

Inputs (12)

NameTypeDefaultDescription
retinaface_modelRETINAFACE_MODEL
imageIMAGE
face_selectionCOMBOlargest3 options: largest, center, highest_score
face_sizeINT512256–1024
crop_scaleFLOAT1.351–2.5
crop_shift_yFLOAT0.00-0.25–0.25
conf_thresholdFLOAT0.600.05–0.99
pre_nms_topkINT50001–20000
nms_thresholdFLOAT0.400.05–0.95
post_nms_topkINT7501–5000
resize_short_edgeINT6400–4096
border_modeCOMBOconstant3 options: constant, reflect101, reflect

Outputs (3)

NameTypeDescription
aligned_faceIMAGE
align_paramsFACEIR_ALIGN_PARAMS
align_params_jsonSTRING