cv2.face.getFacesHAAR
Haar face detection in one shot, with no knobs to turn
- image
- bool
- nparray
This is the flat-function door to the oldest face detector in the world: a Viola-Jones cascade of boosted Haar features, circa 2001. It takes an image and the name of a cascade XML and returns the face rectangles it found. It works with no GPU, no ONNX runtime, no model download in the ML sense - which is why it's still in OpenCV twenty-five years later - and it is, plainly, the worst accuracy-per-effort option in this pack for faces. The pack's own documentation says as much and points you at its YuNet node instead. So why would you touch it? Because it's one node, it never downloads anything, and for "is there a face roughly here, at all" it is often enough.
How it works
A Haar cascade is a cascade of boosted stage tests. Each stage looks at a handful of rectangular intensity-difference features and either rejects the window or passes it on; early stages reject almost everything cheaply, so real work is only spent on promising windows. You give it a grayscale image and it runs a sliding multi-scale search.
face_cascade_name is a plain string - the path to a cascade XML - and the wrapper passes it straight through to OpenCV with no resolution against ComfyUI's folders. Give it something cv2 can actually open; an absolute path is the version that doesn't depend on the process's working directory. This matters more than usual right now: OpenCV 5 removed the bundled cascade files, so cv2.data.haarcascades is an empty folder in current builds. Download haarcascade_frontalface_default.xml from the OpenCV 4.x branch (data/haarcascades) and keep it somewhere stable. This pack's curated CV Cascade Detect reads cascades from ComfyUI/models/cascades, which is the tidier place to put them.
You can feed image an IMAGE, a MASK or an NPARRAY; a colour IMAGE gets converted to gray internally. The inputs, though, end there. There is no scaleFactor, no minNeighbors, no minimum size on this node - it calls the detector with OpenCV's internal defaults. That's the honest limit of the raw wrapper, and it's the main reason to prefer the curated node.
Outputs
Two sockets. The array output is what you want: the face rectangles, as a raw N x 4 array of x, y, width, height. Zero faces is a valid result with an empty array, not an error. The boolean is the function's own status return - did the cascade load and did the call complete - so treat it as plumbing and count rows when you want the number of faces.
Since it's a raw NPARRAY, the next hop is a bridge or a converter: CV Array To BBoxes to get this pack's native BOUNDING_BOX type (which feeds core's Draw BBoxes, face-swap nodes, or the Impact Pack pipeline), or CV Draw Circles / CV Draw Points for a quick look. Nothing here produces SEGS or MASKs directly, so if your goal is a face mask for detailing, expect to convert.
Is this the detector you want?
Usually not. Per the community's own experience in masking-detection-detailing.md, Haar handles frontal, well-lit, reasonably large faces and falls apart on angles, profiles and heavy occlusion - the exact cases where you're using a detector in the first place. YOLO's face_yolov8n/s weights are the community standard for good reason, and this pack ships CV YuNet Face Detect, an ONNX detector that is far more accurate on faces while still being dependency-light. InsightFace is the other end of the spectrum - heavy, non-commercial weights for the models, and the basis of nearly every identity tool.
Reach for Haar when you want zero model files, fast CPU detection, or a baseline to compare against. Then look at the side-by-side with YuNet and decide, because the pack's author laid that comparison out on purpose.
Installing it
cd ComfyUI/custom_nodes
git clone https://github.com/bmad4ever/comfyui_cv
pip install "opencv-contrib-python-headless~=5.0.0.93"
Or install comfyui_cv through ComfyUI Manager, then restart. Python ≥ 3.12 and a recent V3-API ComfyUI. This node is under image/CV/low-level/face and comes from OpenCV's contrib face module - which means the contrib wheel matters. If something installs plain opencv-python over it, the shared cv2 package loses its contrib submodules and the whole cv2.face family disappears from the menu; tools/repair_opencv_contrib.py --check then --apply fixes that.
Traps
A cascade that "downloads" as an HTML error page saved with an .xml extension loads as an empty cascade, and the failure looks like a mysterious cv2 error rather than a bad download. Check the file starts with XML and has real content. Beyond that: no knobs means no tuning, so if you need to trade speed for recall, move to CV Cascade Detect, which exposes scale_factor, min_neighbors, size limits, a confidence floor, and an equalize_hist toggle that defaults on - because cascades were trained on histogram-equalized crops.
Inputs (2)
| Name | Type | Default | Description |
|---|---|---|---|
| image | NPARRAY,IMAGE,MASK | - - - Accepts a ComfyUI IMAGE/MASK directly (frame 0 of a batch) or an NPARRAY. Arithmetic ops (add, multiply, etc.) process the full IMAGE batch when both inputs have the same batch size. | |
| face_cascade_name | STRING | - - - |
Outputs (2)
| Name | Type | Description |
|---|---|---|
| bool | BOOLEAN | — |
| nparray | NPARRAY | — |