DetectCropFace
Pull every face out of a photo as clean crops
- image
- image
DetectCropFace (the UI label in the pack is "Detect and Crop Faces") is the "gimme the faces" node: it finds every face in an image, optionally straightens each one, and returns them as cropped-out images. One photo in, a batch of individual face crops out. If AlignFace is the whole-frame version of face straightening, this is the extractor - think "crop to face" for building a face dataset, feeding a restoration node, or prepping faces for a swap.
How it works
Same RetinaFace resnet50 detector as the rest of the pack, but instead of rotating the whole image it uses the detector's multi-face alignment routine, which crops each detected face and rotates just that crop so the eyes are level. The two padding inputs control how much context survives around the face: horizontal_padding and vertical_padding, both defaulting to 1.0, are multipliers that expand the crop beyond the tight bounding box. Crank them up and you get head-and-shoulders instead of just a face.
The batch behavior is worth understanding before it surprises you:
- Zero faces - returns the original image unchanged (and prints a note).
- One face - returns that single crop.
- Multiple faces - returns a batch of crops, each resized to the largest face's dimensions so they stack cleanly into one tensor.
That resize-to-largest detail means group shots come out as a uniform batch, which is what you want if the next node expects consistent dimensions - and a minor quality hit for the smaller faces, since they get upscaled.
The inputs and outputs
- image - the input IMAGE.
- half - fp16 detector. Off by default; saves VRAM if you're cramped.
- horizontal_padding / vertical_padding - crop context, 0–5, default 1. The first knob you'll actually turn.
- do_align - whether to rotate each crop level. Default true; turn it off to get raw crops at whatever angle the head was.
- angle_offset - the small leveling nudge (default +1.0 degree).
One output, image - the face crop (single) or batch of crops (multiple). Output is a batch, so wire it straight into anything batch-aware, or use a Split Image-style node if you need them individually.
How to install
It's one of six nodes in billwuhao/ComfyUI_PortraitTools:
cd ComfyUI/custom_nodes
git clone https://github.com/billwuhao/ComfyUI_PortraitTools.git
cd ComfyUI_PortraitTools
pip install -r requirements.txt # or: ./python_embeded/python.exe -m pip install -r requirements.txt
Needs the face detector at ComfyUI/models/facedetection/detection_Resnet50_Final.pth (shared with ReActor if you have it). No RMBG models required - this node never touches background removal.
Where people get burned
- The pass-through is quiet. No face found means you get the original image back with only a console message - easy to mistake for a successful run that just "didn't crop."
- Padding is a multiplier, not pixels.
vertical_padding = 2is "double the bounding box height," so values creep up fast. Start at 1 and adjust by tenths. - Batch resizing. With a group shot, the small faces get upscaled to match the big one. Fine for datasets and restoration, noticeable if you're doing precision work on each face.
- Needs the detector model present, or it errors at load - that's the #1 "doesn't work" report for the whole pack.
Inputs (6)
| Name | Type | Default | Description |
|---|---|---|---|
| image | IMAGE | — | |
| half | BOOLEAN | false | — |
| horizontal_padding | FLOAT | 1.00–5 | — |
| vertical_padding | FLOAT | 1.00–5 | — |
| do_align | BOOLEAN | true | — |
| angle_offset | FLOAT | 1.0-10–10 | — |
Outputs (1)
| Name | Type | Description |
|---|---|---|
| image | IMAGE | — |