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

人脸识别程序遇未知人脸时Webcam出现Not Responding问题求助

问题诊断与修复

你的程序在未知人脸场景下出现窗口无响应,核心问题集中在else分支的逻辑错误,以及整体窗口事件处理的缺失:

具体问题点

  • 重复读取摄像头帧:else分支里再次调用cap.read(),跳过了当前循环已经读取的img帧,导致帧序列混乱,后续操作基于新读取的帧,和当前显示逻辑脱节。
  • 提前释放摄像头并销毁窗口:else分支里直接执行cap.release()和cv2.destroyAllWindows(),但外层while True循环还在继续,后续循环里cap.read()会持续失败,窗口无法正常更新。
  • 混用matplotlib和OpenCV窗口:plt.imshow()会启动matplotlib的事件循环,和OpenCV的窗口事件处理冲突,阻塞主线程导致窗口假死。
  • 窗口事件处理不完整:cv2.waitKey(1)只在识别到已知人脸时调用,其他场景下没有触发,OpenCV窗口无法处理用户输入和刷新事件,必然出现"Not Responding"。
  • 未处理无检测人脸的场景:当faceCurFrame为空(没检测到人脸)时,for循环不会执行,完全没有窗口更新逻辑,直接进入time.sleep(0),窗口长时间不刷新导致假死。

修复后的完整代码

import cv2
import numpy as np
import face_recognition
import os
# 不需要matplotlib,用OpenCV足够完成截图功能

path = 'images'
images = []
classNames = []
myList = os.listdir(path)

print(myList)
for cls in myList:
    curImg = cv2.imread(f'{path}/{cls}')
    images.append(curImg)
    classNames.append(os.path.splitext(cls)[0])

print(classNames)

def findEncodings(images):
    encodeList = []
    for img in images:
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
        # 这里加个判断,避免读取的图片中没有人脸导致索引报错
        encodes = face_recognition.face_encodings(img)
        if encodes:
            encodeList.append(encodes[0])
    return encodeList

encodeListKnown = findEncodings(images)
print("Encoding Complete.")

cap = cv2.VideoCapture(1400)
# 确保temp_img目录存在,避免保存截图时出错
os.makedirs("temp_img", exist_ok=True)

while True:
    success, img = cap.read()
    if not success:
        print("无法读取摄像头帧")
        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)
    encodeCurFrame = face_recognition.face_encodings(imgS, faceCurFrame)
    
    # 标记是否识别到已知人脸
    recognized = False
    for encodeFace, faceLoc in zip(encodeCurFrame, faceCurFrame):
        matches = face_recognition.compare_faces(encodeListKnown, encodeFace)
        faceDis = face_recognition.face_distance(encodeListKnown, encodeFace)
        matchIndex = np.argmin(faceDis)

        if matches[matchIndex]:
            recognized = True
            name = classNames[matchIndex].upper()
            print(name)
            y1,x2,y2,x1 = faceLoc
            y1,x2,y2,x1 = y1*4,x2*4,y2*4,x1*4
            cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
            cv2.rectangle(img, (x1, y2-35), (x2, y2), (0, 255, 0), cv2.FILLED)
            cv2.putText(img, name, (x1+6, y2-6), cv2.FONT_HERSHEY_COMPLEX, 0.9, (255, 255, 255), 2)
    
    # 处理未识别或无检测人脸的情况
    if not recognized and len(faceCurFrame) > 0:
        # 直接用当前循环读取的img帧保存,不需要再读一次
        cv2.imwrite(".\\temp_img\\temp.png", img)
        print("Image Captured.")
        # 可以在画面上标注未识别
        cv2.putText(img, "UNKNOWN", (50, 50), cv2.FONT_HERSHEY_COMPLEX, 1, (0, 0, 255), 2)
    
    # 不管什么情况,都要刷新窗口并处理事件
    cv2.imshow('Webcam', img)
    # 按q键退出循环
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# 循环结束后再释放资源
cap.release()
cv2.destroyAllWindows()

修复说明

  1. 移除matplotlib依赖:用OpenCV直接完成截图和画面标注,避免多窗口事件冲突。
  2. 统一帧处理逻辑:所有操作基于当前循环读取的img帧,不再重复调用cap.read()。
  3. 全局窗口刷新:将cv2.imshow和cv2.waitKey(1)移到循环末尾,确保每次循环都刷新窗口,处理事件。
  4. 资源释放时机调整:只在循环结束(用户按q退出)后才释放摄像头和销毁窗口,避免提前终止摄像头服务。
  5. 增加异常防护:检查摄像头读取是否成功,处理训练图片中无人脸的情况,避免索引报错。
  6. 未识别场景优化:仅在检测到人脸但无法匹配时才截图,同时在画面上标注"UNKNOWN",提升交互反馈。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 00:01:03