Restore Face Advanced π ReActor
Run GFPGAN or CodeFormer on the one face you actually want fixed
- image
- IMAGE
The main ReActor face-swap node has restoration built in - pick a model, it cleans up the swapped face automatically. This node is for everything that node doesn't cover: running restoration on its own, on any image, with actual control over which face in a crowd gets touched. It came out of a real complaint - early versions of the built-in restoration hit every face in the frame, swapped or not, and people wanted it scoped down to just the one they cared about. That's exactly what face_selection is for here.
One thing worth clearing up since the pack's other nodes carry an NSFW detector: this one doesn't gate anything. That detector lives on the swap step. Restoration is just image cleanup - it runs on whatever you hand it.
How it works
It runs a face detector over the input image, restores whichever detected face(s) you've told it to touch using the model you picked, and blends the result back in by the visibility amount you set. Two of the models on offer - GFPGAN and CodeFormer - aren't ReActor's own work; GFPGAN traces back to TencentARC, a different Tencent research group from the one behind IP-Adapter, in case you're keeping track of which Tencent lab built what in this space.
The inputs and outputs that matter
image(required, IMAGE) - what you're restoring.facedetection(required, enum, default varies) - which detector finds the faces:retinaface_resnet50,retinaface_mobile0.25,YOLOv5l, orYOLOv5n.model(required, enum) -none,codeformer-v0.1.0.pth,GFPGANv1.3.pth,GFPGANv1.4.pth, orGPEN-BFR-512.onnx.noneis a real, useful option - it lets you test detection and selection without actually restoring anything.visibility(default 1, 0β1) - how much of the restored face shows through versus the original. At 1 you get the full restoration; lower it if the restored face's texture looks noticeably different from the rest of an un-restored image.codeformer_weight(default 0.5, 0β1) - only matters whenmodelis CodeFormer. This is CodeFormer's own fidelity dial: lower values lean toward heavier restoration and more generated detail, higher values stay closer to what was actually in the input. It's easy to assume higher means "more restored" - it's the opposite.face_selection(defaultall) -allrestores every detected face,largestrestores only the biggest one,filteropens up the four optional inputs below for picking specific faces out of a crowd.
Optional, and only doing anything when face_selection is filter: sort_by (area, x_position, y_position, detection_confidence; default area), reverse_order (default false), take_start and take_count - together these let you say something like "sort left to right, skip the first one, restore the next two." Output is a single IMAGE.
How to install it
ComfyUI Manager: search "ReActor", install, restart. Manually, git clone https://github.com/Gourieff/ComfyUI-ReActor into custom_nodes, then run install.bat (Windows) or python install.py (Linux/macOS). This node's models are the separate ones - download whichever restoration .pth/.onnx files you want from the pack's Hugging Face dataset and drop them into ComfyUI/models/facerestore_models. They aren't fetched automatically the way the base swap models are, so model will show as empty until you do this.
Common issues & troubleshooting
The model dropdown is empty or missing your choice. These weights don't auto-download. Grab them from the facerestore_models folder on the pack's Hugging Face dataset and put them in ComfyUI/models/facerestore_models, then restart or refresh the node.
Restoration looks like it did nothing, or did too much. That's codeformer_weight fighting your expectations - remember it runs backwards from intuition, low = more restoration, high = more fidelity to the input. Adjust visibility first if you just want a softer blend rather than reworking the weight.
Only some faces got restored and you expected all of them, or vice versa. Check face_selection before anything else - largest and filter are easy to leave set from a previous workflow. If you're using filter, remember take_start/take_count are counted from wherever sort_by puts the faces, so a face that looks "first" to you visually might be third once sorted by detection confidence.
Same restoration model behaves differently than it does inside the main swap node. That's expected - this is the standalone path, and facedetection here is a separate choice from whatever the main node uses internally. If results diverge, try matching the detector too, not just the restoration model.
Inputs (10)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | β | |
| facedetection | COMBO | 4 options: retinaface_resnet50, retinaface_mobile0.25, YOLOv5l, YOLOv5n | |
| model | COMBO | 5 options: none, codeformer-v0.1.0.pth, GFPGANv1.3.pth, GFPGANv1.4.pth, GPEN-BFR-512.onnx | |
| visibility | FLOAT | 1.000β1 | β |
| codeformer_weight | FLOAT | 0.500β1 | β |
| face_selection | COMBO | all | 3 options: all, filter, largest |
| sort_byopt | COMBO | area | 4 options: area, x_position, y_position, detection_confidence |
| reverse_orderopt | BOOLEAN | false | β |
| take_startopt | INT | 00β100 | β |
| take_countopt | INT | 11β100 | β |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| IMAGE | IMAGE | β |