15 Commits
Author SHA1 Message Date
Gero Doll cd4ce37d53 Merge pull request #4 from Limbicnation/fix/instance-id-validation
fix(validation): instance_id type + combo field validation for legacy…
2026-04-22 04:08:08 +02:00
limbicnation 21e60efe3c refactor(v1): deduplicate face_output_format sanitization in execute()
Remove redundant fallback block — combo sanitization already handles
face_output_format validation earlier in the method.
2026-04-22 04:03:02 +02:00
limbicnation c322a27dfa fix(validation): instance_id type + combo field validation for legacy workflows
- Change instance_id from INT to STRING in INPUT_TYPES to prevent
  ComfyUI pre-execution validation failures (v2.1.2).
- Expand VALIDATE_INPUTS to handle required combo fields (aspect_ratio,
  output_mode, classifier_type) so legacy workflows with misaligned
  positional widgets_values don't crash (v2.1.3).
- Add defensive combo sanitization in v1 and v3 execute methods.
- Fix nested list syntax in combo definitions [[...]] -> [...].

Files: README.md, face_detection_node.py, pyproject.toml
2026-04-22 03:50:48 +02:00
limbicnation 5cffd4c3dd fix: instance_id accepts STRING input (v2.1.2)
Legacy workflows pass instance_id="default" (string) from old v1 nodes.
ComfyUI runs validate_inputs BEFORE execute(), so the in-node _coerce_int
fallback never fires — the workflow errors before reaching our handler.

Change schema input type from INT to STRING in both FaceDetectionNode (v3)
and FaceDetectionNodeV1 (fallback). instance_id is only used as a dict key
(f"{instance_id}"), never arithmetic, so the narrowing is safe.

- v3 schema: IntegerInput → StringInput
- v1 schema: ("INT", ...) → ("STRING", ...)
- Remove instance_id from _INT_DEFAULTS and VALIDATE_INPUTS INT loop
- Simplify coercion to str(instance_id) if not None else "0"
- Bump version 2.1.1 → 2.1.2
2026-04-20 19:08:36 +02:00
limbicnation 68c40eade0 chore: bump pyproject.toml version 2.1.0 -> 2.1.1 2026-04-20 08:25:00 +02:00
limbicnation 7478ee732c fix: temporal_smoothing input validation crash on legacy workflows (v2.1.1)
- Move temporal_smoothing, output_height, instance_id from required to
  optional in INPUT_TYPES to prevent ComfyUI framework-level int()
  coercion crash when legacy workflows pass string 'default' (from
  classifier_type) into INT slots via positional widgets_values mapping
- Add _coerce_int() helper for safe string-to-int conversion with
  fallback to defaults, applied defensively in v1 and v3 execute methods
- Enhance VALIDATE_INPUTS to intercept and validate all optional INT
  inputs with graceful type coercion
- Update README to reflect v2.x features (temporal smoothing, aspect
  ratios, auto-padding, batch processing, changelog)
- Bump version 2.1.0 → 2.1.1
2026-04-20 08:07:31 +02:00
limbicnation ac975a1120 Merge branch feature/face-detection-v2.1-backward-compat: FaceDetectionNode v2.1.0 2026-04-20 06:46:37 +02:00
limbicnation 1069f6324d fix: code review fixes - enumerate bug, dead params, output type, unused imports
- Fix .index() on numpy arrays in v3 individual face loop -> enumerate()
- Remove dead classifier_type param from detect_faces() (cascade already selected via CascadeCache)
- Change v1 RETURN_TYPES for face_metadata from IMAGE to FLOAT (is [B,6] bbox data, not image)
- Improve v3 face_metadata tooltip: NOT an image warning
- Remove unused import torch.nn.functional as F
- Remove unused import StringInput
- Replace _tensor_to_numpy() with _get_batch_dims() - removed dead img_np return
2026-04-20 06:45:32 +02:00
limbicnation 9e5f034807 feat: FaceDetectionNode v2.1.0 — backward compat, all_faces fix, validation
Fixes:
- Restore optional face_output_format param (strip/individual)
  Invalid values (e.g. 'lbp') gracefully fallback to 'strip' with warning
  Fixes 'Value not in list' validation error from stale v1.x workflows
- Restore optional padding param (legacy px-based, auto-converts to ratio)
- Fix all_faces mode: detect_faces() now returns ALL faces, not just largest
- Add VALIDATE_INPUTS to v1 wrapper for early invalid-value catching
- Set OUTPUT_NODE=True on both v3 schema and v1 class
- Fix _lock ClassVar type annotation syntax
- Add _resolve_face_output_format() for centralized format validation
- Proper strip/individual output handling in all_faces mode

