Jetson Orin Nano上的实时推理部署

边缘计算领域,NVIDIA Jetson Orin Nano是一个强大的设备,它能够处理复杂的计算机视觉任务,如实时视频流分析。通过使用Roboflow的推理管道,可以将深度学习模型部署到这个设备上,实现高效的实时推理。这种部署方式不仅能够减少延迟,还能在不牺牲性能的前提下,处理大量的视频数据。

首先,确保Jetson设备已经安装了Jetpack 5.1.1。可以通过下载Jetson Orin Nano开发者套件的SD卡镜像,并按照NVIDIA的指导将镜像写入microSD卡来完成这一步骤。启动设备后,可以通过运行一个简单的脚本来验证Jetpack是否正确安装。此外,为了充分利用NVIDIA GPU的能力,还需要安装正确的库和运行时环境。

#!/bin/bash # 卸载已安装的onnxruntime pip3 uninstall --yes onnxruntime # 下载onnxruntime的wheel文件 wget https://nvidia.box.com/shared/static/v59xkrnvederwewo2f1jtv6yurl92xso.whl -O onnxruntime_gpu-1.12.1-cp38-cp38-linux_aarch64.whl # 安装onnxruntime_gpu和opencv-python pip3 install onnxruntime_gpu-1.12.1-cp38-cp38-linux_aarch64.whl "opencv-python<4.3" # 清理下载的wheel文件和pip缓存 rm -f onnxruntime_gpu-1.12.1-cp38-cp38-linux_aarch64.whl rm -rf ~/.cache/pip # 安装pandas库 pip3 install pandas

使用Roboflow的推理管道,可以轻松地将COCO模型部署到RTSP视频流上。这个管道内置了FPS监控功能,可以跟踪推理的延迟和吞吐量。通过使用Roboflow提供的特殊模型ID,可以方便地获取模型并进行推理。下面是一个使用InferencePipeline的示例代码,它展示了如何将模型部署到RTSP视频流上。

from inference.core.interfaces.stream.inference_pipeline import InferencePipeline from inference.core.interfaces.stream.sinks import render_boxes import supervision as sv # 创建FPS监控实例 fps_monitor = sv.FPSMonitor() # 定义模型别名 REGISTERED_ALIASES = { "yolov8n-640": "coco/3", "yolov8n-1280": "coco/9", "yolov8m-640": "coco/8" } # 示例别名 alias = "yolov8n-640" # 函数:解析模型别名为实际模型ID def resolve_roboflow_model_alias(model_id: str) -> str: return REGISTERED_ALIASES.get(model_id, model_id) # 解析别名获取实际模型ID model_name = resolve_roboflow_model_alias(alias) # 修改render_boxes函数以显示统计信息 def on_prediction(predictions, video_frame): render_boxes( predictions=predictions, video_frame=video_frame, fps_monitor=fps_monitor, display_statistics=True, ) # 初始化推理管道 pipeline = InferencePipeline.init( model_id=model_name, video_reference="RTSP_URL", on_prediction=on_prediction, api_key='API_KEY', confidence=0.5, ) # 启动推理管道 pipeline.start() pipeline.join()

Supervision库提供了强大的功能,可以用于监控特定区域内的对象。例如,可以使用PolygonZone和Bytetrack来测量对象在特定区域内的停留时间。此外,还可以将对象的类别、时间戳以及在区域内的停留时间保存到CSV文件中,以便后续加载到数据库中。

# ByteTrack & Supervision tracker = sv.ByteTrack() annotator = sv.BoxAnnotator() frame_count = defaultdict(int) colors = sv.ColorPalette.default() # 定义感兴趣的多边形区域 polygons = [ np.array([ [390, 543], [1162, 503], [1510, 711], [410, 819], [298, 551], [394, 543] ]) ] # 创建区域、区域注释器和框注释器 zones = [ sv.PolygonZone( polygon=polygon, frame_resolution_wh=[1440, 2560], ) for polygon in polygons ] zone_annotators = [ sv.PolygonZoneAnnotator( zone=zone, color=colors.by_idx(index), thickness=4, text_thickness=8, text_scale=4 ) for index, zone in enumerate(zones) ] box_annotators = [ sv.BoxAnnotator( color=colors.by_idx(index), thickness=4, text_thickness=4, text_scale=2 ) for index in range(len(polygons)) ] # CSV输出的列 columns = ['trackerID', 'class_id', 'frame_count', 'entry_timestamp', 'exit_timestamp', 'time_in_zone'] frame_count_df = pd.DataFrame(columns=columns) # 定义一个字典来存储每个tracker_id的第一个检测时间戳 first_detection_timestamps = {} last_detection_timestamps = {} def render(predictions: dict, video_frame) -> None: detections = sv.Detections.from_roboflow(predictions) detections = tracker.update_with_detections(detections) for zone, zone_annotator, box_annotator in zip(zones, zone_annotators, box_annotators): mask = zone.trigger(detections=detections) detections_filtered = detections[mask] image = box_annotator.annotate(scene=video_frame.image, detections=detections, skip_label=False) image = zone_annotator.annotate(scene=image) for tracker_id, class_id in zip(detections_filtered.tracker_id, detections_filtered.class_id): frame_count[tracker_id] += 1 # 检查tracker_id是否不在first_detection_timestamps中,如果不在,则添加时间戳 if tracker_id not in first_detection_timestamps: first_detection_timestamps[tracker_id] = time.time() last_detection_timestamps[tracker_id] = time.time() time_difference = last_detection_timestamps[tracker_id] - first_detection_timestamps[tracker_id] # 将数据添加到DataFrame中 frame_count_df.loc[tracker_id] = [tracker_id, class_id, frame_count[tracker_id], first_detection_timestamps[tracker_id], last_detection_timestamps[tracker_id], time_difference] frame_count_df.to_csv('demo.csv', index=False) cv2.imshow("Prediction", image) cv2.waitKey(1)

在上面的代码中,定义了一个特定的多边形区域,用于计算区域内对象的数量。多边形的坐标将根据用例而有所不同。要找到适合用例的多边形坐标,可以使用PolygonZone的web助手工具。通过这个工具,可以上传视频的一帧并绘制所需的坐标。注意,必须上传视频的一帧,而不是屏幕截图,因为这个过程对图像分辨率很敏感。可以通过使用OpenCV或Pillow从InferencePipeline中保存一帧来实现这一点。

在NVIDIA Jetson Orin Nano这样的边缘设备上运行RTSP视频流可以扩展实时推理用例,而不会牺牲延迟。在本指南中,介绍了如何使用Roboflow推理服务器在NVIDIA Jetson Orin Nano上运行推理。使用Roboflow推理部署了模型,然后使用Supervision添加了跟踪视频中的车辆并计算交叉口车辆数量的逻辑。

沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485