Python多线程情绪识别代码报错:TypeError - NoneType无len()方法
问题分析与修复
错误根源
- 变量名写错:多线程代码里把
cap.read()的返回值变量写成了result, frame,正确写法是ret, frame——cap.read()返回的是(读取成功标识, 视频帧),你把成功标识命名成result,导致后续的frame实际为None,传给DeepFace.analyze后自然抛出NoneType相关错误。 - 主线程提前释放资源:主线程启动子线程后立刻执行
cap.release()和cv2.destroyAllWindows(),此时子线程还未开始读取摄像头,资源就被释放,必然导致读取失败。
修复后的多线程代码(支持情绪传递)
用Queue实现线程安全的情绪传递,子线程识别出情绪后放入队列,其他函数可从队列取数据执行对应逻辑:
import numpy as np import time from threading import Thread from queue import Queue from cv2 import LINE_4 import cv2 from deepface import DeepFace faceCascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml') cap = cv2.VideoCapture(1) if not cap.isOpened(): cap = cv2.VideoCapture(0) if not cap.isOpened(): raise IOError("无法打开摄像头") # 线程安全队列,用于传递识别出的情绪 emotion_queue = Queue() def emotion_recog(): while True: ret, frame = cap.read() if not ret: print("读取摄像头帧失败") break # 分析情绪 result = DeepFace.analyze(frame, actions=['emotion'], enforce_detection=False) dominant_emotion = result['dominant_emotion'] # 将情绪放入队列,供其他函数调用 emotion_queue.put(dominant_emotion) # 绘制人脸框与情绪文字 gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = faceCascade.detectMultiScale(gray, 1.1, 4) for (x, y, w, h) in faces: cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2) font = cv2.FONT_HERSHEY_SIMPLEX cv2.putText(frame, dominant_emotion, (50, 50), font, 3, (0, 0, 255), 2, LINE_4) cv2.imshow('实时情绪识别', frame) # 按下q键退出循环 if cv2.waitKey(2) & 0xFF == ord('q'): # 放入结束标识,通知处理线程退出 emotion_queue.put(None) break def process_emotion(): """处理识别情绪的示例函数,可根据需求修改逻辑""" while True: emotion = emotion_queue.get() if emotion is None: break # 这里写情绪对应的业务逻辑 print(f"当前识别情绪:{emotion},执行对应操作...") time.sleep(0.5) # 启动线程 t_recog = Thread(target=emotion_recog) t_process = Thread(target=process_emotion) t_recog.start() t_process.start() # 等待线程执行完毕 t_recog.join() t_process.join() # 最后释放资源 cap.release() cv2.destroyAllWindows()
关键修改说明
- 修正
cap.read()的变量名,确保frame为有效视频帧 - 用
Queue实现线程安全的情绪传递,避免多线程共享变量冲突 - 主线程等待子线程执行完成后再释放资源,解决提前释放问题
- 新增
process_emotion示例函数,展示如何接收并处理识别出的情绪 - 增加帧读取失败判断,提升代码健壮性
内容的提问来源于stack exchange,提问作者Fahad Khan
相关产品推荐
相关产品推荐