Packaging:
- pyproject.toml: version 1.1.2 → 2.1.0, updated description and deps
- Removed Pillow and torchvision (no longer used)
- Bumped torch requirement to >=2.0.0
- Updated registry metadata (comfyui-manager-entry.json, node_list.json)
2026-04-20 06:20:38 +02:00
gero 70bdd94adb Updated version number 2025-07-22 06:44:01 +02:00
gero af9a97bdd9 Updated icon path 2025-07-22 06:42:06 +02:00
gero ef78345695 Updated version number 2025-07-22 06:33:28 +02:00
gero 89d1246ae2 Add icon 2025-07-22 06:31:55 +02:00
gero d59dcf7557 Updated 2025-07-22 06:17:39 +02:00
gero 4a631bd58e Added 2025-07-22 05:57:45 +02:00
8 changed files with 1084 additions and 540 deletions
+20
View File
@@ -0,0 +1,20 @@
name: Publish to Comfy registry
on:
workflow_dispatch:
push:
branches:
- main
paths:
- "pyproject.toml"
jobs:
publish-node:
name: Publish Custom Node to registry
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@v4
- name: Publish Custom Node
uses: Comfy-Org/publish-node-action@main
with:
personal_access_token: ${{ secrets.REGISTRY_ACCESS_TOKEN }} ## Add your own personal access token to your Github Repository secrets and reference it here.
+73 -32
View File
@@ -1,18 +1,22 @@
# ComfyUI Face Detection Node
A ComfyUI custom node for face detection and cropping using OpenCV Haar cascades, with full ComfyUI v3 schema support and backward compatibility.
A ComfyUI custom node for face detection and cropping using OpenCV Haar cascades — optimized for H100 cloud pipelines and LTX-Video avatar workflows. Full ComfyUI v3 schema support with backward compatibility for v1/v2.
![Face Detection Output Example](images/combined_strip.jpg)
![Face Detection Output Example](images/comfyui_face_detection_node.png)
## Features
- **Face Detection**: Uses OpenCV Haar cascade classifiers for robust face detection
- **Flexible Cropping**: Crop largest face or all detected faces
- **Adjustable Parameters**: Configurable detection threshold, minimum face size, and padding
- **Multiple Classifiers**: Choose between default and alternative Haar cascades
- **ComfyUI v3 Ready**: Full schema support with backward compatibility for v1/v2
- **Async Execution**: Stateless execution pattern for better performance
- **Auto-Padding**: Adaptive padding based on detected face size (no hardcoded values)
- **Temporal Smoothing**: Exponential moving average of bbox coordinates across video frames — eliminates jitter in batch/video processing
- **Aspect Ratio Presets**: `1:1`, `9:16`, `16:9`, `4:3`, `auto` — with forced crop recalculation
- **Full Batch Processing**: Iterates all batch items, outputs aligned batch tensors
- **GPU-First**: `torch.no_grad()` everywhere, minimal CPU transfers, stateless class-level caching
- **Face Output Format**: `strip` (horizontal layout) or `individual` (separate batch items) for multi-face output
- **Dual Classifiers**: Choose between default and alternative Haar cascades
- **Proper Error Signaling**: Returns flagged tensor + metadata when no face detected
- **ComfyUI v3 Ready**: Full schema support with async execution
- **Legacy Workflow Compat**: Handles old v1.x workflows with positional `widgets_values` misalignment gracefully
## Installation
@@ -22,9 +26,9 @@ A ComfyUI custom node for face detection and cropping using OpenCV Haar cascades
3. Click Install
### Manual Installation
1. Navigate to your ComfyUI custom nodes directory
2. Clone this repository:
1. Navigate to your ComfyUI custom nodes directory:
```bash
cd ComfyUI/custom_nodes
git clone https://github.com/Limbicnation/ComfyUI_FaceDetectionNode.git
cd ComfyUI_FaceDetectionNode
pip install -r requirements.txt
@@ -32,41 +36,78 @@ A ComfyUI custom node for face detection and cropping using OpenCV Haar cascades
## Usage
1. Add the "Face Detection and Crop" node to your workflow
2. Connect an image input
3. Adjust parameters:
- **Detection Threshold**: Confidence threshold (0.1-1.0)
- **Min Face Size**: Minimum face size in pixels (32-512)
- **Padding**: Padding around detected faces (0-256)
- **Output Mode**: "largest_face" or "all_faces"
- **Face Output Format**: "strip" (horizontal layout) or "individual" (separate batch items)
- **Classifier Type**: "default" or "alternative"
1. Add the **"Face Detection and Crop v2"** node to your workflow
2. Connect an image batch input
3. Adjust parameters as needed
## Parameters
### Parameters
| Parameter | Type | Range | Default | Description |
|-----------|------|-------|---------|-------------|
| detection_threshold | Float | 0.1-1.0 | 0.8 | Face detection confidence threshold |
| min_face_size | Int | 32-512 | 64 | Minimum size for detected faces |
| padding | Int | 0-256 | 32 | Padding around detected faces |
| output_mode | Combo | - | largest_face | Output mode for detected faces |
| face_output_format | Combo | - | strip | Format for multiple faces (strip/individual) |
| classifier_type | Combo | - | default | Haar cascade classifier type |
| detection_threshold | Float | 0.1–1.0 | 0.8 | Face detection confidence threshold (0.1=lenient, 1.0=strict) |
| min_face_size | Int | 32–512 | 64 | Minimum face dimension in pixels |
| auto_padding_ratio | Int | 0–100 | 35 | Padding as percentage of detected face size |
| aspect_ratio | Combo | — | auto | Crop aspect ratio: `auto`, `1:1`, `9:16`, `16:9`, `4:3` |
| output_mode | Combo | — | largest_face | `largest_face` or `all_faces` |
| temporal_smoothing | Int | 0–100 | 0 | 0=disabled (image mode) · 1–100=EMA smoothing strength for video |
| output_height | Int | 256–2048 | 512 | Output height for cropped faces (width derived from aspect ratio) |
| instance_id | String | — | "0" | Unique ID for temporal smoothing (share across frames). Use "0" for image mode |
| classifier_type | Combo | — | default | Haar cascade: `default` or `alternative` |
| face_output_format | Combo | — | strip | `strip` (horizontal) or `individual` (separate batch items) |
| padding | Int | 0–256 | 0 | Legacy padding in pixels — if >0, overrides `auto_padding_ratio` |
### Outputs
| Output | Type | Description |
|--------|------|-------------|
| cropped_faces | IMAGE | Batch of cropped face tensors `[B, H, W, C]` |
| face_metadata | FLOAT | Per-face metadata `[x, y, w, h, score, detected]` normalized to image dims. Shape: `[B, 6]` — NOT an image, use for downstream bbox logic only |
### Temporal Smoothing for Video
When processing video frames through ComfyUI, face detection bboxes can jitter frame-to-frame. Enable temporal smoothing to stabilize:
- Set `temporal_smoothing` to 1–100 (higher = more smoothing)
- Use a consistent `instance_id` across all frames in the same video sequence
- Set to `"0"` for single-image mode (no smoothing)
## Changelog
### v2.1.3
- **FIX**: `VALIDATE_INPUTS` now includes required combo fields (`aspect_ratio`, `output_mode`, `classifier_type`) in its signature, forcing ComfyUI to delegate their validation to our method instead of doing strict framework-level "Value not in list" checks. Legacy workflows with misaligned positional `widgets_values` (e.g. `'auto'` landing on `output_mode`, `0` landing on `classifier_type`) are now caught and replaced with defaults.
- **FIX**: Added defensive combo sanitization in both v1 and v3 execute methods — invalid combo values are replaced with defaults at runtime as a safety net.
### v2.1.2
- **FIX**: `instance_id` input type changed from INT to STRING. Legacy workflows pass `instance_id="default"` (string) from old v1 nodes — ComfyUI's `validate_inputs` runs before `execute()`, so `_coerce_int` never fires. Since `instance_id` is only a dict key, STRING is the correct type.
### v2.1.1
- **FIX**: `temporal_smoothing` input validation error — moved to optional section in `INPUT_TYPES` to prevent ComfyUI framework-level `int()` coercion crash when legacy workflows pass string `"default"` (from `classifier_type`) into this slot via positional `widgets_values` mapping
- **FIX**: Added `_coerce_int()` helper for safe string→int conversion with fallback to defaults, applied defensively in both v1 and v3 execute methods
- **FIX**: Enhanced `VALIDATE_INPUTS` to handle type mismatches gracefully (was only handling `face_output_format` before)
### v2.1.0
- **BACKWARD-COMPAT**: Re-added optional `face_output_format` param (`strip`/`individual`) — old workflows now work; invalid values auto-fallback with warning
- **BACKWARD-COMPAT**: Re-added optional `padding` param — auto-converts to `auto_padding_ratio`
- **FIX**: `all_faces` mode now actually detects ALL faces (not just largest)
- **FIX**: `OUTPUT_NODE=True` on v3 schema
- **FIX**: `VALIDATE_INPUTS` on v1 wrapper to catch invalid combo values early
### v2.0.0
- Auto-Padding, Temporal Smoothing, Aspect Ratio Presets, Full Batch Processing, GPU-First, Proper Error Signaling
## Compatibility
- **ComfyUI v3**: Full schema support with async execution
- **ComfyUI v1/v2**: Backward compatibility via wrapper class
- **Auto-detection**: Automatically selects appropriate implementation
- **ComfyUI v3**: Full schema support with async execution (`DEFINE_SCHEMA`)
- **ComfyUI v1/v2**: Backward compatibility via `FaceDetectionNodeV1` wrapper class
- **Auto-detection**: Automatically selects appropriate implementation based on available ComfyUI API
## Requirements
- Python ≥ 3.8
- Python ≥ 3.10
- OpenCV ≥ 4.5.0
- PyTorch ≥ 1.9.0
- PyTorch ≥ 2.0.0
- NumPy ≥ 1.21.0
- Pillow ≥ 8.0.0
## License
Apache License Version 2.0, January 2004 - see LICENSE file for details.
Apache License Version 2.0, January 2004 — see [LICENSE](LICENSE) file for details.
+3 -3
View File
@@ -1,12 +1,12 @@
{
"author": "Limbicnation",
"title": "ComfyUI Face Detection Node",
"title": "ComfyUI Face Detection Node v2",
"id": "comfyui-face-detection-node",
"reference": "https://github.com/Limbicnation/ComfyUI_FaceDetectionNode",
"files": [
"https://github.com/Limbicnation/ComfyUI_FaceDetectionNode"
],
"install_type": "git-clone",
"description": "A ComfyUI custom node for face detection and cropping using OpenCV Haar cascades, with full ComfyUI v3 schema support and backward compatibility. Features adjustable detection threshold, minimum face size, padding, and multiple classifier options.",
"description": "H100-optimized face detection with Auto-Padding, Temporal Smoothing, Aspect Ratio Presets (1:1/9:16/16:9/4:3/auto), and full batch processing for LTX-Video avatar pipelines. Backward compatible with v1.x workflows.",
"nodename_pattern": "FaceDetectionNode"
}
}
+977 -492
View File
File diff suppressed because it is too large Load Diff
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

+4 -4
View File
@@ -2,17 +2,17 @@
"custom_nodes": [
{
"author": "Limbicnation",
"title": "ComfyUI Face Detection Node",
"title": "ComfyUI Face Detection Node v2",
"reference": "https://github.com/Limbicnation/ComfyUI_FaceDetectionNode",
"files": [
"https://github.com/Limbicnation/ComfyUI_FaceDetectionNode"
],
"install_type": "git-clone",
"description": "A ComfyUI custom node for face detection and cropping using OpenCV Haar cascades, with full ComfyUI v3 schema support and backward compatibility.",
"description": "H100-optimized face detection with Auto-Padding, Temporal Smoothing, Aspect Ratio Presets, and full batch processing for LTX-Video avatar pipelines.",
"nodes": [
"Face Detection and Crop"
"Face Detection and Crop v2"
],
"nodename_pattern": "FaceDetectionNode"
}
]
}
}
+6 -6
View File
@@ -1,15 +1,15 @@
[project]
name = "ComfyUI_FaceDetectionNode"
description = "A ComfyUI custom node for face detection and cropping using OpenCV Haar cascades, with full ComfyUI v3 schema support and backward compatibility."
version = "1.1.0"
description = "H100-optimized face detection with Auto-Padding, Temporal Smoothing, Aspect Ratio Presets, and full batch processing for LTX-Video avatar pipelines. Backward compatible with v1.x workflows."
version = "2.1.3"
license = {text = "Apache-2.0"}
dependencies = ["opencv-python>=4.5.0", "torch>=1.9.0", "torchvision>=0.10.0", "numpy>=1.21.0", "Pillow>=8.0.0"]
dependencies = ["opencv-python>=4.5.0", "torch>=2.0.0", "numpy>=1.21.0"]
[project.urls]
Repository = "https://github.com/Limbicnation/ComfyUI_FaceDetectionNode"
# Used by Comfy Registry https://comfyregistry.org
[tool.comfy]
PublisherId = "Limbicnation"
DisplayName = "Face Detection Node"
Icon = ""
PublisherId = "limbicnation"
DisplayName = "Face Detection and Crop v2"
Icon = "https://raw.githubusercontent.com/Limbicnation/ComfyUI_FaceDetectionNode/main/icon.png"
+1 -3
View File
@@ -1,5 +1,3 @@
opencv-python>=4.5.0
torch>=1.9.0
torchvision>=0.10.0
torch>=2.0.0
numpy>=1.21.0
Pillow>=8.0.0