☰
jetson-inference 实战:用 Flask + REST 打造多模型 WebRTC 交互式 DNN 控制台
2026/9/25 7:06:04 网站建设 项目流程
  • 人工智能
  • 计算机视觉
  • 深度学习
  • 微调

【免费下载链接】jetson-inference

Hello AI World guide to deploying deep-learning inference networks and deep vision primitives with TensorRT and NVIDIA Jetson.

项目地址:https://gitcode.com/gh_mirrors/je/jetson-inference
点击查看免费下载

本篇指南聚焦 jetson-inference 仓库中的 Flask + REST 示例,讲解如何基于 Flask 微框架与 REST JSON 接口构建一个可在浏览器中实时观看、动态切换与调参的多模型深度学习推理控制台。读完本文,你将掌握该 WebApp 的启动方式、多 DNN 模型加载方法、前后端 REST 通信机制与每个模型可调参数的对应端点,并能结合源码理解其底层实现。

Flask 示例概览:Web 前端与 DNN 推理的桥接

Flask 是一个广受欢迎的 Python Web 微框架,负责把 HTTP/HTTPS 请求路由到用户实现的 Python 函数。在这个示例中,Flask 承担了两层职责:一是托管 WebRTC 视频流的页面呈现,二是处理来自前端用户操作的后端 REST 请求,让网页能够在运行时动态控制属性、触发推理内容。

该示例是一个可交互的 DNN "playground":多个视觉模型可以被同时加载并在 WebApp 中自由开关,每种模型的各种设置都可以通过 UI 实时调整:

界面组件使用 Bootstrap CSS 进行样式化。示例的四个核心源文件及其职责如下:

文件职责
python/www/flask/app.pyFlask 主程序:路由、命令行参数、启动服务器与流线程
python/www/flask/stream.pyWebRTC 视频采集/传输与推理调度的后台线程
python/www/flask/model.pyDNN 模型的封装:加载、推理(Process)与可视化(Visualize)
python/www/flask/templates/index.html前端页面:视频播放、模型控制面板的呈现与交互

此外还有两个关键辅助文件:utils.py 提供后端 REST 属性读写工具函数,templates/macros.html 提供渲染控制组件的 Jinja 宏模板。

启动示例:一条命令拉起 WebRTC 流与推理

进入示例目录、安装依赖并启动app.py,它会同时启动 Flask Web 服务器和一条独立运行的流处理线程(负责 WebRTC 的采集、传输与推理):

$ cd jetson-inference/python/www/flask $ pip3 install -r requirements.txt $ python3 app.py --detection=ssd-mobilenet-v2 --pose=resnet18-hand --action=resnet18-kinetics

依赖清单 requirements.txt 中仅包含flask一项,因为其余推理与视频能力(jetson_inference、jetson_utils)来自仓库本体,需按项目 README.md 的构建流程预先安装好 Python 绑定(python/bindings)。

启动后,在浏览器中访问https://<JETSON-IP>:8050即可开始播放/发送流。要点如下:

  • 默认端口 8050:可通过--port=N命令行参数更改(源码见 app.py 第 35 行parser.add_argument("--port", default=8050, ...))。
  • 默认输入输出均为 WebRTC:--input默认值为webrtc://@:8554/input,--output默认值为webrtc://@:8554/output(app.py 第 39-40 行)。
  • 改用其他视频输入:通过--input指定,例如--input=/dev/video0使用直接连接 Jetson 的 V4L2 摄像头,也可传入 CSI 摄像头地址或视频文件,完整输入类型说明见 aux-streaming.md 中 "Input Streams" 一节。
  • 接收浏览器摄像头必须启用 HTTPS/SSL:WebRTC 传输与网页默认走加密通道,详见下文"启用 HTTPS/SSL"一节,以及 webrtc-server.md 的说明。

