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

  1. Lower det_thresh / increase det_size when creating FaceAnalysis (e.g. det_size=(640,640)).
  2. Skip or blacklist images that legitimately contain no face before evaluation.
  3. Verify image loading channel order and that images actually contain visible faces.
  4. 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

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


AI-assisted analysis of deepinsight/insightface@7fadd420c2 (2026-08-28). Data as JSON: /api/errors/00ad01ae86d1d3d3. Report an issue: GitHub.