[具身智能-634]:Python 封装的地平线 VIO 多媒体库:libsrcampy库详解
srcampy /libsrcampy 名称释义
先明确结论: 官方文档没有公布标准化英文全称,是地平线内部项目缩写;行业公认拆解如下:
srcampy = Source Amplifier Python binding
- src = Source(图像源:MIPI Sensor、视频源)
- amp = Amplifier(引申:VSP/VPU 图像信号处理流水线 ISP 放大器通道;内部代号
AMP,指代地平线多媒体图像流水线)- py = Python binding(C 库对外 Python 封装)
底层库文件名:libsrcamp.so,Python 封装后命名
libsrcampy,代码内导入别名srcampy。补充背景(RDK 平台内部代号)
地平线 RDK X3/X5 多媒体驱动内部存在 AMP Pipeline: AMP = Advanced Multimedia Pipeline(高级多媒体流水线) 负责:MIPI 接收 → ISP 处理 → 多路缩放 → 编码 → 显示通路。 这是
amp词根真正来源。完整合理全称: Source Advanced Multimedia Pipeline Python API 中文理解:图像源多媒体流水线 Python 接口库。
不要混淆
- 和音频 amplifier 功放无关;属于图像 ISP 流水线代号;
- 不是
Sample、Stream之类缩写;- 区分:
libsrcamp.so:原生 C 多媒体库libsrcampy.so:C 库 + Python 包装层 → 代码from hobot_vio import libsrcampy极简一句话记忆
src(图像源) + amp(多媒体流水线 AMP) + py(Python 封装) = srcampy
顺带区分配套名词方便你整体理解:
- hobot_vio:VIO = Video Input Output(视频输入输出,包名)
- libsrcampy:VIO 包里面负责操控摄像头、HDMI、硬件数据流绑定的核心模块。
srcampy(libsrcampy)完整详解
一、基础定位
python
运行
try:
from hobot_vio import libsrcampy as srcampy
except ImportError:
from hobot_vio_rdkx5 import libsrcampy as srcampy
- 全称:
libsrcampy,Python 封装的地平线 VIO 多媒体库 - 平台区分
- RDK X3:包名
hobot_vio - RDK X5:包名
hobot_vio_rdkx5
- RDK X3:包名
- 核心用途 专门操控 MIPI CSI 摄像头、ISP 图像流水线、HDMI 显示、硬件绑定数据流、OSD 图层叠加
- ⚠️最重要区别:
- 只用于板载 MIPI 相机,不用于 USB 摄像头
- 不兼容标准 V4L2 /cv2.VideoCapture;不要混用!
- 底层调用地平线自研 ISP 驱动,不是 Linux 通用 uvc 驱动
底层硬件流水线(FCOS 代码的完整链路)
plaintext
MIPI Sensor → ISP硬件流水线(VPS) → 多路硬件缩放输出
├─通路A:原始分辨率 → 直通HDMI
└─通路B:模型输入尺寸(NV12) → Python读取送给BPU推理
所有缩放、格式转换由硬件 ISP 完成,几乎不占用 CPU。
二、srcampy 四大核心类
Camera / Display / Encoder / Decoder FCOS 代码只用到前两个。
1. srcampy.Camera () — MIPI 摄像头采集类
1.1 cam.open_cam () 【重中之重】
函数原型(RDK X5 标准)
python
运行
cam.open_cam(video_index, fps, [out_w1, out_w2], [out_h1, out_h2], sensor_h, sensor_w)
对应你代码:
python
运行
cam.open_cam(0, -1, -1, [w, disp_w], [h, disp_h], sensor_height,sensor_width)
逐个参数拆解(RDK X5 专属规则)
表格
| 参数 | 含义 | 说明 |
|---|---|---|
video_index | MIPI CSI 硬件通道 ID | CSI0 → 0;CSI1 → 2(不是 1!) |
fps | 帧率 | -1 = 使用传感器默认帧率(通常 30fps) |
[out_w1, out_w2] | 两路输出宽度数组 | ISP硬件双通路输出 |
[out_h1, out_h2] | 两路输出高度数组 | 通路 1:模型输入尺寸;通路 2:HDMI 预览尺寸 |
sensor_h / sensor_w | Sensor 原生分辨率 | IMX415/IMX477 常用:1080/1920 |
双通路含义: ISP 硬件同时生成两张 NV12 图像:
- 通路 1:
w × h(512×512)→ 送给 FCOS 模型推理 - 通路 2:
disp_w × disp_h(1920×1080)→ 送到 HDMI 实时预览 全程硬件缩放,无 CPU 图像 resize!
1.2 cam.get_img()
python
运行
img = cam.get_img(2, 512, 512)
- 参数 1:图像格式编号,2 = NV12(模型需要的格式)
- 参数 2/3:读取哪一路通路的分辨率
- 返回值:bytes 裸缓冲区,NV12 内存数据
python
运行
# 转为numpy数组
img = np.frombuffer(img, dtype=np.uint8)
✅巨大优势: 拿到直接可用的 NV12,不需要运行 bgr2nv12_opencv(),省去大量 CPU 运算。
1.3 cam.close_cam()
释放 ISP、MIPI 通道资源;程序退出必须调用,否则下次打开摄像头失败。
1.4 常见坑
- CSI1 通道必须写
video_index=2,填 1 直接识别不到摄像头 open_cam两路分辨率顺序必须和get_img匹配- 不能同时用 srcampy + v4l2-ctl/cv2.VideoCapture 读取同一个 CSI 通道,驱动互斥抢占
2. srcampy.Display () — HDMI 显示 & OSD 图层类
2.1 disp.display(layer_id, w, h)
切换显示图层
python
运行
# layer 0:原始视频画面图层(摄像头直通画面)
disp.display(0, disp_w, disp_h)
# layer 3:OSD图形叠加图层(绘制框、文字)
disp.display(3, disp_w, disp_h)
图层规则:
- Layer0:原始视频流
- Layer3:OSD 叠加层(透明图层,用于绘制检测框)
OSD 图层不会修改原始视频流,只是硬件叠加渲染,CPU 开销极低。
2.2 srcampy.bind(cam, disp)
python
运行
srcampy.bind(cam, disp)
硬件通路绑定! 把 Camera ISP 输出的原始分辨率图像,直接硬件路由到 HDMI 显示。
👉 画面传输完全不走 Python 内存,零拷贝、极低延迟,主线程不需要转发图像给显示器。
2.3 OSD 绘图 API(代码绘制检测框核心)
disp.set_graph_rect(x1,y1,x2,y2,line_width,refresh_flag, ARGB_color)
绘制矩形框(目标检测框)
disp.set_graph_word(x,y,text_bytes,font_size,refresh_flag, ARGB_color)
绘制文字(类别 + 置信度)
refresh_flag(0 / 1)关键说明
1:刷新整个 OSD 画布,清空上一轮所有框0:增量绘制,不清空画布
代码逻辑:第一个目标使用 flag=1 清空旧框,后续目标 flag=0 叠加绘制
ARGB 颜色格式
python
运行
box_color_ARGB = 0xFF000000 | R<<16 | G<<8 | B
最高字节 Alpha (FF = 不透明),依次 R、G、B。
2.4 disp.get_display_res()
查询 HDMI 显示器支持的分辨率列表,用于自动适配,防止黑屏。
python
运行
resolution_list = disp.get_display_res()
2.5 disp.close()
释放显示硬件资源。
3. 全局接口 srcampy.bind ()
python
运行
srcampy.bind(源对象, 目标对象)
支持绑定组合:
- Camera → Display:摄像头直通 HDMI 预览
- Camera → Encoder:摄像头图像直接送入硬件 H.264/H.265 编码器录像 数据流走硬件 DMA,不经过用户内存,极致低延迟。
三、srcampy 完整流水线对照你的 FCOS 代码
plaintext
1. cam.open_cam() → 启动MIPI CSI0,开启ISP双通路硬件缩放
2. disp.display(0) → 打开视频图层
3. srcampy.bind(cam, disp) → 原始画面硬件直通HDMI
4. disp.display(3) → 切换到OSD绘图图层
循环:
cam.get_img(2,512,512) → 获取ISP输出512×512 NV12 buffer
models[0].forward(img) → BPU FCOS推理
多进程执行后处理
→ 解码检测框
→ disp.set_graph_rect / set_graph_word 在OSD图层绘制框
四、srcampy 优势对比 cv2.VideoCapture
表格
| 特性 | srcampy (MIPI 专用) | cv2.VideoCapture(V4L2) |
|---|---|---|
| 图像来源 | MIPI CSI 摄像头 | USB 摄像头;RDK MIPI原生不支持 |
| 图像格式 | 直接输出 NV12 | 只能读取 BGR/YUYV |
| 缩放操作 | ISP 硬件缩放,零 CPU | CPU resize,占用算力 |
| 直通 HDMI | 硬件 bind,极低延迟 | 软件转发,延迟高 |
| OSD 叠加 | 硬件图层绘制,性能高 | 需要 CPU 逐帧绘制图像 |
| 多路输出 | 支持同时输出多路分辨率 | 单路输出 |
五、高频踩坑清单(工程调试重点)
- CSI1 通道 video_index=2,不要写 1(最常见错误)
cam.get_img(2,w,h)分辨率必须和 open_cam 通路匹配,否则返回空- OSD 图层绘制多进程并发容易闪烁,建议收敛到同一个进程绘制
- 程序异常退出务必调用
cam.close_cam(),否则 ISP 卡死,重启才能恢复 - bind 之后,原始画面不再经过 Python,Python 只能读取第二路推理尺寸图像
- NV12 是 packed 格式,不要错误当作 RGB 处理
- HDMI 热插拔后需要重新执行
get_display_res()刷新分辨率
六、拓展能力(你现有代码没有用到)
- srcampy.Encoder() 硬件 H.264/H.265 编码,直接把摄像头 NV12 流转码保存视频;无需 CPU 编码。
python
运行
enc = srcampy.Encoder()
enc.encode(0, width, height)
- srcampy.Decoder() 硬件解码 H264/H265 码流,输出 NV12 图像送入 BPU 推理。
七、最简使用模板(单路 CSI0 摄像头)
python
运行
from hobot_vio_rdkx5 import libsrcampy as srcampy
import numpy as np
sensor_w, sensor_h = 1920,1080
model_w, model_h = 512,512
preview_w, preview_h = 1920,1080
cam = srcampy.Camera()
# CSI0 = 0;CSI1 = 2
cam.open_cam(0, -1, -1, [model_w, preview_w], [model_h, preview_h], sensor_h, sensor_w)
disp = srcampy.Display()
disp.display(0, preview_w, preview_h)
srcampy.bind(cam, disp)
disp.display(3, preview_w, preview_h)
while True:
nv12_buf = cam.get_img(2, model_w, model_h)
frame = np.frombuffer(nv12_buf, dtype=np.uint8)
# frame 直接送入dnn forward推理
cam.close_cam()
disp.close()
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐


所有评论(0)