前端页面会依据是否为 WebRTC 输入自动适配:在 index.html 中,当send_webrtc为真时,页面会在加载时调用checkMediaDevices()枚举浏览器的视频输入设备并填充到 "Webcam" 下拉框,用户点击 Send 即可将本机摄像头经 WebRTC 发送到 Jetson 侧参与推理(该功能需要 HTTPS 才能获取浏览器权限);当输入为本地设备时,页面则直接自动播放已运行的流。

同时加载多种 DNN 模型

该示例支持同时加载并运行多类 DNN 模型:图像分类、目标检测、语义分割、姿态估计、动作识别以及背景移除。启动应用时通过命令行参数选择加载哪些模型:

$ python3 app.py \ --classification=resnet18 \ --detection=ssd-mobilenet-v2 \ --segmentation=fcn-resnet18-mhp \ --pose=resnet18-body \ --action=resnet18-kinetics \ --background=u2net

注意:取决于你的 Jetson 型号与后台进程负载,可能没有足够内存一次加载全部模型,也可能没有足够算力让它们全部实时运行。可以参考 pytorch-transfer-learning.md 中的 "Mounting Swap"(挂载交换分区)与 "Disabling the Desktop GUI"(关闭桌面图形界面)来释放内存。

想要查看内置模型清单,运行python3 app.py --help,或直接查看 data/networks/models.json。--help输出的参数说明由 stream.py 中的usage()汇总而来,它拼接了videoSource、videoOutput与Model.Usage()的帮助文本,后者依次包含imageNet/detectNet/segNet/actionNet/poseNet/backgroundNet的用法说明(model.py 第 150-155 行)。

Model.__init__(model.py 第 31-85 行)按type分派加载不同的网络类:

  • classification→imageNet(可选threshold、smoothing参数);
  • detection→detectNet,若未指定output_layer则默认生成{'scores': '', 'bbox': ''};
  • segmentation→segNet;pose→poseNet;action→actionNet;background→backgroundNet。

模型在页面中以可折叠卡片(card)呈现,每个卡片带一个展开/收起按钮(card_header+collapse_handler宏),卡片内是控制组件的组合。

REST 查询:前端 UI 与后端推理的实时联动

该应用在 webrtc-html.md 所述的基础 WebRTC HTML/JavaScript 流式播放代码之上,叠加了 REST JSON 查询,用于动态更新组件与参数。后端的路由桩代码在 app.py,前端的 JavaScript 查询在 templates/index.html,并通过模板与宏来减少新增设置项时的样板代码。以分类模型为例,完整的"开关 + 阈值调节"实现如下:

# backend - app.py (Python) @app.route('/classification/enabled', methods=['GET', 'PUT']) def classification_enabled(): return rest_property(stream.models['classification'].IsEnabled, stream.models['classification'].SetEnabled, bool) @app.route('/classification/confidence_threshold', methods=['GET', 'PUT']) def classification_confidence_threshold(): return rest_property(stream.models['classification'].net.GetThreshold, stream.models['classification'].net.SetThreshold, float)
<!-- frontend - index.html (Jinja/HTML/JavaScript) --> {{ checkbox('classification_enabled', '/classification/enabled', 'Classification Enabled') }} {{ slider('classification_confidence_threshold', '/classification/confidence_threshold', 'Confidence Threshold') }}

后端:rest_property()的 GET/PUT 语义

utils.py 中的rest_property(getter, setter, type, key=None)封装了读写 REST JSON 属性的全部样板逻辑:

  • GET 请求:调用getter()取值,若传入了key则取返回字典中的该键,最后flask.jsonify(value)序列化为 JSON 返回给前端;
  • PUT 请求:用type(flask.request.get_json())把请求体 JSON 强制转换为目标类型(如bool、float、int),若有key则setter(**{key: value}),否则setter(value),随后返回 HTTP 200;
  • 每次请求都会在 Jetson 终端打印一行日志:<客户端IP> - - REST <方法> <路径> => <值>。

检测模型的追踪参数(minFrames、dropFrames、overlapThreshold)就利用了key参数:rest_property(GetTrackingParams, SetTrackingParams, int, key='minFrames')(app.py 第 105-115 行),实现对同一个字典参数对象中不同键的单独读写。

