2026-07-01 18:16:18 +08:00

14 KiB
Raw Blame History

libstereo_bolt 交付说明(.so + 头文件)

你拿到的是预编译的 aarch64 动态库 + C 头文件 + 模型 + 标定 + 示例,不含算法源码。 运行时依赖中 libstereo_bolt.so、OpenCV 4.5.0 .solibrknnrt.so 均已随包 lib/;无需 apt 安装 OpenCV。NPU 驱动由板子系统提供。

本库导出两个独立的产品接口(同一个 .so、同一个 StereoBoltCtx

  1. 精测PRECISE sb_process_bolt_module_buffers / _files —— 12MP 高精度测量, 每颗螺栓高度 / 相邻间距 / 地平面 / 3D 中心轴 / 顶底 3D 坐标。触发式"测得准"路径(板上约 400ms/帧,依输入和 QC 耗时波动)。
  2. 测距RANGING sb_range_bolt_binned —— 2×2 binned(3MP) 实时测距, 输出相机→螺栓代表直线距离。无人机实时路径(统一用 OBB@1024当前 distance_153304_403 复测约 153ms/帧)。

创建上下文推荐用内存接口 sb_create_ex(见下节):标定、模型、参数全部经接口/buffer 传入, 库零文件 IO、无路径假设、无安装目录读权限问题。旧的 sb_create(config.yaml) 仍保留作向后兼容。


★ 创建上下文:sb_create_ex推荐vs sb_create(兼容)

两个产品接口共用同一个 StereoBoltCtx。创建它有两种方式:

推荐:sb_create_ex —— 全参数经接口传入,零文件 IO

StereoBoltCtx* sb_create_ex(const StereoBoltCalibC* calib,
                            const StereoBoltModelC*  model,
                            const StereoBoltParamsC* params);
StereoBoltParamsC sb_default_params(void);   /* 预填默认值,再覆盖你关心的 */
  • StereoBoltCalibC:标定 —— 左右 K[9]/D[5] + R[9]/T[3] + baseline_mm + 图像尺寸。替代标定 XML。
  • StereoBoltModelC:模型 —— .rknn 字节流 data+size + backend(rk3588 用 SB_YOLO_BACKEND_RKNN) + imgsz/conf/iou替代 weights 文件路径。
  • StereoBoltParamsC:算法数值参数 —— 视差带(wd_z_min/max_mm 物理带, sgbm_min/num_disparities 固定带,二选一必填)、rectificationmeasurement.foot_rimranging.*替代 config.yaml 数值键。struct_size 做前向兼容。

这条路径库不碰磁盘:标定/模型从哪来由你决定(你的标定流程、资源文件、相机 SDK本包提供的 calib/*.xmlweights/*.rknn 只是给你读进来填结构体的现成数据。

兼容:sb_create(const char* config_yaml_path)

config.rk3588.12mp.yaml(其内部再按相对路径找标定 XML + 模型)。有两文件依赖 + 工作目录/读权限要求——正是 sb_create_ex 要规避的。仅在离线/快速测试时用。

sb_create / sb_create_ex 只调一次(载配置+标定+模型进 NPU之后每帧复用同一个 ctxsb_destroy / sb_last_error 两接口共用。线程安全:同一 ctx 别多线程并发。


交付边界(职责划分)

本交付物是一个"算法模块",不是完整软件系统。 软件总体集成由你(接入方)负责。

由谁负责
双目螺栓测量/测距算法.so + .h + 模型 + 标定 + 示例 + 文档) 算法方(本包提供)
板子运行时环境aarch64 + glibc、NPU 驱动;算法依赖的 OpenCV 与 librknnrt.so 已随包 lib/ 接入方
取图(相机驱动 / Mono8 buffer 喂入、上层业务、UI、调度、与上位机/无人机通信 接入方
标定数据来源(填入 StereoBoltCalibC)、按 c_api.h 调用、对 height/distance/confidence 做业务决策 接入方

算法方只交付"喂进左右图 → 返回螺栓高度/距离"的纯算法能力C ABI。本库不碰相机、不碰网络、 不碰磁盘(sb_create_ex + buffer 接口)、不做悬停/对中等业务决策。逐颗 confidence(trusted/suspect) + status 由接入方取舍。

包内容

路径 说明
lib/libstereo_bolt.so 预编译共享库aarch64sb_create_ex 内存接口)
include/stereo_bolt/c_api.h C ABI 头文件(唯一对外接口)
weights/best_obb_1024.rknn NPU 模型 —— OBB 检测(精测+测距共用imgsz 1024FP16
calib/stereo_calib_20260621_202857_ascii.xml 12MP 双目标定(0621 装配 baseline 482mmHalcon 位姿已修正)
config/config.rk3588.12mp.yaml sb_create(兼容)用 + 作参数参考;sb_create_ex 不需要它
lib/*.so 算法库、OpenCV 4.5.0 运行库、RKNN 运行时aarch64 2.3.2),运行时通过 LD_LIBRARY_PATH=./lib 加载
INSTALL_3588.md / ABI_FINGERPRINT.txt 板上装环境说明 / .so 二进制指纹(你的环境必须匹配
example/ C 调用示例(main.c 精测,sb_create + buffer 接口+ CMakeLists

编译期 vs 运行期

你不需要重编这个库(预编译成品,无源码)。你只编译你自己调用它的程序。

东西 编译你的调用程序 板上运行
c_api.h
libstereo_bolt.so (链接,带 --allow-shlib-undefined
OpenCV 你的程序: 不需要C ABI 不暴露 cv 类型,相机直接给 Mono8 buffer
本包 example 运行不需要系统 OpenCV
已随包 lib/,无需 apt
librknnrt.so 已随包 lib/LD_LIBRARY_PATH=./lib
NPU 驱动 + /dev/rknpu 必须(内核态)
模型 / 标定 (已在本包;sb_create_ex 由你读进来传,sb_create 由库读)

example 用 OpenCV 只是为了独立跑(读本包的标定 XML + 测试图)。你的产品里相机直接给 Mono8 buffer、 标定来自你自己的来源,调用端无需 OpenCV库也始终零文件 IO。


⚠️ 必须匹配的 ABI 指纹

.so 二进制里写死了依赖的 so 名字和 glibc 版本。打开 ABI_FINGERPRINT.txt 确保板子满足:

  • CPU = aarch64glibc ≥ 指纹版本GLIBC_2.32
  • 运行时优先使用本包 lib/(内含标准 SONAME libopencv_*.so.4.5,无需系统 OpenCV
  • librknnrt 版本 = 转 .rknn 的 toolkit 版本(2.3.x)。
  • 指纹应列出 9 个导出符号,含 sb_create_ex / sb_default_params

自检(应无任何 not foundldd lib/libstereo_bolt.so | grep "not found"


公共错误码

SB_OK=0 / SB_ERR_INVALID_CONFIG=-1 / SB_ERR_IO=-2 / SB_ERR_ALGORITHM_REJECTED=-3 / SB_ERR_INTERNAL=-99

SB_ERR_ALGORITHM_REJECTED 不是崩溃,是算法判定该帧不满足 expected 颗(仅精测返回);仍返回已测出的部分螺栓(见下)。


接口 1 —— 精测PRECISE

用途12MP 逐颗高精度测量。触发式"测得准"路径,板上 ~2.5Hz@1024。 输入:内存 Mono8 buffer生产首选或文件路径离线。buffer 尺寸必须等于标定尺寸,否则 SB_ERR_IO

sb_status_t sb_process_bolt_module_buffers(
    StereoBoltCtx* ctx,
    const uint8_t* left_data,  int left_width,  int left_height,  int left_stride_bytes,
    const uint8_t* right_data, int right_width, int right_height, int right_stride_bytes,
    int channels, int expected_bolt_count, StereoBoltModuleResultC* out);
sb_status_t sb_process_bolt_module_files(StereoBoltCtx*, const char* left, const char* right,
                                         int expected_bolt_count, StereoBoltModuleResultC* out);
void sb_free_bolt_module_result(StereoBoltModuleResultC* out);   /* 用完必须释放 */

输出 StereoBoltModuleResultC —— 每颗 data.bolts[i]

  • height_mm(高度)
  • top_xyz / foot_xyz(顶 / 底 3D 坐标)
  • centerline3D 中心轴:point + direction
  • left_roi / right_roi(左右图 2D 框 x,y,w,h,score
  • confidence0=trusted / 1=suspect+ status 另含 adjacent_distances[](相邻 distance_mm)、ground_planemodel[4]/rms_mm/inlier_count)。

坐标系/单位高度、间距、3D 坐标 = mm校正后左相机坐标系x 右 / y 下 / z=深度,典型 z≈16002200mm

★ 部分输出契约(去 all-or-nothing:即使 success==0(数量不符 count_mismatch,无论检到的多还是少于 expected data.bolts[] 仍含所有干净测出的螺栓(各带 height/top/foot/confidencefailurereason + 完整 ROI + 配对状态)始终填充,能看出缺哪颗、为何缺。别只看返回码就丢结果——照样遍历 data.bolts[],按 confidence 自行取舍。

最简用法(sb_create_ex

StereoBoltCalibC calib = {...};            /* 填 K/D/R/T/size/baseline */
StereoBoltModelC model = {.data=rknn_bytes, .size=n, .backend=SB_YOLO_BACKEND_RKNN, .imgsz=1024, .conf=0.5f};
StereoBoltParamsC p = sb_default_params(); p.wd_z_min_mm=1200; p.wd_z_max_mm=2800;
StereoBoltCtx* ctx = sb_create_ex(&calib, &model, &p);          /* 一次 */
StereoBoltModuleResultC out;
sb_process_bolt_module_buffers(ctx, L,w,h,0, R,w,h,0, 1, /*expected=*/6, &out);
/* 遍历 out.data.bolts[i].height_mm / top_xyz / foot_xyz ... */
sb_free_bolt_module_result(&out);  sb_destroy(ctx);

完整示例见 example/main.cimgsz 首选 1024OBB 模型,自动检测旋转框);交付权重 FP16INT8 检出全废,不可用)。


高度测量模式(measurement.height_from_plane

精测接口支持两种高度计算方式,通过 config 中 measurement.height_from_plane 切换:

模式 config 值 高度定义 是否需要平面拟合 板上耗时8颗场景
顶到底(默认) height_from_plane: false 螺杆顶端到可见底端沿拟合轴的长度 不需要(自动跳过) ~400ms
顶到平面 height_from_plane: true 螺杆顶端到支撑平面的法向距离 需要StereoBM 拟合) ~800ms

默认关闭平面测量height_from_plane: false),此时平面计算完全跳过,节省 300-550ms。

开启平面测量:在 config.rk3588.12mp.yaml 中修改:

measurement:
  height_from_plane: true    # 开启:高度 = 螺杆顶端到支撑平面的法向距离

sb_create_ex 用户:当前 StereoBoltParamsC 不含此字段,默认为 false顶到底。如需平面模式使用 sb_create(config.yaml) 并在 config 中设置。


接口 2 —— 测距RANGINGsb_range_bolt_binned

用途:实时回答"左目光心→螺栓多远"。容忍部分可见:绝不要求螺栓数≥1 颗即给距离。当前板上约 153ms/帧(~6.5Hz@1024。 输入2×2 binned 内存 buffer12MP→3MP=2048×1500Mono8/BGR。binned 内参内部推导,无需单独 binned 标定。

typedef struct { double distance_mm; int left_x,left_y,right_x,right_y; double ncc_score,lrc_px; int confidence; } StereoBoltRangeBoltC;
typedef struct { int found; double distance_mm; int bolt_count; char status[32]; } StereoBoltRangeSummaryC;
sb_status_t sb_range_bolt_binned(
    StereoBoltCtx* ctx,
    const uint8_t* left_data,  int left_width,  int left_height,  int left_stride_bytes,
    const uint8_t* right_data, int right_width, int right_height, int right_stride_bytes,
    int channels, StereoBoltRangeSummaryC* out, StereoBoltRangeBoltC* bolts, int max_bolts);

输出:主用 out.distance_mm(可见杆代表距离);out.found 每帧轮询;bolts[] 给出每颗候选的左右匹配点。OBB 轴路线下 ncc_score 为检测/匹配分数、lrc_px 为轴视差自洽度(字段名保留用于 ABI 兼容NCC 回退路线下为 NCC/LRC 指标。精度目标 ±50mm(稳定区 1.32.4m)。 可选 ranging.* 参数StereoBoltParamsCrng_*,都有默认):z_min/max_mm 视差带、lrc_max_mm/lrc_trusted_mm 物理同根门 等。完整示例见 example/range_example.cpp

注:sb_create_ex 即使只做测距也要求提供精测视差带(wd_z_*sgbm_*),因为同一 ctx 两接口共用。


该用哪个 + 板上实测吞吐

精测 sb_process_bolt_module_* 测距 sb_range_bolt_binned
问题 每颗螺栓高度/间距/地平面/3D 坐标 相机离螺栓多远(代表距离)
输入 12MP 原图Mono8 buffer / 文件) 2×2 binned 3MP buffer
螺栓数 expected(不符=部分输出+count_mismatch 不要≥1 颗即 found
板上吞吐@1024 约 400ms/帧 约 153ms/帧 ≈ 6.5Hz
定位 触发式"测得准" 无人机实时定位反馈

测距实测于 RK3588best_obb_1024.rknndistance_153304_40321 帧):均值 153.146ms,距离均值 1652.360mm,跨度 0.491mm。 本交付为单模型 OBB@1024精测+测距共用)。


编译你的调用程序 + 运行

示例用 C/C++,运行时库从本包 lib/ 加载:

cd example
cmake -S . -B build -DSB_ROOT="$(cd .. && pwd)"
cmake --build build        # -> bolt_demo精测+ range_demo测距

# ../lib 含 libstereo_bolt.so + OpenCV 4.5.0 + librknnrt.so
# 精测:传标定 XML + 模型 + 左右图 + 期望螺栓数
LD_LIBRARY_PATH=../lib:$LD_LIBRARY_PATH \
    ./build/bolt_demo ../calib/stereo_calib_20260621_202857_ascii.xml \
                      ../weights/best_obb_1024.rknn L.bmp R.bmp 6

# 测距:传标定 + 模型 + 左右图demo 内部 2×2 binning生产直接喂相机 binned buffer
LD_LIBRARY_PATH=../lib:$LD_LIBRARY_PATH \
    ./build/range_demo ../calib/stereo_calib_20260621_202857_ascii.xml \
                       ../weights/best_obb_1024.rknn L.bmp R.bmp