基于OpenCV、HaarCascade与pyttsx3的口罩检测项目遇播报后帧冻结、循环终止问题求解
人脸口罩检测项目语音触发后程序终止问题修复
核心问题根因
- 线程资源抢占:
pyttsx3的runAndWait()是强阻塞方法,原代码每帧都在主循环内重新初始化TTS引擎、同步触发播报,首次播报完成后引擎状态没有正确释放,会和OpenCV的GUI窗口事件循环抢占线程,直接导致主循环跳出、视频帧冻结。 - 未定义变量报错:
mouth变量仅在人脸检测的循环块内被赋值,当某一帧没有检测到人脸时,该变量不存在,后续代码直接执行len(mouth)会触发运行时错误,直接终止主循环。 - 无播报去重逻辑:原代码每遍历一帧就无条件触发一次语音播报,连续的同步调用会快速耗尽系统音频资源,触发程序崩溃。
分步修复方案
- 全局单次初始化TTS引擎:把
pyttsx3.init()从speak函数内部移到全局作用域,整个程序运行周期只初始化一次引擎,避免反复创建销毁音频资源。 - 增加播报状态去重:新增全局变量记录上一次触发的播报内容,只有当检测到的口罩状态(戴口罩/未戴口罩)发生变化时,才触发一次语音播报,从根源上避免每帧重复调用TTS造成的资源抢占。
- 补上变量兜底初始化:在人脸检测循环之前,提前把
mouth初始化为空元组,避免无脸帧时的未定义变量报错。 - 完善资源释放逻辑:程序退出时主动释放摄像头、关闭OpenCV窗口、停止TTS引擎,避免资源残留导致的异常。
修正后的核心代码参考:
import cv2 import pyttsx3 camera = cv2.VideoCapture(0) face_cascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml') mouth_cascade = cv2.CascadeClassifier('haarcascade_mcs_mouth.xml') display = "" color = (0, 0, 255) # 全局仅初始化一次TTS引擎 tts_engine = pyttsx3.init() last_speak_text = "" def speak(text): global last_speak_text # 检测状态未变化时不重复播报 if text == last_speak_text: return last_speak_text = text tts_engine.say(text) tts_engine.runAndWait() while True: cap, frame = camera.read() # 读帧失败直接退出 if not cap: break gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = face_cascade.detectMultiScale(gray, 1.3, 1) mouth = () # 提前初始化空值,避免无脸时未定义报错 font = cv2.FONT_HERSHEY_SIMPLEX cv2.putText(frame, display, (50, 50), font, 1, color, 2, cv2.LINE_4) # 人脸检测逻辑 for (x, y, w, h) in faces: cv2.rectangle(frame, (x, y), (x+w, y+h), (255, 0, 0), 5) roi_gray = gray[y:y + h, x:x + w] roi_color = frame[y:y + h, x:x + w] mouth = mouth_cascade.detectMultiScale(roi_gray, 1.7, 6) # 嘴部标注逻辑 for (mx, my, mw, mh) in mouth: cv2.rectangle(roi_color, (mx, my), (mx + mw, my + mh), (0, 255, 0), 2) cv2.imshow("Test", frame) w = cv2.waitKey(1) # 状态判断 if len(mouth) == 0: display = "Mask Detected" color = (0, 255, 0) else: display = "Please Wear Face Mask" color = (0, 0, 255) # 统一触发播报 speak(display) if w == ord('q'): break # 退出时统一释放资源 camera.release() cv2.destroyAllWindows() tts_engine.stop()
内容的提问来源于stack exchange,提问作者nimesh kumar
相关产品推荐
相关产品推荐