前端:Jinja 宏与 fetch 客户端

index.html 中的{{ ... }}是 Jinja 模板表达式,由 Flask 在服务端渲染页面时求值,用于按命令行参数动态生成模型卡片。具体控件由 macros.html 提供:

  • slider(id, rest_path, label, min, max, step, oninput):生成 range 滑块,get_<id>()通过rest_get()拉取当前值回填,oninput事件经debounce触发rest_put()把新值推送到后端;step < 1时显示值会格式化为两位小数;
  • checkbox(id, rest_path, label, oninput):生成开关,同样封装了rest_get/rest_put与初始回填;
  • card_header/collapse_handler:生成 Bootstrap 折叠卡片头与事件处理。

前端 REST 客户端由 static/rest.js 实现,基于原生fetchAPI:rest_get(url)返回解析后的 JSON,rest_put(url, data)以PUT方法发送JSON.stringify(data)并设置Content-type: application/json; charset=UTF-8请求头。滑块拖拽时还借助 static/debounce.js 做防抖,避免高频 PUT 请求压垮后端。

各模型的可调参数与 REST 端点一览

app.py 为每类模型按命令行参数动态注册路由(只有加载了对应模型才会注册对应端点),完整端点映射如下:

分类(--classification,imageNet)

  • GET/PUT /classification/enabled→IsEnabled/SetEnabled(bool)
  • GET/PUT /classification/confidence_threshold→GetThreshold/SetThreshold(float)
  • GET/PUT /classification/output_smoothing→GetSmoothing/SetSmoothing(float)

目标检测(--detection,detectNet)

  • GET/PUT /detection/enabled
  • GET/PUT /detection/confidence_threshold→GetConfidenceThreshold/SetConfidenceThreshold
  • GET/PUT /detection/clustering_threshold→GetClusteringThreshold/SetClusteringThreshold
  • GET/PUT /detection/overlay_alpha→GetOverlayAlpha/SetOverlayAlpha(float,前端滑块范围 0-255、步长 1)
  • GET/PUT /detection/tracking_enabled→IsTrackingEnabled/SetTrackingEnabled(bool,开启后前端才会显示下方三个追踪参数滑块)
  • GET/PUT /detection/tracking_min_frames→GetTrackingParams/SetTrackingParams,key=minFrames(int,滑块 0-60)
  • GET/PUT /detection/tracking_drop_frames→ 同上,key=dropFrames(int,滑块 0-60)
  • GET/PUT /detection/tracking_overlap_threshold→ 同上,key=overlapThreshold

语义分割(--segmentation,segNet)

  • GET/PUT /segmentation/enabled
  • GET/PUT /segmentation/overlay_alpha→GetOverlayAlpha/SetOverlayAlpha(float,滑块 0-255)

姿态估计(--pose,poseNet)

  • GET/PUT /pose/enabled
  • GET/PUT /pose/confidence_threshold→GetThreshold/SetThreshold(float)

动作识别(--action,actionNet)

  • GET/PUT /action/enabled
  • GET/PUT /action/confidence_threshold→GetThreshold/SetThreshold
  • GET/PUT /action/skip_frames→GetSkipFrames/SetSkipFrames(int,滑块 0-30)

背景移除(--background,backgroundNet)

  • GET/PUT /background/enabled

前端 index.html 中每种模型的卡片都只在对应模型被加载(模板变量非空)时才渲染,例如分类卡片的Confidence Threshold滑块默认min=0.0, max=1.0, step=0.01,检测的Overlay Alpha与分割的Overlay Alpha则显式指定min=0, max=255, step=1。

推理管线:流线程如何逐帧运行模型

stream.py 的Stream继承threading.Thread,构造时通过videoSource(args.input)与videoOutput(args.output)创建输入输出(源码见 stream.py 第 42-43 行)。它按背景→分割→分类→检测→姿态→动作的顺序维护self.models字典——该顺序即叠加层(overlay)的合成顺序,保证背景移除与分割结果先绘制、文本类标注最后叠加。

