树莓派多进程运行TensorFlow遇阻塞,求可行解决方案
树莓派多进程运行TensorFlow Lite目标检测的阻塞问题解决
问题背景
在树莓派上开发TensorFlow Lite目标检测项目时,将TensorFlow相关代码封装到独立类(主脚本外)并结合多进程运行时,程序会在TensorFlow方法调用处阻塞,无任何报错;但将所有逻辑放在主脚本的进程函数内时可正常运行。需要保留当前项目结构与多进程机制。
问题根源
- TensorFlow Lite对象无法跨进程共享:
ObjectDetector实例基于C++后端实现,无法在多进程间安全序列化/共享,子进程直接访问主进程创建的检测器会导致资源竞争或死锁。 - 相机实例跨进程访问冲突:
Picamera2实例同样不能跨进程共享,子进程直接调用主进程初始化的相机资源会引发底层资源访问冲突。
解决办法
核心思路:让每个子进程独立初始化自己的TensorFlow检测器与相机资源,避免跨进程共享不可序列化的硬件/AI模型资源。
修改后的代码实现
detector.py
from tflite_support.task import core from tflite_support.task import processor from tflite_support.task import vision from multiprocessing import Process import cv2 from picamera2 import Picamera2 from tflite_support.task import utils class Detector: def __init__(self): # 主进程仅初始化进程对象,不创建硬件/AI资源 self._sub_process = None def start_camera_feed(self): # 启动子进程执行检测逻辑 self._sub_process = Process(target=self._init_and_run) self._sub_process.start() def _init_and_run(self): # 子进程内部独立初始化所有资源 dispW = int(1280 / 2) dispH = int(720 / 2) # 初始化相机 picam2 = Picamera2() picam2.preview_configuration.main.size = (dispW, dispH) picam2.preview_configuration.main.format = 'RGB888' picam2.preview_configuration.align() picam2.configure("preview") picam2.start() # 初始化TensorFlow Lite检测器 model = "efficientdet_lite0.tflite" numThreads = 4 base_options = core.BaseOptions(file_name=model, use_coral=False, num_threads=numThreads) detection_options = processor.DetectionOptions(max_results=3, score_threshold=0.5) options = vision.ObjectDetectorOptions(base_options=base_options, detection_options=detection_options) detector = vision.ObjectDetector.create_from_options(options) # 启动检测循环 self._detection_loop(picam2, detector) def _detection_loop(self, picam2, detector): iterator = 0 while True: # 获取相机帧 im = picam2.capture_array() im = cv2.flip(im, -1) # 图像格式转换与检测 im_rgb = cv2.cvtColor(im, cv2.COLOR_BGR2RGB) im_tensor = vision.TensorImage.create_from_array(im_rgb) detections = detector.detect(im_tensor) annotated_image = utils.visualize(im, detections) # 显示结果 cv2.imshow('Camera', annotated_image) if cv2.waitKey(1) == ord('q'): break iterator += 1 if iterator == 100: break # 释放资源 cv2.destroyAllWindows() picam2.stop()
main.py
from detector import Detector detector = Detector() detector.start_camera_feed()
额外注意事项
- 进程资源释放:子进程退出时必须手动停止相机、销毁OpenCV窗口,避免树莓派硬件资源泄漏。
- 进程间通信(可选):如果需要将检测结果传递到主进程,可使用
multiprocessing.Queue,传递的数据需为可序列化格式(如字典、列表),不能直接传递TensorFlow或相机相关对象。 - 树莓派环境优化:确保TensorFlow Lite已针对ARM架构优化,可通过
pip install tflite-support[rpi]安装适配版本,提升检测性能。
内容的提问来源于stack exchange,提问作者Siggerud
相关产品推荐
相关产品推荐

