尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

SPLINTER 样条插值库实战解析:SensorsCalibration 中多变量 B-spline 拟合与偏航角标定的底层基石

SPLINTER 样条插值库实战解析:SensorsCalibration 中多变量 B-spline 拟合与偏航角标定的底层基石 自动驾驶计算机视觉【免费下载链接】SensorsCalibrationOpenCalib: A Multi-sensor Calibration Toolbox for Autonomous Driving项目地址https://gitcode.com/gh_mirrors/se/SensorsCalibration点击查看免费下载SPLINTERSPLine INTERpolation是一个面向多变量函数逼近的开源 C 库以张量积 B-spline 为核心支持函数逼近、回归、数据平滑与数据降维并被 SensorsCalibration 项目中的 pose_sensor2carGNSS/INS 偏航角标定与 lidar2car 模块作为第三方依赖深度使用。本文以 SPLINTER README 为主线结合其官方指南基本用法、C 接口、编译指南与仓库源码完整梳理其数学模型、构建流程、四类语言接口以及编译集成方式并落到 yawCalib.cpp 的真实调用链上帮助你既会用、又懂原理。一、SPLINTER 是什么为多变量函数逼近而生的样条库SPLINTER 是一个用于**多变量函数逼近multivariate function approximation的库核心数据载体是张量积 B-splinetensor product B-spline**的快速 C 实现。它覆盖了以下典型任务函数逼近function approximation回归regression数据平滑data smoothing数据降维/约简data reduction其数学基础是分段多项式基函数piecewise polynomial basis functions构成的 B-spline在灵活性与光滑性之间取得良好平衡。样本拟合采用普通最小二乘ordinary least squares, OLS并可选正则化此外还内置了**惩罚样条penalized splinesP-splines**构造能力。从源码结构看库的核心实现位于 include 与 src 目录关键类包括BSplinebspline.h多变量张量积 B-spline 本体继承自Function抽象基类除eval外还提供evalJacobian、evalHessian——这正是文档所述为数学规划/非线性优化而设计的能力BSpline::Builderbsplinebuilder.h链式构建器封装回归拟合流程BSplineBasis/BSplineBasis1Dbsplinebasis.h多维基函数张量积与一维基函数DataTabledatatable.h多维样本 (x, y) 的有序存储与网格管理SerializerB-spline 与 DataTable 的序列化save/load。说明本文所述版本为仓库中version文件记录的3-0即静态库文件名为splinter-static-3-0见 CMakeLists.txt。二、核心原理张量积 B-spline 如何逼近任意采样函数B-spline 由 B-spline 基函数构造而来这些基函数是高度光滑的分段多项式。用户可以选择线性degree 1、二次degree 2、三次degree 3乃至更高次数的 B-spline对采样数据进行平滑或插值。B-spline 从样本出发通过求解一个线性方程组得到控制点系数。几个关键性质局部支撑local support求值时只有采样点附近的样本影响该点的 B-spline 取值因此求值时间与样本总数无关只随 B-spline 的**次数degree与变量数number of variables**增长。这是它适合在线快速查询的根本原因。构建规模限制文档给出的一般性经验值在现代桌面机上普通 B-spline 构建的样本量上限约为10 万对应变量数约5~7 个P-spline 因需要求解大规模最小二乘问题样本量上限降至约1 万。构建成本随样本与变量增长求值成本则与之无关。光滑性分级线性 B-spline 连续二次 B-spline 一阶连续可导三次 B-spline 具有连续的二阶导数。SensorsCalibration 的偏航角标定正是利用了高阶导数信息见下文第六节。2.1 三种平滑/正则化模式SPLINTER 的BSpline::Builder通过smoothing参数控制拟合策略枚举定义见 bsplinebuilder.h模式枚举值行为无平滑插值Smoothing::NONE直接 OLS 拟合B-spline 插值全部样本点恒等正则化Smoothing::IDENTITY在 OLS 目标中加入二次惩罚项alpha * c * I * c即 Tikhonov 正则化抑制过拟合P-splineSmoothing::PSPLINE对控制点施加近似二阶差分惩罚得到平滑而非插值的样条Tikhonov 正则化在 OLS 目标函数上加入对系数的二次惩罚可降低过拟合影响。当前实现以单位矩阵作为 Tikhonov 矩阵平滑强度由alpha控制。P-spline从源码看其惩罚矩阵由getSecondOrderFiniteDifferenceMatrixbsplinebuilder.cpp生成——即对控制点序列施加二阶有限差分惩罚且每个维度至少需要 3 个基函数/系数。P-spline 构建需解大规模最小二乘问题因此更耗时。两种方式的 Python 构建示例来自 basic_usage.md# P-spline平滑参数 alpha 0.1 bspline splinter.BSplineBuilder(data, smoothingsplinter.BSplineBuilder.Smoothing.PSPLINE, alpha0.1).build() # Tikhonov恒等正则化三次 B-splinealpha 0.1 bspline splinter.BSplineBuilder(data, smoothingsplinter.BSplineBuilder.Smoothing.IDENTITY, alpha0.1).build()三、基本使用工作流采样 → 构建 → 评估 → 验证官方给出的工作流非常简洁采样一个函数然后构造逼近。该过程可迭代执行直到得到满意的逼近效果评估逼近精度时既可用已有样本做交叉验证也可补充采样。当前版本 SPLINTER 主要承载采样与模型构建两个环节见 basic_usage.md。3.1 二次 B-spline 构建示例Python 单行完成bspline splinter.BSplineBuilder(data, degree2).build()其中data为样本集合通常要求落在规则网格regular grid上。SPLINTER 也接受非规则网格数据但该行为目前属于实验性质、官方不推荐。四、C 接口实战原生 API 与完整示例C 接口是 SPLINTER 的原生接口在任何时候都是最全面、暴露特性最多的接口。官方示例cpp_interface.md以六峰驼背函数Six-hump camelback function为被采样函数演示了完整流程#include iostream #include datatable.h using std::cout; using std::endl; using namespace SPLINTER; // 六峰驼背函数 double f(DenseVector x) { assert(x.rows() 2); return (4 - 2.1*x(0)*x(0) (1/3.)*x(0)*x(0)*x(0)*x(0))*x(0)*x(0) x(0)*x(1) (-4 4*x(1)*x(1))*x(1)*x(1); } int main(int argc, char *argv[]) { // 创建 DataTable 管理样本 DataTable samples; // 采样函数 DenseVector x(2); double y; for(int i 0; i 20; i) { for(int j 0; j 20; j) { x(0) i*0.1; x(1) j*0.1; y f(x); samples.addSample(x,y); // 存储样本 } } // 构建插值 B-spline BSpline bspline1 BSpline::Builder(samples).degree(1).build(); BSpline bspline3 BSpline::Builder(samples).degree(3).build(); // 构建平滑 P-spline BSpline pspline BSpline::Builder(samples) .degree(3) .smoothing(BSpline::Smoothing::PSPLINE) .alpha(0.03) .build(); /* 在 x (1,1) 处评估三个逼近器 * 注意该点是我们采样过的点因此误差为 0P-spline 除外 * 它可能为了平滑而引入误差 */ x(0) 1; x(1) 1; cout Function at x: f(x) endl; cout Linear B-spline at x: bspline1.eval(x) endl; cout Cubic B-spline at x: bspline3.eval(x) endl; cout P-spline at x: pspline.eval(x) endl; return 0; }要点BSpline::Builder(samples).degree(d).build()一行完成 B-spline 构建degree支持 0~5 次源码getBSplineDegrees对 degree 5 抛异常见 bsplinebuilder.hsmoothing与alpha组合实现 P-spline 平滑编译需使用C11 兼容编译器README 的硬性要求。4.1 使用 DataTable 管理采样为简化采样管理SPLINTER 提供DataTable数据结构DataTable samples; // 添加样本 (x,y)其中 y f(x) samples.addSample(1,0); samples.addSample(2,5); samples.addSample(3,10); samples.addSample(4,15); // 样本添加顺序无关紧要DataTable 内部保持排序从 datatable.h 可见样本以std::multisetDataPoint存储内部自动排序并提供getNumSamples()、getNumVariables()、getTableX()、getVectorY()、isGridComplete()等查询接口以及save/load序列化能力。五、Builder 构建细节degree、smoothing、alpha 与网格限制5.1 Builder 链式参数一览BSpline::Builder是构建 B-spline 的唯一入口默认以 3 次、无平滑、AS_SAMPLED节点间距构建。可配置项见 bsplinebuilder.h参数默认值说明degree(d)/degree(vector)3基函数次数支持 0~5传向量可为每个维度分别指定次数smoothing(Smoothing)NONE平滑策略NONE/IDENTITY/PSPLINEalpha(a)—平滑/正则化强度必须非负源码中对负 alpha 抛异常numBasisFunctions(vector)自动各维度基函数个数可显式指定knotSpacing(KnotSpacing)AS_SAMPLED节点向量构造策略AS_SAMPLED移动平均模拟样本分布、EQUIDISTANT等距节点等build()—校验数据并执行构建5.2 网格完整性限制重要当前实现要求样本构成一个完整网格complete grid / regular grid若被采样函数是二维的变量x0、x1则x0与x1的所有组合都必须出现在样本中。例如二维情形可想象为坐标纸——所有交叉点都应存在缺一个样本就缺一个交叉点网格即不完整。不完整网格示例x₀x₁y2.11-72.33102.139.3完整网格示例x₀x₁y2.11-72.33102.139.32.310注意网格是否完整只取决于 x 的取值组合与 y 无关。可通过DataTable::isGridComplete()检查从源码看BSpline::Builder::build()会直接对不完整网格抛异常bsplinebuilder.cpp。该限制在后续版本计划移除。有意思的是SensorsCalibration 的 yawCalib.cpp 中样本按等间隔时间戳i采样天然构成一维完整网格因此可顺利通过构建校验——这正是按采样网格取数这一限制在真实工程中的典型应对。六、在 SensorsCalibration 中的真实应用P-spline 驱动的偏航角标定SPLINTER 并非孤立的第三方库它直接服务于 SensorsCalibration 的传感器标定算法。在 SensorX2car/pose_sensor2carGNSS/INS 航向角标定与 SensorX2car/lidar2car 中SPLINTER 被链接为静态库splinter-static-3-0。6.1 集成方式SensorX2car/pose_sensor2car/CMakeLists.txt 中的典型集成# Get splinter include_directories(${PROJECT_SOURCE_DIR}/3rdparty/splinter-3.0/include) link_directories(${PROJECT_SOURCE_DIR}/lib) ... target_link_libraries(... splinter-static-3-0 ...)6.2 源码级调用链yawCalib.cpp 中GetYawSegs用两条 P-spline 分别拟合车辆轨迹的 x、y 坐标再借助evalJacobian与evalHessian求取航向与曲率BSpline bspline_x BSpline::Builder(sample_x).degree(bspine_degree_).smoothing(BSpline::Smoothing::PSPLINE).alpha(0.03).build(); BSpline bspline_y BSpline::Builder(sample_y).degree(bspine_degree_).smoothing(BSpline::Smoothing::PSPLINE).alpha(0.03).build(); ... double dx bspline_x.evalJacobian(t)(0, 0); // 一阶导数 - 速度分量 double dy bspline_y.evalJacobian(t)(0, 0); double ddx bspline_x.evalHessian(t)(0, 0); // 二阶导数 - 曲率判断 double ddy bspline_y.evalHessian(t)(0, 0); double yaw atan2(dx, dy); // 由速度方向反解航向角而CalibrateSingle中再对每段 yaw 序列构建一条alpha0.06的三次 P-spline 平滑bspine_degree_默认 4见 yawCalib.hBSpline bspline_yaw BSpline::Builder(sample_yaw).degree(bspine_degree_).smoothing(BSpline::Smoothing::PSPLINE).alpha(0.06).build();随后将 IMU 原始 yaw 与 B-spline 平滑 yaw 做差、剔除离群点Util::DeleteOutliers后取均值得到车体与 IMU 之间的安装偏航角。这条链路完整印证了 README 所述能力P-spline 平滑 Jacobian/Hessian 解析求导正是为数学规划与优化场景设计的。七、多语言接口Python、MATLAB 与 C除原生 C 接口外SPLINTER 提供 Python、MATLAB、C 三套绑定C 接口是 MATLAB/Python 绑定的底层通道。7.1 Python 接口官方说明其已测试兼容Python 2.7 与 3.x。make install后产生lib/os/arch下的共享库与python/splinter包将python目录加入路径后即可import splinter。基本用法python_interface.mdimport splinter import numpy as np def f1(x): return -1. 2*x 0.1*(x**2) 10*np.random.rand(1)[0] x np.arange(0, 11, 1) y np.zeros((len(x),)) for i in range(len(x)): y[i] f1(x[i]) data list(zip(x, y)) # 构建插值三次 B-spline bspline splinter.BSplineBuilder(data, degree3).build() # 评估多点多批次比逐点调用更高效 xd np.arange(0, 10, .01) yd bspline.eval(xd) # 保存 / 加载 bspline.save(myfile.myextension) loadedBSpline splinter.BSpline(myfile.myextension)7.2 MATLAB 接口安装后在 MATLAB 中运行setup()每次启动 MATLAB 需执行一次即可加载示例代码位于matlab/examples目录。7.3 C 接口C 接口几乎所有函数都以splinter_obj_ptr定义为typedef void *splinter_obj_ptr为首参模拟面向对象风格。官方示例c_interface.md展示了完整流程#include stdio.h #include stdlib.h #include cinterface/cinterface.h double f(double x, double y) { return x*x*y y*y*y; } int main(int argc, char **argv) { splinter_obj_ptr datatable splinter_datatable_init(); // 以行主序批量添加 10x10 网格样本 double samples[300]; int sampleIdx -1; for (int x 0; x 10; x) for (int y 0; y 10; y) { samples[sampleIdx] x; samples[sampleIdx] y; samples[sampleIdx] f(x, y); } splinter_datatable_add_samples_row_major(datatable, samples, 100, 2); splinter_obj_ptr bspline_builder splinter_bspline_builder_init(datatable); unsigned int degrees[2] {3, 3}; splinter_bspline_builder_set_degree(bspline_builder, degrees, 2); splinter_obj_ptr bspline splinter_bspline_builder_build(bspline_builder); double x_eval[] {0.1, 0.5}; double *val splinter_bspline_eval_row_major(bspline, x_eval, 2); printf(Approximated value at (%f, %f): %f\n, x_eval[0], x_eval[1], val[0]); return 0; }C 接口还提供splinter_get_error()/splinter_get_error_string()进行错误检查以及求值eval、Jacobianeval_jacobian、Hessianeval_hessian的行/列主序变体详见 cinterface.h。八、编译与安装从一行脚本到精细化 CMake官方建议优先使用预编译二进制如需自行编译提供了快速脚本与进阶手动两条路线compile.md。8.1 快速方式release 脚本依赖CMake、GitUNIX 下需 GCC 与/或 ClangWindows 下需 MinGW 与/或 Visual StudioUbuntu 下需apt-get install build-essentials。脚本会为所有已知编译器/架构编译较耗时git clone https://github.com/bgrimstad/splinter.git # 以官方仓库为例 cd splinter ./scripts/build_release.sh产物位于build/OS/COMPILER/ARCHITECTURE目录。README 还给出两条平台注意事项MinGW 非 multilibx86 与 x86-64 需分别安装Ubuntu 下 clang 可能未符号链接需sudo ln -s /usr/bin/clang-3.5 /usr/bin/clang。8.2 进阶方式UNIX / Windows 手动构建git clone https://github.com/bgrimstad/splinter.git cd splinter mkdir build cd build export CXX$(which g) # 或 clang cmake .. make make installWindowsMinGW下对应cmake .. -DCMAKE_MAKE_PROGRAMmingw32-make -G Unix Makefiles后mingw32-make可接install。常见排错make: *** [install] Error 1安装目录无写权限改用sudo make install或调整安装路径64 位系统编译 32 位报bits/cconfig.h缺失安装g-multilib。8.3 CMake 选项表所有平台通用变量名默认值说明EIGEN_DIRECTORYthirdparty/EigenEigen 库路径HEADER_INSTALL_DIRECTORYinclude头文件安装目录LIBRARY_INSTALL_DIRECTORYlib库文件安装目录ARCHx86目标架构x86 / x86-64仅 GCC/Clang 生效CMAKE_BUILD_TYPERelease构建类型Debug / Release用法示例cmake .. -DEIGEN_DIRECTORY/path/to/eigen -DHEADER_INSTALL_DIRECTORY/home/me/splinter/includes -DARCHx86-64语法为-DVARIABLE_NAMEVARIABLE_VALUE含空格的值需用双引号包裹。若头文件/库路径为相对路径则相对CMAKE_INSTALL_PREFIX解析。仓库内 CMakeLists.txt 与文档一致默认ARCH为x86-64、Release构建、同时产出共享库splinter-3-0与静态库splinter-static-3-0并支持 Doxygen 文档目标make doc。九、源码结构与测试佐证仓库中 test 目录基于 Catch 框架对库的核心行为进行了覆盖可作为理解与验证的补充材料test/approximation/bspline.cpp线性/二次/三次/四次 B-spline 在密采样、正常采样、稀疏采样下的函数值、Jacobian、Hessian 对称性测试test/approximation/pspline.cppP-splinealpha0.03的函数值与 Jacobian 对比、Hessian 对称性检查test/general/bspline.cpp节点插入knot insertion测试test/serialization/bspline.cppB-spline 的 save/load 往返一致性1~4 次均有覆盖test/unit/bsplinebasis1d.cpp、test/unit/knots.cpp一维基函数与节点向量单元测试。这些测试同样演示了BSpline::Builder(table).degree(n).build()的标准用法与文档示例完全同构。十、引用与贡献SPLINTER 源于多年对快速、通用的多变量函数逼近库的开发积累最初为数学规划非线性优化中的样条构建而生因此对 Jacobian/Hessian 计算投入较多。若在科研工作中使用 SPLINTER官方建议在论文中引用可参考 README 中的 bibtex 条目作者 Bjarne Grimstad 等标题SPLINTER: a library for multivariate function approximation with splines2015 年发布注明访问日期。官方欢迎任何人使用与贡献近期目标包括改善接口与文档以提升可及性、实现新特性、通过测试改进现有代码。最直接的贡献方式是使用并反馈体验编码贡献可从 GitHub issues 列表中选择issue 按工作类型Bug/Docs/Enhancement/New feature/Refactoring/Tests与难度Beginner/Intermediate/Advanced标记Critical标记表示需要优先处理。小结SPLINTER 以张量积 B-spline OLS/正则化/P-spline的组合为多变量函数逼近提供了高速、光滑、可求导的通用方案并通过 C/C/Python/MATLAB 四套接口覆盖不同研发链路。在 SensorsCalibration 中它被 pose_sensor2car 用作轨迹平滑与解析微分的底层引擎——BSpline::Builder(...).degree(...).smoothing(PSPLINE).alpha(...)一行式构建配合eval/evalJacobian/evalHessian正是自动驾驶传感器标定中从带噪轨迹稳健提取航向的实用利器。理解它的网格约束、次数范围与平滑参数语义是正确使用的前提。赞分享自动驾驶计算机视觉【免费下载链接】SensorsCalibrationOpenCalib: A Multi-sensor Calibration Toolbox for Autonomous Driving项目地址https://gitcode.com/gh_mirrors/se/SensorsCalibration点击查看免费下载相关推荐SPLINTER 张量积 B 样条B-spline构建与平滑全解析从插值、P-spline 到 Tikhonov 正则化及其在 SensorsCalibration 航向角标定中的实战应用SPLINTER 张量积 B 样条B spline构建与平滑全解析从插值、P spline 到 Tikhonov 正则化及其在 SensorsCalib自动驾驶计算机视觉SensorsCalibration 内嵌 SPLINTER 库 Python 接口实战B 样条拟合、批量求值与模型持久化指南SensorsCalibration 内嵌 SPLINTER 库 Python 接口实战B 样条拟合、批量求值与模型持久化指南 SPLINTERSPLine自动驾驶计算机视觉SPLINTER MATLAB 接口实战指南环境配置、核心类与 B 样条拟合SensorsCalibrationSPLINTER MATLAB 接口实战指南环境配置、核心类与 B 样条拟合SensorsCalibration SPLINTERSPLine INTE自动驾驶计算机视觉上一篇Detect-It-Easy文件类型检测与安全分析的强力解密工具下一篇魔兽争霸3终极优化指南7个必开功能解决黑边、卡顿和地图限制创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表