You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python多线程情绪识别代码报错:TypeError - NoneType无len()方法

问题分析与修复

错误根源

  1. 变量名写错:多线程代码里把cap.read()的返回值变量写成了result, frame,正确写法是ret, frame——cap.read()返回的是(读取成功标识, 视频帧),你把成功标识命名成result,导致后续的frame实际为None,传给DeepFace.analyze后自然抛出NoneType相关错误。
  2. 主线程提前释放资源:主线程启动子线程后立刻执行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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 06:54:06