deepinsight/insightface · warning · ValueError
no face detected
Error message
no face detected
What it means
_select_face_from_faces raises ValueError('no face detected') when the detector's face list is empty — the embedding step cannot proceed without a face, regardless of policy (policies only differentiate multi-face cases). Callers reach it through select_face_by_policy / _embedding_for_image during evaluation.
Source
Thrown at python-package/insightface/gui/core/evaluation.py:166
bounding_box_size = (det[:, 2] - det[:, 0]) * (det[:, 3] - det[:, 1])
img_center = img_size / 2.0
offsets = np.vstack(
[
(det[:, 0] + det[:, 2]) / 2.0 - img_center[1],
(det[:, 1] + det[:, 3]) / 2.0 - img_center[0],
]
)
offset_dist_squared = np.sum(np.power(offsets, 2.0), axis=0)
return faces[int(np.argmax(bounding_box_size - offset_dist_squared * 2.0))]
except Exception:
return max(faces, key=_face_area)
def _select_face_from_faces(faces, image_shape, path: Path, policy: str, stage: str):
del path, stage
face_count = len(faces)
if face_count == 0:
raise ValueError("no face detected")
if face_count > 1 and policy == MULTI_FACE_REQUIRE_ONE:
raise ValueError(f"multiple faces detected ({face_count}); expected exactly one face")
if face_count > 1 and policy == MULTI_FACE_SKIP:
raise ValueError(f"skipped multi-face image ({face_count} faces)")
if face_count > 1 and policy == MULTI_FACE_USE_CENTERED_LARGEST:
return _largest_centered_face(faces, image_shape)
if face_count > 1:
return max(faces, key=_face_area)
return faces[0]
def select_face_by_policy(faces, image_shape, policy: str = MULTI_FACE_REQUIRE_ONE, path: str | Path = "", stage: str = ""):
return _select_face_from_faces(
faces,
image_shape,
Path(path) if path else Path("image"),
_normalize_multi_face_policy(policy),
stage,View on GitHub (pinned to 7fadd420c2)
Solutions
- Lower det_thresh / increase det_size when creating FaceAnalysis (e.g. det_size=(640,640)).
- Skip or blacklist images that legitimately contain no face before evaluation.
- Verify image loading channel order and that images actually contain visible faces.
- Catch this ValueError per-image in evaluation loops and count it as a 'no-detection' skip metric.
Example fix
# before
emb = _embedding_for_image(img_path) # ValueError: no face detected
# after
faces = app.get(img)
if not faces:
stats['no_face'] += 1
continue # skip image
emb = _embedding_for_image(img_path) Defensive patterns
Strategy: try-catch
Validate before calling
faces = app.get(img)
if not faces:
skip(image_path) # no face — do not call the embedding step Type guard
def has_detectable_face(faces) -> bool:
return len(faces) >= 1 Try / catch
try:
emb = _embedding_for_image(p)
except ValueError as e:
if str(e) == 'no face detected':
stats['no_face'] += 1
continue
raise Prevention
- Pre-filter datasets with the detector before evaluation.
- Tune det_size/det_thresh for small or low-quality faces.
- Track no-detection counts as a data-quality metric.
When it happens
Trigger: Evaluating an image where FaceAnalysis.get() returns zero faces: dark/blurry/tiny faces, non-face images, det_thresh too high, or det_size too small for the face scale.
Common situations: Datasets containing crowd/background images; det_size=(320,320) missing small faces; det_thresh raised too aggressively; wrong BGR/RGB channel order feeding the detector; grayscale/low-res probe photos.
Related errors
- multiple faces detected ({face_count}); expected exactly one
- skipped multi-face image ({face_count} faces)
- no face or embedding
- failed detection
- Identity folder root not found: {root}
AI-assisted analysis of deepinsight/insightface@7fadd420c2 (2026-08-28).
Data as JSON: /api/errors/00ad01ae86d1d3d3.
Report an issue: GitHub.