树莓派3B+基于Python3实现TFlite口罩识别触发TypeError问题求解
问题原因
- 核心错误是TFLite预测结果的取值逻辑错误,导致后续迭代时
pred为单个浮点值,无法解包为mask和withoutMask两个变量。
原来的Keras模型predict返回的是形状为(人脸数量, 2)的数组,每个元素对应单个人脸的「戴口罩概率、未戴口罩概率」。但你的代码中获取TFLite输出时加了[0],直接取出了第一个人脸的预测结果(形状为(2,)的数组),并将其赋值给preds变量。
后续执行for (box, pred) in zip(locs, preds)时,会把长度为2的预测数组拆成两个单独的浮点值迭代,第一次循环的pred就是单个float32类型的概率值,尝试解包为两个变量就触发了报错。 - 次要问题:代码中存在未定义的变量
sw2Press,运行到对应逻辑会触发新的报错;detect_and_predict_mask函数中每次调用都执行interpreter.allocate_tensors()属于冗余操作,会拖慢树莓派上的运行效率;检测到人脸后执行time.sleep(2)甚至直接sys.exit(),会导致程序卡住或直接退出。
修复方案
- 修正TFLite输出获取逻辑
找到detect_and_predict_mask函数中的以下代码:
preds = interpreter.tensor(interpreter.get_output_details()[0]["index"])()[0]
删除末尾的[0],修改为:
preds = interpreter.tensor(interpreter.get_output_details()[0]["index"])()
- 优化TFLite初始化逻辑
把interpreter.allocate_tensors()从detect_and_predict_mask函数中移出,放在模型加载的位置只初始化一次:
找到加载TFLite模型的代码段:
#maskNet = load_model("facemask_model.model") interpreter = tf.lite.Interpreter("facemask_model.tflite")
修改为:
#maskNet = load_model("facemask_model.model") interpreter = tf.lite.Interpreter("facemask_model.tflite") interpreter.allocate_tensors() # 移到此处,仅初始化一次
之后删除detect_and_predict_mask函数里的interpreter.allocate_tensors()行即可。
- 修复冗余/错误逻辑
- 代码中
sys.exit() if sw2Press else buzzer.off()行的sw2Press未定义,如果不需要按钮退出功能直接删除该行即可,需要的话先补充对应按钮的初始化代码。 - 检测到人脸后的
time.sleep(2)会阻塞视频流处理,不需要可以直接删除。 - 逻辑行
buzzer.beep(0.1, 0.1, 1) if mask > withoutMask else led.off()的else分支逻辑错误,不需要LED操作的话可以改成else buzzer.off()。
内容的提问来源于stack exchange,提问作者sya
相关产品推荐
相关产品推荐

