Nodes/ComfyUI Deepface/Deepface Verify
ComfyUI Node

Deepface Verify

Keep only the renders that actually look like the person

By jordoh·Created 3 years ago·Updated 2 months ago· 38
Deepface Verify
  • images
  • reference_images
  • verified_images
  • verified_image_distances
  • verified_image_verified_ratios
  • rejected_images
  • rejected_image_distances
  • rejected_image_verified_ratios
  • bboxes
distance_threshold0.60
ratio_threshold0.70
detector_backendssd
model_nameVGG-Face
sort_bydistance

The scenario: you ran a big batch of generations, your character's face is drifting all over the place, and you need to keep only the images where it actually looks like the reference. That's exactly what Deepface Verify is for - and it's the reason this pack exists. It wraps DeepFace.verify() as graph plumbing, and it's a direct descendant of CeFurkan's widely-shared trick of scoring finetune outputs with deepface and ranking them by face similarity. Give it a stack of candidate images and a set of reference faces, and it splits them into "good enough" and "nope," nearest-match first.

How it works

For every input image it compares against every reference image: detect the face, embed it, measure the distance to the reference's embedding - smaller is closer. That's an n×m set of comparisons, which is the thing to remember about speed. From all those pairwise results it computes two numbers per input image:

  • average distance across all your reference images
  • verified ratio - the fraction of references that deepface itself flags as a match, using the selected model's own threshold

An image passes only if both clear your thresholds: average distance below distance_threshold AND ratio at or above ratio_threshold. The two filters are deliberately complementary - one reference that happens to be a great match shouldn't carry a set of bad ones over the line, and vice versa.

Inputs that matter

  • images - your candidates.
  • reference_images - the face(s) you want to match. More references means more robust but linearly slower, since each one adds a comparison per image.
  • distance_threshold - default 0.6; lower is stricter. Note it's looser than deepface's own per-model "verified" cutoff, which is exactly why the ratio exists.
  • ratio_threshold - default 0.7; the fraction of references that must verify.
  • detector_backend - default ssd here (not retinaface like the pack's other nodes), because this node does the most detection work and ssd is the fast default.
  • model_name - VGG-Face by default. Facenet512 and ArcFace are more discriminating but heavier, and each new model downloads on first use.

Outputs

verified_images and rejected_images, each sorted by distance (nearest first), plus the per-image ..._distances and ..._verified_ratios for both piles, and bboxes - one frame of detections per input image, in input order, so you can draw boxes over the originals with a BOUNDING_BOX renderer (Impact Pack has the pieces). The important gotcha: any output can be None when nothing qualifies, and ComfyUI's built-in PreviewImage/SaveImage choke on None. The README's answer is ComfyUI-Impact-Pack's None-handling nodes in front of the preview/save.

Installing

Same pack, same story as the rest: Manager → search "ComfyUI Deepface", or:

cd ComfyUI/custom_nodes
git clone https://github.com/jordoh/ComfyUI-Deepface
cd ComfyUI-Deepface
pip install -r requirements.txt

Restart, and the first run downloads models into ComfyUI/models/deepface. The heavy lift is TensorFlow (deepface==0.0.89 + tf_keras in requirements.txt): TF needs CUDA/cuDNN to use your GPU and falls back to CPU when it can't, which turns an already n×m workload into a very long coffee break.

Troubleshooting

  • Watch the console - the node prints every comparison's distance and verified status, so you can see which reference is dragging the average up.
  • If a "face too large to detect" error would kill an image, the node pads it by 40% and retries. That resilience trick is in the code, not the README.
  • Empty results? Check thresholds before blaming the models. distance_threshold at 0.6 is lenient, so an all-rejected batch usually means the faces genuinely don't match.

If you're picking a likeness threshold by feel, this node gives you the numbers to do it properly - and it's the closest thing this pack has to a headline act.

Categorydeepface

Inputs (7)

NameTypeDefaultDescription
imagesIMAGE
reference_imagesIMAGE
distance_thresholdFLOAT0.60
ratio_thresholdFLOAT0.70
detector_backendCOMBOssd9 options: opencv, ssd, dlib, mtcnn, retinaface, mediapipe, +3
model_nameCOMBOVGG-Face9 options: VGG-Face, Facenet, Facenet512, OpenFace, DeepFace, DeepID, +3
sort_byCOMBOdistance2 options: distance, ratio

Outputs (7)

NameTypeDescription
verified_imagesIMAGE
verified_image_distancesNUMBER
verified_image_verified_ratiosNUMBER
rejected_imagesIMAGE
rejected_image_distancesNUMBER
rejected_image_verified_ratiosNUMBER
bboxesBOUNDING_BOX