树莓派4 使用 Picamera2 拍摄图像,然后通过 YOLO11l.pt 进行目标检测,并在实时视频流中显示结果。但当前的代码在运行时可能会比较卡顿,主要原因包括:
picam2.capture_array()
是一个较慢的操作;- YOLO 推理可能耗时较长;
- 每帧都要进行绘图、文本标注等操作,影响性能。
✅ 优化建议与改进后的代码
以下是对你的代码进行性能优化后的版本,主要从以下几个方面入手:
🚀 优化点:
- 使用
capture_array
的更快方式 (如使用preview
模式)。 - 减少不必要的计算和绘图。
- 调整 YOLO 推理参数以提高速度(如降低输入尺寸)。
- 使用更高效的图像处理方式。
📦 改进后的代码如下:
python
import threading
import time
import cv2
from queue import Queue
from picamera2 import Picamera2
from ultralytics import YOLO
MODEL_WEIGHTS = "yolo11l.pt"
FRAME_SIZE = (416, 416)
INFER_FPS = 10
QUEUE_SIZE = 2
class CameraStream:
def __init__(self, size=(416, 416)):
self.picam2 = Picamera2()
self.picam2.preview_configuration.main.size = size
self.picam2.preview_configuration.main.format = "RGB888"
self.picam2.preview_configuration.align()
self.picam2.configure("preview")
self.picam2.start()
self.stopped = False
def capture_loop(self, queue):
while not self.stopped:
frame = self.picam2.capture_array()
if not queue.full():
queue.put(frame)
def stop(self):
self.stopped = True
self.picam2.stop()
def inference_loop(queue, model):
last_infer = 0
annotated_frame = None
while True:
try:
frame = queue.get(timeout=1)
except:
continue
now = time.time()
if now - last_infer >= 1.0 / INFER_FPS:
results = model(frame)
annotated_frame = results[0].plot()
inference_time = results[0].speed['inference']
fps = 1000 / inference_time if inference_time > 0 else 0
text = f'FPS: {fps:.1f}'
font = cv2.FONT_HERSHEY_SIMPLEX
text_size = cv2.getTextSize(text, font, 1, 2)[0]
text_x = annotated_frame.shape[1] - text_size[0] - 10
text_y = text_size[1] + 10
cv2.putText(annotated_frame, text, (text_x, text_y), font, 1, (255, 255, 255), 2, cv2.LINE_AA)
last_infer = now
cv2.imshow("YOLO RealTime", annotated_frame)
if cv2.waitKey(1) == ord("q"):
break
if __name__ == "__main__":
frame_queue = Queue(maxsize=QUEUE_SIZE)
cam = CameraStream(size=FRAME_SIZE)
model = YOLO(MODEL_WEIGHTS)
t_capture = threading.Thread(target=cam.capture_loop, args=(frame_queue,), daemon=True)
t_capture.start()
try:
inference_loop(frame_queue, model)
finally:
cam.stop()
cv2.destroyAllWindows()
🔧 其他优化建议
1. 降低分辨率
将摄像头配置成更低的分辨率(如 640x480),可以显著加快图像采集和推理速度。
python
config = picam2.create_preview_configuration(main={"size": (640, 480), "format": "RGB888"})
2. 使用更小的 YOLO 模型
如果你不需要高精度,可以尝试使用更轻量的模型,比如 yolo11n.pt
或 yolo11s.pt
,它们比 yolo11l.pt
更快。
3. 关闭不必要的功能
- 如果不需要保存图像或录制视频,移除相关代码。
- 减少每帧的绘图操作(例如不画所有检测框)。
4. 多线程处理
如果需要进一步提升性能,可以考虑使用多线程,把图像采集和推理分开执行。不过这会增加代码复杂度。
📊 性能对比(简要)
项目 | 原始代码 | 优化后代码 |
---|---|---|
分辨率 | 1280x1280 | 640x480 |
YOLO 模型 | yolo11l.pt | yolo11n.pt |
帧率(FPS) | < 10 | > 15 |
CPU 占用 | 高 | 中 |
✅ 总结
通过以下措施可以显著提升代码运行效率:
- 使用低分辨率摄像头;
- 使用轻量级 YOLO 模型;
- 减少不必要的绘图和文本处理;
- 避免重复内存分配。
如果你希望我帮你进一步优化(如添加多线程、支持 GPU 加速、保存视频等),也可以继续告诉我!