Python人脸识别程序检测到人脸即崩溃的问题排查求助
Python人脸识别程序捕捉人脸时崩溃问题排查
问题描述
我开发的基于Python的人脸识别程序,每当摄像头捕捉到人脸时就会崩溃。尝试更换不同人脸图片、甚至不加载图片,问题依然存在,恳请帮忙排查崩溃原因。
程序代码
import face_recognition import os, sys import cv2 import numpy as np import math def face_confidence(face_distance, face_match_threshold=0.6): range = (1.0-face_match_threshold) linear_valu=(1.0-face_distance)/(range*2.0) if face_distance> face_match_threshold: return str(round(linear_valu*100/2))+'%' else: value= (linear_valu+((1-linear_valu)*math.pow((linear_valu-0.5)*2,0.2)))*100 return str(round(value,2))+"%" class FaceRecognition: face_location=[] face_encodings=[] face_names=[] known_face_encodings=[] known_face_names=[] process_current_frame= True def __init__(self): self.encode_faces() def encode_faces(self): for image in os.listdir('faces'): face_image= face_recognition.load_image_file(f'faces/{image}') face_encoding= face_recognition.face_encodings(face_image)[0] self.known_face_encodings.append(face_encoding) self.known_face_encodings.append(image) print(self.known_face_names) def run_recognition(self): video_capture= cv2.VideoCapture(0) if not video_capture.isOpened(): sys.exit("Video source not found") while True: ret, frame= video_capture.read() if self.process_current_frame: small_frame=cv2.resize(frame,(0,0),fx=0.25,fy=0.25) rgb_small_frame= small_frame[:,:,::-1] #find all faces in frame self.face_location= face_recognition.face_locations(rgb_small_frame) self.face_encodings=face_recognition.face_encodings(rgb_small_frame, self.face_location) self.face_names=[] for face_encoding in self.face_encodings: matches= face_recognition.compare_faces(self.known_face_encodings, face_encoding) name= 'Unknown' confidence= 'Unknown' face_distances= face_recognition.face_distance(self.known_face_encodings,face_encoding) best_match_index=np.argmin(face_distances) if matches[best_match_index]: name= self.known_face_names[best_match_index] confidence=face_confidence(face_distances[best_match_index]) self.face_names.append(f'{name}({confidence}') self.process_current_frame = not self.process_current_frame #desplay annotaations for(top,right,bottom,left), name in zip(self.face_location, self.face_names): top*=4 right*=4 bottom*=4 left*=4 cv2.rectangle(frame,(left,top),(right,bottom),(0,0,255),2) cv2.rectangle(frame,(left,bottom-35),(right,bottom),(0,0,255),-1) cv2.putText(frame,name,(left+6,bottom-6),cv2.FONT_HERSHEY_DUPLEX,0.8,(255,255,255),1) cv2.imshow("face recognition",frame) if cv2.waitKey(1)== ord('q'): break video_capture.release() cv2.destroyAllWindows() if __name__=='__main__': fr = FaceRecognition() fr.run_recognition()
报错信息
Traceback (most recent call last): File "/Users/youssefmajdalani/PycharmProjects/faceproj/main.py", line 96, in <module> fr.run_recognition() File "/Users/youssefmajdalani/PycharmProjects/faceproj/main.py", line 56, in run_recognition self.face_encodings=face_recognition.face_encodings(rgb_small_frame, self.face_location) File "/Users/youssefmajdalani/PycharmProjects/faceproj/venv/lib/python3.9/site-packages/face_recognition/api.py", line 214, in face_encodings return [np.array(face_encoder.compute_face_descriptor(face_image, raw_landmark_set, num_jitters)) for raw_landmark_set in raw_landmarks] File "/Users/youssefmajdalani/PycharmProjects/faceproj/venv/lib/python3.9/site-packages/face_recognition/api.py", line 214, in <listcomp> return [np.array(face_encoder.compute_face_descriptor(face_image, raw_landmark_set, num_jitters)) for raw_landmark_set in raw_landmarks] TypeError: compute_face_descriptor(): incompatible function arguments. The following argument types are supported: 1. (self: _dlib_pybind11.face_recognition_model_v1, img: numpy.ndarray[(rows,cols,3),numpy.uint8], face: _dlib_pybind11.full_object_detection, num_jitters: int = 0, padding: float = 0.25) -> _dlib_pybind11.vector 2. (self: _dlib_pybind11.face_recognition_model_v1, img: numpy.ndarray[(rows,cols,3),numpy.uint8], num_jitters: int = 0) -> _dlib_pybind11.vector 3. (self: _dlib_pybind11.face_recognition_model_v1, img: numpy.ndarray[(rows,cols,3),numpy.uint8], faces: _dlib_pybind11.full_object_detections, num_jitters: int = 0, padding: float = 0.25) -> _dlib_pybind11.vectors 4. (self: _dlib_pybind11.face_recognition_model_v1, batch_img: List[numpy.ndarray[(rows,cols,3),numpy.uint8]], batch_faces: List[_dlib_pybind11.full_object_detections], num_jitters: int = 0, padding: float = 0.25) -> _dlib_pybind11.vectorss 5. (self: _dlib_pybind11.face_recognition_model_v1, batch_img: List[numpy.ndarray[(rows,cols,3),numpy.uint8]], num_jitters: int = 0) -> _dlib_pybind11.vectors Invoked with: <_dlib_pybind11.face_recognition_model_v1 object at 0x10533b830>, array([[[134, 105, 82], [135, 106, 83], [136, 107, 82], ..., [132, 111, 81], [133, 111, 82], [132, 110, 81]], [[131, 102, 79], [136, 107, 84], [136, 106, 81], ..., [131, 111, 81], [133, 112, 82], [133, 111, 81]], [[127, 100, 76], [131, 104, 81], [133, 104, 80], ..., [132, 112, 82], [132, 111, 81], [134, 112, 80]], ..., [[138, 116, 89], [139, 117, 89], [139, 116, 87], ..., [168, 140, 121], [ 37, 18, 8], [ 44, 30, 17]], [[137, 115, 86], [138, 116, 89], [140, 117, 90], ..., [146, 105, 97], [ 39, 17, 7], [ 42, 24, 10]], [[134, 115, 85], [137, 115, 86], [138, 116, 87], ..., [129, 92, 88], [ 45, 24, 12], [ 42, 23, 9]]], dtype=uint8), <_dlib_pybind11.full_object_detection object at 0x1078d3d30>, 1 Process finished with exit code 1
问题分析与修复方案
1. 核心崩溃原因:类变量与实例变量混淆+命名错误
代码中类定义的face_location是类变量(所有实例共享),且命名为单数,但face_recognition.face_locations()返回的是人脸位置列表。后续调用face_encodings()时,若类变量被意外修改为单个对象,就会触发参数类型不匹配的报错。
修复:将类变量改为实例变量,统一使用复数命名保持语义一致:
class FaceRecognition: def __init__(self): self.face_locations = [] self.face_encodings = [] self.face_names = [] self.known_face_encodings = [] self.known_face_names = [] self.process_current_frame = True self.encode_faces()
同时将run_recognition()中所有self.face_location替换为self.face_locations。
2. 致命逻辑错误:人脸编码与文件名存储混淆
encode_faces()方法中,错误地将图片文件名添加到known_face_encodings列表(本该存储人脸编码numpy数组),导致列表中混合了数组和字符串,后续对比时必然出错。
修复:将文件名存入known_face_names,并去掉文件后缀:
def encode_faces(self): for image in os.listdir('faces'): face_image= face_recognition.load_image_file(f'faces/{image}') # 添加异常处理,避免图片无人脸导致索引错误 face_encodings = face_recognition.face_encodings(face_image) if not face_encodings: print(f"警告:图片{image}中未检测到人脸,已跳过") continue face_encoding= face_encodings[0] self.known_face_encodings.append(face_encoding) # 存储去掉后缀的文件名作为人名 self.known_face_names.append(os.path.splitext(image)[0]) print(self.known_face_names)
3. 其他细节错误修复
- 拼写错误:
face_confidence()中的linear_valu改为linear_value,且避免使用Python内置函数range作为变量名,改为range_val:def face_confidence(face_distance, face_match_threshold=0.6): range_val = (1.0 - face_match_threshold) linear_value = (1.0 - face_distance) / (range_val * 2.0) if face_distance > face_match_threshold: return str(round(linear_value * 100 / 2)) + '%' else: value = (linear_value + ((1 - linear_value) * math.pow((linear_value - 0.5) * 2, 0.2))) * 100 return str(round(value, 2)) + "%" - 字符串格式错误:
self.face_names.append(f'{name}({confidence}')缺少闭合括号,改为:self.face_names.append(f'{name}({confidence})') - 空列表防护:在计算人脸距离前,先判断
known_face_encodings是否为空,避免空列表调用np.argmin()出错:if self.known_face_encodings: face_distances = face_recognition.face_distance(self.known_face_encodings, face_encoding) best_match_index = np.argmin(face_distances) if matches[best_match_index]: name = self.known_face_names[best_match_index] confidence = face_confidence(face_distances[best_match_index])
内容的提问来源于stack exchange,提问作者youssef majdalani youssefmaj25
相关产品推荐
相关产品推荐

