You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python使用face_recognition库出现索引越界及重复存人脸问题求助

问题排查与修复方案

问题1:IndexError: list index out of range 报错修复

原因

face_recognition.face_encodings() 函数在输入图片中没有检测到人脸时,会返回空列表,直接取下标[0]就会触发索引越界报错。你初始加载的KArtIntel文件夹中可能存在不包含人脸的图片,或者图片损坏无法正常读取。

修复方法

  1. 读取初始图片后先判断是否读取成功,编码前先判断编码列表非空
  2. 路径拼接改用os.path.join()避免操作系统路径格式问题

问题2:同一张人脸重复保存修复

现有代码逻辑错误点

  • 每次循环都将计数变量i重置为0,导致保存的文件名永远重复,旧文件会被覆盖
  • 匹配逻辑错误:误将当前帧所有编码的列表encodesCurFrame拿去和已知编码列表判断,应该判断当前单个人脸编码encodeFace和所有已知编码的最小距离是否超过阈值(通常取0.6)
  • 仅保存整帧图片,没有按人脸坐标截取单独的人脸区域
  • 新增人脸后没有将对应编码加入已知编码列表encodelistKnown,导致后续帧检测到同一张人脸仍会判定为新人脸
  • 变量i定义在循环内部,计数完全不生效

修正后完整代码

import face_recognition
import cv2
import os
import numpy as np

# 配置路径
known_face_path = r"C:\Users\CHIJINDU\Desktop\KArtIntel"
save_path = known_face_path  # 新人脸保存路径
os.makedirs(save_path, exist_ok=True)

# 加载已知人脸
images = []
class_names = []
myList = os.listdir(known_face_path)
for cl in myList:
    # 跳过非图片文件,避免读取错误
    if cl.lower().endswith(('.png', '.jpg', '.jpeg', '.bmp')):
        curImg_path = os.path.join(known_face_path, cl)
        curImg = cv2.imread(curImg_path)
        if curImg is None:
            continue
        images.append(curImg)
        class_names.append(os.path.splitext(cl)[0])
print("已加载已知人脸:", class_names)

def find_encodings(images):
    encodelist = []
    for idx, img in enumerate(images):
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        encodes = face_recognition.face_encodings(img)
        # 跳过没有检测到人脸的图片
        if len(encodes) == 0:
            print(f"警告:第{idx}张图片未检测到人脸,已跳过")
            continue
        encodelist.append(encodes[0])
    return encodelist

encodelistKnown = find_encodings(images)
print(f"已加载有效人脸编码数量:{len(encodelistKnown)}")

# 初始化保存计数,避免覆盖已有文件
save_counter = len([f for f in os.listdir(save_path) if f.startswith("KUDOS-J14")])
# 匹配阈值,数值越低匹配要求越严格
MATCH_THRESHOLD = 0.6

cap = cv2.VideoCapture(r"C:\Users\CHIJINDU\Desktop\Elastic.mp4")

while True:
    success, img = cap.read()
    # 视频读取结束就退出循环
    if not success:
        break
    imgS = cv2.resize(img, (0,0), None, 0.25, 0.25)
    imgS = cv2.cvtColor(imgS, cv2.COLOR_BGR2RGB)

    faceCurFrame = face_recognition.face_locations(imgS)
    encodesCurFrame = face_recognition.face_encodings(imgS, faceCurFrame)

    for encodeFace, faceloc in zip(encodesCurFrame, faceCurFrame):
        # 计算和已知人脸的匹配度
        if len(encodelistKnown) > 0:
            matches = face_recognition.compare_faces(encodelistKnown, encodeFace, tolerance=MATCH_THRESHOLD)
            faceDis = face_recognition.face_distance(encodelistKnown, encodeFace)
            min_dis = np.min(faceDis)
            is_known = min_dis < MATCH_THRESHOLD
        else:
            # 没有已知人脸的情况,直接判定为新人脸
            is_known = False

        if not is_known:
            # 还原人脸坐标(因为之前缩放到了0.25倍)
            y1, x2, y2, x1 = [pos *4 for pos in faceloc]
            # 截取人脸区域
            face_img = img[y1:y2, x1:x2]
            # 保存人脸截图
            save_name = f"KUDOS-J14{save_counter}.jpg"
            cv2.imwrite(os.path.join(save_path, save_name), face_img)
            # 将新人脸编码加入已知列表,避免重复保存
            encodelistKnown.append(encodeFace)
            save_counter += 1
            print(f"已保存新人脸:{save_name}")

    # 显示结果
    cv2.imshow('Video', img)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

cap.release()
cv2.destroyAllWindows()

内容的提问来源于stack exchange,提问作者KUDOS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.20 16:24:03