基于OpenCV的人脸识别程序运行后意外闪退问题求助
问题:OpenCV人脸识别程序启动摄像头后闪退,报错0xC0000005
程序启动摄像头后立刻停止运行,报错信息:
Process finished with exit code -1073741819 (0xC0000005)
(翻译:内存访问冲突,通常是非法内存读写导致的程序崩溃)
以下是我的代码:
import cv2 as cv import numpy as np import face_recognition import os, sys from datetime import datetime import datetime as dt import math def face_conf (face_distance, face_match_threshold=0.6): range = (1.0 - face_match_threshold) linear_val = (1.0 - face_distance) / (range * 2.0) if face_distance > face_match_threshold: return str(round(linear_val * 100, 2)) + '%' else: value = (linear_val + ((1.0 - linear_val) * math.pow((linear_val - 0.5) * 2, 0.2 ) )) * 100 return str (round(value, 2)) + '%' def markAttendance(name): with open ('FaceAttendance.csv','r+') as f: myList = f.readlines() nameList = [] for line in myList: entry = line.split(',') nameList.append(entry[0]) if name not in nameList: now = datetime.now() current_date = now.strftime('%B-%d-%Y') time_arr = dt.time(10, 30, 00) dateString = now.strftime('%H:%M:%S') time_arr_string = time_arr.strftime('%H:%M:%S') status_late = ('LATE') status_present = ('PRESENT') if dateString > time_arr_string: f.writelines(f'\n{name}, {dateString}, {current_date}, {status_late}') elif dateString < time_arr_string: f.writelines(f'\n{name}, {dateString}, {current_date}, {status_present}') markAttendance('Attendance Start: ') class FaceRecognition: face_locations = [] face_encodings = [] face_names = [] knownFaceEncodings = [] knownFaceNames = [] process_current_frame = True def __init__(self): self.encode_faces() def encode_faces(self): for img in os.listdir('Attendance'): face_image = face_recognition.load_image_file(f'Attendance/{img}') face_encoding = face_recognition.face_encodings(face_image)[0] self.knownFaceEncodings.append(face_encoding) self.knownFaceNames.append(os.path.splitext(img)[0]) print(self.knownFaceNames) def run_recognition(self): video_cap = cv.VideoCapture(0) if not video_cap.isOpened(): sys.exit('Error: Video Not Found!') while True: ret, frame = video_cap.read() if self.process_current_frame: small_frame = cv.resize(frame, (0,0), fx=0.25, fy=0.25) rgb_small_frame = small_frame [:, :, ::-1] #Find the face in current frame self.face_locations = face_recognition.face_locations(rgb_small_frame) self.face_encodings = face_recognition.face_encodings(rgb_small_frame, self.face_locations) self.face_names = [] for face_encoding in self.face_encodings: matches = face_recognition.compare_faces(self.knownFaceEncodings, face_encoding) name = 'Unknown' confidence = 'Unknown' face_distances = face_recognition.face_distance(self.knownFaceEncodings, face_encoding) matchIndex = np.argmin(face_distances) if matches[matchIndex]: name = self.knownFaceNames[matchIndex] confidence = face_conf(face_distances[matchIndex]) markAttendance(name) self.face_names.append(f'{name} ({confidence})') self.process_current_frame = not self.process_current_frame #display annotations for (top, right, bottom, left), name in zip (self.face_locations, self.face_names): top *=4 right *= 4 bottom *= 4 left *= 4 cv.rectangle (frame, (left, top), (right, bottom), (0, 255, 0), 2) cv.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 255, 0), -1) cv.putText(frame, name, (left + 6, bottom - 6), cv.FONT_HERSHEY_COMPLEX, .75, (255, 255, 255), 2) cv.imshow ('Face Recognition', frame) if cv.waitKey(1) & 0xFF == ord('s'): break video_cap.release() cv.destroyAllWindows() if __name__ == '__main__': fr = FaceRecognition() fr.run_recognition()
解决方案
错误码0xC0000005是Windows系统的内存访问冲突,核心原因是程序尝试读写非法内存区域。针对你的代码,以下是具体修复点:
1. 修复人脸编码的索引越界问题
face_recognition.face_encodings(face_image)[0]直接取索引0,如果图片中没有检测到人脸,会抛出索引错误并导致崩溃。修改encode_faces方法:
def encode_faces(self): for img in os.listdir('Attendance'): face_image = face_recognition.load_image_file(f'Attendance/{img}') face_encodings = face_recognition.face_encodings(face_image) if face_encodings: # 确保检测到人脸 face_encoding = face_encodings[0] self.knownFaceEncodings.append(face_encoding) self.knownFaceNames.append(os.path.splitext(img)[0]) else: print(f"Warning: No face detected in image {img}") print(self.knownFaceNames)
2. 检查摄像头帧读取有效性
如果摄像头读取失败(ret为False),frame是空值,后续resize操作会触发内存错误。在处理前加判断:
while True: ret, frame = video_cap.read() if not ret: print("Failed to read frame from camera") break # 或添加重试逻辑 if self.process_current_frame: # 后续处理代码...
3. 将类属性改为实例属性
你的FaceRecognition类中,face_locations、face_encodings等是类级属性,所有实例共享,可能在帧处理时引发并发冲突。改为实例属性:
class FaceRecognition: def __init__(self): # 初始化实例属性 self.face_locations = [] self.face_encodings = [] self.face_names = [] self.knownFaceEncodings = [] self.knownFaceNames = [] self.process_current_frame = True self.encode_faces()
4. 修复考勤文件的异常处理
如果FaceAttendance.csv不存在,open('FaceAttendance.csv','r+')会报错。修改markAttendance函数,确保文件存在:
def markAttendance(name): # 先检查文件是否存在,不存在则创建并写入表头 if not os.path.exists('FaceAttendance.csv'): with open('FaceAttendance.csv', 'w') as f: f.write('Name,Time,Date,Status\n') with open('FaceAttendance.csv','r+') as f: myList = f.readlines() nameList = [] for line in myList: entry = line.strip().split(',') if entry: # 避免空行导致索引错误 nameList.append(entry[0]) if name not in nameList: now = datetime.now() current_date = now.strftime('%B-%d-%Y') time_arr = dt.time(10, 30, 00) dateString = now.strftime('%H:%M:%S') time_arr_string = time_arr.strftime('%H:%M:%S') status_late = 'LATE' status_present = 'PRESENT' if dateString > time_arr_string: f.writelines(f'\n{name}, {dateString}, {current_date}, {status_late}') else: # 补充等于时间点的情况 f.writelines(f'\n{name}, {dateString}, {current_date}, {status_present}')
5. 排查依赖库版本兼容性
Windows下face_recognition依赖的dlib库容易出现版本不兼容问题,建议:
- 卸载现有库:
pip uninstall opencv-python face-recognition numpy dlib - 重新安装兼容版本:
pip install opencv-python face-recognition numpy(让pip自动匹配兼容版本) - 若仍有问题,手动安装对应Python版本和系统架构的预编译dlib包
内容的提问来源于stack exchange,提问作者Ecn Nllr
相关产品推荐
相关产品推荐

