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

Python代码中已定义label,为何仍触发NameError未定义报错?

问题原因与修复方案

为什么会触发NameError?

你的label变量是在for (x,y,w,h) in faces_rect:循环内部定义的——只有当faces_rect不为空(也就是检测到人脸)时,循环才会执行,label才会被赋值。如果某一帧没检测到人脸(比如人脸移出画面、光线不足、分类器加载失败),faces_rect是空列表,循环根本跑不起来,label就从未被定义过,后面执行file.write(people[label])自然会报错。

另外你的代码还有几个隐性问题,会加剧这个情况:

  • 循环里重复初始化haar_cascade,而且路径和开头不一致(开头是绝对路径,循环里用相对路径),如果当前工作目录不对,faces.xml加载失败,直接导致faces_rect为空。
  • 代码里漏了关键的人脸检测步骤:没有将帧转灰度图(gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)),也没有调用detectMultiScale生成faces_rect,这会直接导致faces_rect未定义或为空。
  • 就算检测到多张人脸,最后写入文件的也只是最后一张的信息,逻辑可能不符合你的预期。

为什么之前运行正常?

之前能正常跑是因为每一次循环都成功检测到了人脸,for循环正常执行,label被正确赋值。但只要某次摄像头没捕捉到人脸,或者分类器没识别出来,就会触发这个错误。

修复代码的关键点

  1. 提前初始化变量:在循环开头给label和confidence设默认值,避免未定义的情况:
haar_cascade = cv.CascadeClassifier(r'C:\Users\User\Desktop\Project-III\faces.xml')
people = ['ABC', 'XYZ','PQR']
file = open(r'C:\Users\User\Desktop\face.txt', 'a')
capture = cv.VideoCapture(1)

while True:
    isTrue, frame = capture.read()
    if not isTrue:
        break  # 读取帧失败直接退出
    
    # 补全灰度转换和人脸检测步骤
    gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    faces_rect = haar_cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=4)
    
    # 初始化默认值
    label = -1
    confidence = 0.0
    
    for (x,y,w,h) in faces_rect:
        # 修正ROI截取错误:x:x+w而不是x:x+h
        faces_roi = gray[y:y+h, x:x+w]
        label, confidence = face_recognizer.predict(faces_roi)
        print(f'Label={people[label]} with a confidence of {confidence}')
        # 如果要每检测到一张人脸就写入,把write放在循环内
        # file.write(f"{people[label]} {confidence} {datetime.datetime.now()}\n")
    
    # 只有检测到人脸时才写入文件
    if label != -1:
        file.write(f"{people[label]} {confidence} {datetime.datetime.now()}\n")
    
    # 把显示窗口放在循环内,实时更新画面
    cv.imshow('Detected faces', frame)
    
    if cv.waitKey(20) & 0xFF == ord('d'):
        break

file.close()
cv.destroyAllWindows()  # 加上销毁窗口的代码
  1. 补全缺失的检测步骤:必须包含灰度转换和detectMultiScale调用,否则根本检测不到人脸。
  2. 修正ROI错误:之前的x:x+h会导致截取的人脸区域变形,改成x:x+w才是正确的矩形区域。
  3. 避免重复加载分类器:把haar_cascade初始化放在循环外,没必要每次循环都重新加载一次文件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 10:22:49