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

Python3.7中NotADirectoryError报错:人脸识别程序运行异常

解决人脸识别程序中的NotADirectoryError报错

我在PyCharm环境开发人脸识别程序时,运行始终触发NotADirectoryError,尝试复制完整目录路径、使用os.path.join方法都没能解决。以下是原代码及报错信息:

原程序代码

import face_recognition
import cv2
import os
import numpy
os.chdir('C:/Users/a/Desktop/ftp')


KNOWN_FACE_DIR = "known_faces"
print(KNOWN_FACE_DIR)
#UNKNOWN_FACES_DIR = r"unknown_faces"
TOLERANCE = 0.6
FRANE_THICKNESS = 3
FONT_THICKNESS = 2
MODEL = "cnn"

video = cv2.VideoCapture(0)


print("loading known faces ")

known_faces = []
known_names = []


for name in os.listdir(KNOWN_FACE_DIR):
    for filename in os.listdir(f"{KNOWN_FACE_DIR}/{name}"):
        image = face_recognition.load_image_file(f"{KNOWN_FACE_DIR}/{name}/{filename}")


print("processing unknown faces")
while True :
    #print(filename)
    #image = face_recognition.load_image_file(f"{UNKNOWN_FACES_DIR}/{filename}")
    ret ,image = video.read()

    locations = face_recognition.face_locations(image, model=MODEL)
    encodings = face_recognition.face_encodings(image, locations)
    #image = cv2.cvtColor(image, cv2.COLOR_RGB2BGR)

    for face_encoding, face_location in zip(encodings, locations):
        results = face_recognition.compare_faces(known_faces, face_encoding, TOLERANCE)
        match = None
        if True in results:
            match = known_names[results.index(True)]
            print(f"Match found:{match}")

            top_left = (face_location[3], face_location[0])
            bottom_right = (face_location[1], face_location[2])

            color = [0,255,0]

            cv2.rectangle(image, top_left, bottom_right, color, FRANE_THICKNESS)

            top_left = (face_location[3], face_location[2])
            bottom_right = (face_location[1], face_location[2]+22)

            cv2.rectangle(image, top_left, bottom_right, color, cv2.FILLED)
            cv2.putText(image, match, (face_location[3]+10,face_location[2]+15).cv2.FONT_HERSHEY_SIMPLEX,0.5,(200,200,200),FONT_THICKNESS)

    cv2.imshow(filename,image)
    if cv2.waitKey(1) & 0xFF == ord("q"):
        break
    cv2.destroyWindow(filename)

报错信息

Traceback (most recent call last):
  File "C:\Users\a\Desktop\ftp\face recognition.py", line 27, in <module>
    for filename in os.listdir(f"{KNOWN_FACE_DIR}/{name}"):
NotADirectoryError: [WinError 267] The directory name is invalid: 'known_faces/Majd.jpg'

问题分析

代码默认KNOWN_FACE_DIR目录下的所有条目都是子目录(用来存放对应人名的人脸图片),但实际known_faces目录里直接存放了图片文件(比如Majd.jpg)。os.listdir()会列出目录下所有文件和子目录,当遍历到图片文件时,调用os.listdir()读取这个文件就会触发报错——因为它不是目录。

解决方案

修改后的完整代码

import face_recognition
import cv2
import os
import numpy as np

# 切换工作目录
os.chdir('C:/Users/a/Desktop/ftp')

KNOWN_FACE_DIR = "known_faces"
TOLERANCE = 0.6
FRAME_THICKNESS = 3  # 修正原拼写错误FRANE_THICKNESS
FONT_THICKNESS = 2
MODEL = "cnn"

video = cv2.VideoCapture(0)

print("加载已知人脸...")

known_faces = []
known_names = []

# 遍历已知人脸目录,仅处理子目录
for entry in os.listdir(KNOWN_FACE_DIR):
    entry_path = os.path.join(KNOWN_FACE_DIR, entry)
    # 跳过非目录条目(比如直接存放的图片)
    if os.path.isdir(entry_path):
        name = entry
        # 遍历子目录下的图片文件
        for filename in os.listdir(entry_path):
            img_path = os.path.join(entry_path, filename)
            # 加载图片并生成人脸编码
            image = face_recognition.load_image_file(img_path)
            encodings = face_recognition.face_encodings(image)
            # 假设单张图片仅含一个人脸,取第一个编码存入列表
            if encodings:
                known_faces.append(encodings[0])
                known_names.append(name)

print("处理摄像头画面...")
while True:
    ret, image = video.read()
    if not ret:
        break  # 摄像头读取失败时退出循环

    # 检测人脸位置并生成编码
    locations = face_recognition.face_locations(image, model=MODEL)
    encodings = face_recognition.face_encodings(image, locations)

    for face_encoding, face_location in zip(encodings, locations):
        # 对比已知人脸编码
        results = face_recognition.compare_faces(known_faces, face_encoding, TOLERANCE)
        match = None
        if True in results:
            match = known_names[results.index(True)]
            print(f"匹配到:{match}")

            # 绘制人脸框
            top_left = (face_location[3], face_location[0])
            bottom_right = (face_location[1], face_location[2])
            color = [0, 255, 0]
            cv2.rectangle(image, top_left, bottom_right, color, FRAME_THICKNESS)

            # 绘制名字背景框
            top_left = (face_location[3], face_location[2])
            bottom_right = (face_location[1], face_location[2] + 22)
            cv2.rectangle(image, top_left, bottom_right, color, cv2.FILLED)
            # 修正语法错误:将点改为逗号
            cv2.putText(image, match, (face_location[3] + 10, face_location[2] + 15),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.5, (200, 200, 200), FONT_THICKNESS)

    # 使用固定窗口名,避免原代码中filename变量未定义问题
    cv2.imshow("人脸识别", image)
    if cv2.waitKey(1) & 0xFF == ord("q"):
        break

# 释放摄像头和窗口资源
video.release()
cv2.destroyAllWindows()

关键修改点

  1. 目录判断:增加os.path.isdir(entry_path)检查,确保只遍历known_faces下的子目录,跳过直接存放的图片文件
  2. 路径拼接:全程使用os.path.join()拼接路径,避免跨平台路径分隔符差异问题
  3. 人脸编码存储:补充人脸编码生成与存储逻辑,这是后续识别功能的核心(原代码仅加载图片未存储编码)
  4. 语法修正:修复cv2.putText中的标点错误、FRANE_THICKNESS的拼写错误
  5. 窗口名修复:使用固定窗口名"人脸识别",解决原代码中filename变量未定义的问题
  6. 资源释放:添加video.release()和cv2.destroyAllWindows(),确保程序退出时释放摄像头和窗口资源

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 15:45:50