树莓派4B(64位Bookworm)+Pi Camera v3 OpenCV帧捕获失败求助
树莓派4B Bookworm 64位 + Pi Camera v3 实时目标检测解决方案
问题根源
Raspbian Bookworm默认启用libcamera相机堆栈,替代了传统的V4L2框架。你使用的OpenCV默认VideoCapture后端不兼容libcamera的虚拟视频节点,导致无法捕获帧;而rpicam命令基于libcamera开发,因此可以正常工作。
解决方案:PiCamera2 + TF Lite Runtime(推荐)
PiCamera2是官方为Bookworm推出的相机库,完美适配libcamera堆栈,配合TF Lite Runtime可以实现无加速器的实时目标检测。
1. 环境准备
# 更新系统 sudo apt update && sudo apt upgrade -y # 创建并激活虚拟环境 python3 -m venv .venv source .venv/bin/activate # 安装依赖 pip install picamera2 opencv-python numpy tflite-runtime
2. 测试PiCamera2相机捕获
创建测试脚本test_picam2.py:
from picamera2 import Picamera2 import cv2 import numpy as np picam2 = Picamera2() # 配置相机分辨率(可根据需求调整) config = picam2.create_preview_configuration(main={"size": (640, 480)}) picam2.configure(config) picam2.start() while True: # 获取RGB格式帧,转换为OpenCV兼容的BGR格式 frame_rgb = picam2.capture_array() frame_bgr = cv2.cvtColor(frame_rgb, cv2.COLOR_RGB2BGR) cv2.imshow("Camera Test", frame_bgr) if cv2.waitKey(1) & 0xFF == ord('q'): break picam2.stop() cv2.destroyAllWindows()
运行脚本:python3 test_picam2.py,如果正常显示画面,说明相机配置没问题。
若之前PiCamera2报错numpy,执行pip install --upgrade numpy更新依赖即可。
3. 整合TF Lite实时目标检测
步骤1:下载测试模型(或替换为你的自定义模型)
# 下载预训练量化模型和标签 wget https://storage.googleapis.com/download.tensorflow.org/models/tflite/task_library/object_detection/rpi/lite-model_ssd_mobilenet_v2_object_detector_quant_3_default_1.tflite wget https://storage.googleapis.com/download.tensorflow.org/models/tflite/task_library/object_detection/rpi/labelmap.txt
步骤2:编写检测脚本object_detection.py
from picamera2 import Picamera2 import cv2 import numpy as np import tflite_runtime.interpreter as tflite # 模型和标签路径 MODEL_PATH = "lite-model_ssd_mobilenet_v2_object_detector_quant_3_default_1.tflite" LABEL_PATH = "labelmap.txt" # 加载标签 with open(LABEL_PATH, 'r') as f: labels = [line.strip() for line in f.readlines()] # 初始化TF Lite解释器 interpreter = tflite.Interpreter(model_path=MODEL_PATH) interpreter.allocate_tensors() # 获取输入输出张量信息 input_details = interpreter.get_input_details() output_details = interpreter.get_output_details() INPUT_WIDTH = input_details[0]['shape'][2] INPUT_HEIGHT = input_details[0]['shape'][1] # 初始化相机 picam2 = Picamera2() config = picam2.create_preview_configuration(main={"size": (INPUT_WIDTH, INPUT_HEIGHT)}) picam2.configure(config) picam2.start() # 检测置信度阈值 THRESHOLD = 0.5 while True: # 获取帧并转换格式 frame_rgb = picam2.capture_array() frame_bgr = cv2.cvtColor(frame_rgb, cv2.COLOR_RGB2BGR) # 预处理输入帧(量化模型需转为uint8) input_data = cv2.resize(frame_rgb, (INPUT_WIDTH, INPUT_HEIGHT)) input_data = np.expand_dims(input_data, axis=0) input_data = np.uint8(input_data) # 运行推理 interpreter.set_tensor(input_details[0]['index'], input_data) interpreter.invoke() # 解析输出结果 boxes = interpreter.get_tensor(output_details[0]['index'])[0] classes = interpreter.get_tensor(output_details[1]['index'])[0] scores = interpreter.get_tensor(output_details[2]['index'])[0] # 绘制检测框 for i in range(len(scores)): if scores[i] > THRESHOLD: # 转换坐标到帧尺寸 ymin = int(max(1, boxes[i][0] * INPUT_HEIGHT)) xmin = int(max(1, boxes[i][1] * INPUT_WIDTH)) ymax = int(min(INPUT_HEIGHT, boxes[i][2] * INPUT_HEIGHT)) xmax = int(min(INPUT_WIDTH, boxes[i][3] * INPUT_WIDTH)) # 绘制矩形和标签 cv2.rectangle(frame_bgr, (xmin, ymin), (xmax, ymax), (0, 255, 0), 2) label = f"{labels[int(classes[i])]}: {int(scores[i]*100)}%" cv2.putText(frame_bgr, label, (xmin, ymin-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 2) cv2.imshow("Real-time Object Detection", frame_bgr) if cv2.waitKey(1) & 0xFF == ord('q'): break picam2.stop() cv2.destroyAllWindows()
步骤3:运行检测脚本
python3 object_detection.py
4. 自定义模型部署
若使用自己训练的自定义TF Lite模型:
- 确保模型输入尺寸、数据类型与脚本匹配(如浮点模型需将
input_data转为float32并做归一化:input_data = np.float32(input_data) / 255.0) - 替换
MODEL_PATH和LABEL_PATH为你的模型和标签文件路径
备选方案:修复OpenCV相机捕获
若坚持使用OpenCV,需指定libcamera后端初始化VideoCapture:
import cv2 cap = cv2.VideoCapture(0, cv2.CAP_LIBCAMERA) cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480) while True: ret, frame = cap.read() if not ret: print("Failed to capture frame") break cv2.imshow("Camera", frame) if cv2.waitKey(1) & 0xFF == ord('q'): break cap.release() cv2.destroyAllWindows()
注:该方案依赖OpenCV编译时包含libcamera支持,Bookworm官方源的opencv-python已支持,但兼容性不如PiCamera2。
内容的提问来源于stack exchange,提问作者Mehmet Akif Aydemir
相关产品推荐
相关产品推荐

