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

