Face Area Batch Splitter
Send small faces to the detail branch, big faces straight through
- images
- bbox_detector
- images_to_detail
- images_passthrough
- detail_indices
- total_count
- face_masks
In a character dataset, small faces are the problem children. A close-up gets enough pixels for a sharp, identity-rich face; a wide shot's tiny face is mush that will teach your LoRA wrong details. Face Area Batch Splitter looks at every image in a batch, finds the faces, and routes each one down one of two branches: images where the largest face is small go to a "detail" branch (upscale, face-fix, whatever you do to rescue them), and images with a big enough face pass through untouched. Cleanly, in one node, with masks to match.
It's part of the Consistent Character Creator (CCC) toolset in Mickmumpitz-Nodes, built to feed the character-LoRA dataset pipeline the pack is known for.
How it works
For each image, it runs face detection, sorts the boxes by area (largest first), and computes the fraction of the image the largest face fills. If that ratio is below area_threshold (default 0.5), the image routes to images_to_detail - because a face covering less than half the frame is presumably small enough to need rescuing. Otherwise it goes to images_passthrough. If no face is found, no_face_action decides: passthrough (default) or detail.
Outputs are:
images_to_detailandimages_passthrough(IMAGE) - the two routed batches.detail_indices(STRING) - comma-separated original indices of the detail images, so you can map them back.total_count(INT) - the total input count.face_masks(MASK) - one mask per detail image, built from the (up tomax_faces) largest face boxes, aligned withimages_to_detail.
That mask output is the sleeper feature: it means you can send the detail branch straight into an inpainting or face-fix node and only touch the face region, keeping the rest of the image pixel-identical.
Detector: connect one or let it load its own
This is where the README gets specific, and it matters. Two ways to provide face detection:
- Recommended: wire a
bbox_detectorinput with anUltralyticsDetectorProvidernode from the ComfyUI Impact Subpack. With it connected, this node doesn't load any model itself - no extra Python package needed. - Fallback: leave
bbox_detectorempty and it loads the model named inmodel_path(defaultface_yolov8m.pt) itself - which requirespip install ultralyticsplus that model file inComfyUI/models/ultralytics/bbox/.
The README is explicit that neither is required for the pack to load; you only hit the dependency if you take the fallback path.
Inputs that matter
area_threshold(FLOAT, 0–1) - the routing cutoff; lower means only truly tiny faces get the detail treatment.confidence(FLOAT, default 0.5) - detector confidence threshold.max_faces(INT, default 0) - keep only the N largest faces per image for the mask; 0 = all faces.
Installing
ComfyUI Manager → "Mickmumpitz" → install → restart, or:
cd ComfyUI/custom_nodes
git clone https://github.com/mickmumpitz/ComfyUI-Mickmumpitz-Nodes
Base deps are numpy, Pillow, opencv-python. Only add ultralytics if you're letting the node load its own model. If you're new to Impact, installing the Impact Subpack for UltralyticsDetectorProvider is the smoother route - and it keeps this node dependency-free.
Gotchas
The community has hit a real one here: on newer PyTorch (2.6+), loading an ultralytics model directly can fail with a weights_only error - "Unsupported global: GLOBAL ultralytics.nn.tasks.DetectionModel". Users hit it on exactly this kind of node. The clean fix is wiring an Impact detector instead (which manages its own loading), or updating ultralytics. Worth knowing before you spend an evening on the fallback path.
Inputs (7)
| Name | Type | Default | Description |
|---|---|---|---|
| images | IMAGE | — | |
| area_threshold | FLOAT | 0.500–1 | Route to detail branch when the largest face fills LESS than this fraction of the image area (0.5 = 50%). |
| confidence | FLOAT | 0.500–1 | — |
| no_face_action | COMBO | passthrough | 2 options: passthrough, detail |
| bbox_detectoropt | BBOX_DETECTOR | Connect an UltralyticsDetectorProvider node here (recommended). That node requires the ComfyUI Impact Subpack to be installed. With it connected, this node does not load the model itself. If left empty, it falls back to the 'model_path' below (needs ultralytics). | |
| model_pathopt | STRING | face_yolov8m.pt | — |
| max_facesopt | INT | 00–100 | Keep only the N largest faces per image (largest first) for the mask. 0 = all faces. |
Outputs (5)
| Name | Type | Description |
|---|---|---|
| images_to_detail | IMAGE | — |
| images_passthrough | IMAGE | — |
| detail_indices | STRING | — |
| total_count | INT | — |
| face_masks | MASK | — |