主循环process()每帧执行四步(第 68-84 行):

  1. self.input.Capture()采集一帧图像;
  2. 对每个模型调用model.Process(img)执行推理;
  3. 对每个模型调用model.Visualize(img)绘制结果(检测的检测框、分割的类别着色、姿态的关键点/骨架连线、分类与动作的文本标签等);
  4. self.output.Render(img)把合成结果编码输出。

同时每 25 帧在终端打印一次统计:captured N frames from <input> => <output> (W x H)。app.py在定义完所有路由后调用stream.start()启动该线程,再以app.run(host=args.host, port=args.port, ssl_context=ssl_context, debug=True, use_reloader=False)启动 Web 服务器(app.py 第 155-164 行),--host默认0.0.0.0即绑定所有网卡接口。

加载自定义模型

除内置预训练模型外,app.py还支持加载用户自有的自定义模型,相关命令行参数如下(app.py 第 47-50 行):

  • --labels:labels.txt 路径(类别标签);
  • --colors:colors.txt 路径(类别着色,用于检测/分割);
  • --input-layer:模型输入层名称;
  • --output-layer:输出层名称,多个以逗号分隔。

这些参数会透传给 model.py 的Model.__init__:例如检测模型要求output_layer必须能拆出scores与bbox两个 key(传入字符串时按逗号拆分为前两个元素),否则抛出ValueError(model.py 第 58-73 行)。自定义模型对应的标签与着色文件需要与 data/networks/models.json 中登记的内置条目保持相同的格式约定。

启用 HTTPS / SSL

接收浏览器摄像头、以及在公网场景下传输 WebRTC 流与网页内容,官方均推荐启用 HTTPS 加密(详细背景见 webrtc-server.md 的 "Enabling HTTPS / SSL" 一节)。首先生成自签名证书:

$ cd jetson-inference/data $ openssl req -x509 -newkey rsa:4096 -keyout key.pem -out cert.pem -sha256 -days 365 -nodes -subj '/CN=localhost' $ export SSL_KEY=/jetson-inference/data/key.pem $ export SSL_CERT=/jetson-inference/data/cert.pem

当设置$SSL_KEY与$SSL_CERT环境变量后,本仓库的应用会自动启用 HTTPS。若不想用环境变量,也可以在启动 Flask 示例时显式传入命令行参数:

$ python3 app.py --ssl-key=key.pem --ssl-cert=cert.pem --detection=ssd-mobilenet-v2

app.py 中--ssl-key与--ssl-cert的默认值正是从环境变量SSL_KEY/SSL_CERT读取(第 36-37 行),并在第 160-161 行将二者组合为ssl_context传给app.run()。注意:首次用自签名证书访问页面时浏览器会提示安全警告,选择继续访问即可;证书可存放在任意路径,若使用 Docker 容器则建议放在data/目录下,因为它会挂载回宿主机,容器退出后证书依然保留。

延伸阅读

  • webrtc-html.md:上一节的纯 HTML/JavaScript 前端,本示例的流式播放代码基础;
  • webrtc-dash.md:下一节基于 Plotly 的仪表盘变体(python/www/dash),同样是 WebApp 框架系列;
  • webrtc-server.md:WebRTC 服务器的发送/接收/全双工模式与 HTTPS 配置;
  • aux-streaming.md:videoSource/videoOutput支持的各类视频流输入输出;
  • python/examples:仓库提供的一组可运行 Python 示例,便于对比控制台与 Web 两种推理形态。
  • 人工智能
  • 计算机视觉
  • 深度学习
  • 微调

【免费下载链接】jetson-inference

Hello AI World guide to deploying deep-learning inference networks and deep vision primitives with TensorRT and NVIDIA Jetson.

项目地址:https://gitcode.com/gh_mirrors/je/jetson-inference
点击查看免费下载

相关推荐

上一篇:mkdocstrings 性能优化:10个技巧让你的文档构建速度提升3倍
下一篇:推荐开源项目:Asp.Net-Core-Inventory-Order-Management-System

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询