当前位置: 首页 > article >正文

最小二乘问题详解15:束平差原理与基础实现

初始两帧的 E 矩阵分解可能存在错误解或尺度模糊三角化结果受位姿误差和图像噪声影响PnP 的位姿估计会继承并放大前期误差。随着图像数量增加这些局部误差会不断累积导致最终重建结果出现尺度漂移、结构扭曲甚至拓扑错误。要解决这一问题我们需要一种全局优化机制能够同时调整所有相机位姿和所有 3D 点使得整个观测系统在统一的几何模型下达到最优自洽。这就是束平差Bundle Adjustment, BA一种非线性最小二乘优化方法它将所有相机位姿和所有 3D 点作为联合变量最小化所有观测点的重投影误差总和从而实现全局一致的高精度重建。BA 并不取代上述局部方法而是作为 SFM 流程的最终全局优化阶段对由 PnP 与三角化逐步构建的初始重建结果进行一致性精修。在本文中我们将建立 BA 的完整数学模型分析其稀疏结构并基于 Ceres Solver 实现一个基础但可运行的 BA 系统。2 几何模型束平差建立在针孔相机成像模型基础之上。考虑一个由 N 个相机和 M 个 3D 空间点构成的多视图系统。对于任意一个被第 i 个相机观测到的第 j 个 3D 点其成像过程可描述如下世界坐标系中的 3D 点记为 Xj∈R3∈3变换至第 i 个相机坐标系X(i)jRiXjti()其中 Ri∈SO(3)∈(3) 和 ti∈R3∈3 分别表示第 i 个相机的旋转矩阵和平移向量即外参透视投影至归一化平面xnormij1Z(i)j⎡⎣X(i)jY(i)j⎤⎦norm1()[()()]应用内参得到像素坐标假设相机内参 K 已知且固定^xijK[xnormij1]π(K[Ri∣ti][Xj1])^[norm1]([∣][1])其中 π(⋅)(⋅) 表示齐次坐标到非齐次坐标的转换操作。在理想无噪声情况下重投影点 ^xij^ 应与图像中实际检测到的特征点 xij 完全重合。然而由于特征提取误差、初始位姿不准、三角化偏差等因素二者通常存在偏差。BA 的目标正是通过调整所有 {Ri,ti}{,} 与 {Xj}{}使这一偏差全局最小化。在几何上BA 可理解为调整所有相机光心位置与朝向以及所有 3D 点的空间位置使得从各相机出发、穿过对应图像点的“光线束”bundle of rays尽可能交汇于同一点。3 问题建模束平差本质上是一个大规模非线性最小二乘问题。我们首先定义可见性集合Ω{(i,j)∣第 i 个相机观测到了第 j 个 3D 点}Ω{(,)∣第 个相机观测到了第 个 3D 点}其大小 K|Ω||Ω| 表示有效观测总数。3.1 优化变量相机位姿共 N 个每个用李代数 ξi[ϕ⊤i,t⊤i]⊤∈R6[⊤,⊤]⊤∈6 表示ϕi 为旋转向量避免直接优化带约束的旋转矩阵3D 点坐标共 M 个Xj∈R3∈3。将所有变量拼接为全局参数向量p[ξ⊤1,…,ξ⊤N,X⊤1,…,X⊤M]⊤∈R6N3M[1⊤,…,⊤,1⊤,…,⊤]⊤∈633.2 残差函数对每一对观测 (i,j)∈Ω(,)∈Ω定义重投影残差rij(ξi,Xj)xij−π(K[exp([ϕi]×)|ti][Xj1])∈R2(,)−([exp⁡([]×)|][1])∈2其中 exp([ϕi]×)exp⁡([]×) 将旋转向量映射为旋转矩阵。3.3 目标函数将所有残差堆叠为总残差向量 rtotal∈R2Ktotal∈2束平差的目标为minp ∥rtotal(p)∥2∑(i,j)∈Ω∥∥rij(ξi,Xj)∥∥2min ‖total()‖2∑(,)∈Ω‖(,)‖2该问题具有以下关键特性非线性因透视除法与旋转指数映射引入强非线性稀疏性每个残差 rij 仅依赖两个变量块ξi 与 Xj导致雅可比矩阵呈块状稀疏结构大规模当 N,M, 较大时如 N100,M104100,104变量维数可达数万需专用稀疏求解器。4 理论推导在《最小二乘问题详解4非线性最小二乘》与《最小二乘问题详解8Levenberg-Marquardt方法》中我们已系统介绍了 Gauss-NewtonGN与 Levenberg-MarquardtLM方法求解非线性最小二乘问题的一般框架。束平差BA作为其典型应用场景同样通过迭代求解如下线性化系统(J⊤JλI)Δp−J⊤r,(⊤)Δ−⊤,其中 J∂rtotal/∂p∂total/∂ 为总残差对所有参数的雅可比矩阵ΔpΔ 为参数更新量。BA 的高效求解关键在于 J 的特殊稀疏结构。下面我们将具体推导单个残差块的雅可比并揭示其全局稀疏模式。4.1 单个残差的雅可比分解考虑一个观测 (i,j)∈Ω(,)∈Ω其残差为rijxij−^xij,^xijπ(K[Ri∣ti][Xj1]).−^,^([∣][1]).该残差仅依赖两个变量相机 i 的位姿 ξi 和 3D 点 j 的坐标 Xj。因此其雅可比可分解为两部分∂rij∂p⎡⎢ ⎢ ⎢⎣0⋯J(ij)ξi⋯0关于相机位姿,0⋯J(ij)Xj⋯0关于3D点⎤⎥ ⎥ ⎥⎦,∂∂[0⋯()⋯0⏟关于相机位姿,0⋯()⋯0⏟关于3D点],其中J(ij)ξi∂rij/∂ξi∈R2×6()∂/∂∈2×6J(ij)Xj∂rij/∂Xj∈R2×3()∂/∂∈2×3。这两部分可通过链式法则推导其核心思想是J(ij)ξi() 描述相机微小运动旋转平移对重投影的影响涉及李代数扰动模型。J(ij)Xj() 描述 3D 点微小移动对重投影位置的影响4.2 全局雅可比的稀疏结构从以上雅可比分解的推导可以看到每个残差块仅贡献两个非零子块其余位置全为零。当所有 K 个残差的雅可比垂直堆叠得到总雅可比矩阵 J∈R2K×(6N3M)∈2×(63)。其结构如下图所示Bundle Adjustment Jacobian Sparsity Columns (Optimization Variables) --------------------------------------------------------- | Cameras (6N) | Points (3M) | --------------------------------------------------------- Rows (Residuals) r11 | XXXX | XXX r12 | XXXX | XXX r13 | XXXX | XXX r21 | XXXX | XXX r22 | XXXX | XXX r31 | XXXX | XXX r41 | XXXX| XXX 每一行只有两个非零块 camera_i point_j每2 行对应一个观测 (i,j)(,)每行中仅有两个非零块一个在相机 i 对应的 6 列一个在 3D 点 j 对应的 3 列非零元素占比通常低于0.1%属于典型的块状稀疏矩阵Block-Sparse Matrix。4.3 稀疏求解优势尽管束平差BA的目标函数是非线性的但在 Gauss-Newton 或 Levenberg-Marquardt 框架下每一步迭代都归结为求解一个大型线性方程组HΔp−g,其中 HJ⊤J, gJ⊤r.Δ−,其中 ⊤, ⊤.这里 H∈R(6N3M)×(6N3M)∈(63)×(63) 是所谓的信息矩阵或 Hessian 近似g 是梯度向量。虽然原始雅可比矩阵 J 是高度稀疏的但其信息矩阵 HJ⊤J⊤ 通常是稠密的——因为两个相机若共视同一个 3D 点它们的参数块就会在 H 中产生非零耦合项。直接对 H 进行 Cholesky 分解的复杂度为 O((6N3M)3)((63)3)在大规模问题中不可接受。然而BA 的特殊结构——每个残差仅连接一个相机和一个 3D 点——使得 H 具有可利用的块结构。我们可以通过Schur Complement舒尔补技巧将原系统分解并消元从而大幅降低计算量。4.3.1 按变量类型重排系统我们将优化变量分为两类相机参数c[ξ⊤1,…,ξ⊤N]⊤∈R6N[1⊤,…,⊤]⊤∈63D点参数x[X⊤1,…,X⊤M]⊤ ∈R3M[1⊤,…,⊤]⊤ ∈3相应地将信息矩阵 H 和梯度 g 按此分块H[BEE⊤C],g[vw],[⊤],[],其中B∈R6N×6N∈6×6相机-相机块表示相机之间的耦合通过共视点间接产生C∈R3M×3M∈3×3点-点块E∈R6N×3M∈6×3相机-点交叉块。由于每个 3D 点仅被一组相机观测且不同 3D 点之间无共享残差因此 C 是一个块对角矩阵Cdiag(C1,C2,…,CM),diag⁡(1,2,…,),其中每个 Cj∈R3×3∈3×3 仅与观测到点 j 的相机有关。这意味着 C−1−1 可以并行、高效地计算只需对每个 3×3 块求逆。4.3.2消去 3D 点变量原线性系统为{BΔcEΔx−v(1)E⊤ΔcCΔx−w(2){ΔΔ−(1)⊤ΔΔ−(2)由方程 (2) 解出 ΔxΔΔx−C−1(E⊤Δcw).Δ−−1(⊤Δ).代入方程 (1)得到仅关于 ΔcΔ 的方程BΔc−EC−1(E⊤Δcw)−v,Δ−−1(⊤Δ)−,整理后即为 Schur Complement 系统(B−EC−1E⊤)Δc−(v−EC−1w)(−−1⊤)Δ−(−−1)4.3.3求解与回代求解简化系统新系统的规模仅为 6N×6N6×6。虽然 B−EC−1E⊤−−1⊤ 仍是稠密的称为“填充” fill-in但当 N≪M≪通常如此如 100 相机 vs 10,000 点其规模远小于原始 (6N3M)2(63)2。回代求 ΔxΔ一旦得到 ΔcΔ即可通过Δx−C−1(E⊤Δcw)Δ−−1(⊤Δ)快速计算所有 3D 点的更新量。由于 C 是块对角的这一步可完全并行化。计算复杂度对比与常规的 Cholesky 分解算法相比Schur Complement 方法的复杂度从 O((6N3M)3)((63)3) 下降到 O((6N)3M)((6)3) 可带来数个数量级的加速。5. 实际案例基于以上的理论推导这里设计了一个完整的束平差数值优化实现。为了能验证初始估计存在显著偏差全局优化仍能恢复高精度重建按照如下设计思路生成了实验数据构建一个由 5 个相机和 100 个 3D 点组成的简单航拍场景相机沿 Y 轴匀速旋转并向前平移模拟无人机飞行3D 点随机分布在相机前方一定深度范围内对真实重投影点添加高斯噪声标准差 1 像素模拟特征检测误差初始估计在真值基础上叠加小量噪声平移 ±0.1m点位置 ±0.1m模拟 SFM 前端输出。完整代码如下所示#include ceres/ceres.h #include ceres/rotation.h #include Eigen/Core #include Eigen/Geometry #include iostream #include random #include vector using namespace std; struct Camera { double q[4]; // quaternion double t[3]; // translation }; struct Point3D { double xyz[3]; }; struct Observation { int cam_id; int pt_id; double x; double y; }; struct ReprojectionError { ReprojectionError(double x, double y, double fx, double fy, double cx, double cy) : x_(x), y_(y), fx_(fx), fy_(fy), cx_(cx), cy_(cy) {} template typename T bool operator()(const T* const q, const T* const t, const T* const point, T* residuals) const { T p[3]; ceres::QuaternionRotatePoint(q, point, p); p[0] t[0]; p[1] t[1]; p[2] t[2]; T xp p[0] / p[2]; T yp p[1] / p[2]; T u T(fx_) * xp T(cx_); T v T(fy_) * yp T(cy_); residuals[0] u - T(x_); residuals[1] v - T(y_); return true; } static ceres::CostFunction* Create(double x, double y, double fx, double fy, double cx, double cy) { return new ceres::AutoDiffCostFunctionReprojectionError, 2, 4, 3, 3( new ReprojectionError(x, y, fx, fy, cx, cy)); } double x_, y_; double fx_, fy_, cx_, cy_; }; double ComputeRMSE(const vectorCamera cams, const vectorPoint3D pts, const vectorObservation obs, double fx, double fy, double cx, double cy) { double err 0; int n 0; for (auto o : obs) { const Camera c cams[o.cam_id]; const Point3D p pts[o.pt_id]; Eigen::Quaterniond q(c.q[0], c.q[1], c.q[2], c.q[3]); Eigen::Vector3d t(c.t[0], c.t[1], c.t[2]); Eigen::Vector3d P(p.xyz[0], p.xyz[1], p.xyz[2]); Eigen::Vector3d Pc q * P t; double u fx * Pc.x() / Pc.z() cx; double v fy * Pc.y() / Pc.z() cy; double du u - o.x; double dv v - o.y; err du * du dv * dv; n 2; } return sqrt(err / n); } double PoseError(const Camera a, const Camera b) { Eigen::Quaterniond qa(a.q[0], a.q[1], a.q[2], a.q[3]); Eigen::Quaterniond qb(b.q[0], b.q[1], b.q[2], b.q[3]); double rot qa.angularDistance(qb); Eigen::Vector3d ta(a.t[0], a.t[1], a.t[2]); Eigen::Vector3d tb(b.t[0], b.t[1], b.t[2]); double trans (ta - tb).norm(); return rot trans; } int main() { int num_cams 5; int num_pts 100; double fx 800, fy 800, cx 320, cy 240; vectorCamera gt_cams(num_cams); vectorPoint3D gt_pts(num_pts); vectorObservation obs; mt19937 rng(0); normal_distributiondouble noise(0, 1); // 生成真实相机 for (int i 0; i num_cams; i) { double ang i * 0.2; Eigen::Quaterniond q(Eigen::AngleAxisd(ang, Eigen::Vector3d::UnitY())); gt_cams[i].q[0] q.w(); gt_cams[i].q[1] q.x(); gt_cams[i].q[2] q.y(); gt_cams[i].q[3] q.z(); gt_cams[i].t[0] i * 0.5; gt_cams[i].t[1] 0; gt_cams[i].t[2] 0; } // 生成3D点 for (int i 0; i num_pts; i) { gt_pts[i].xyz[0] (rand() % 100) / 50.0 - 1; gt_pts[i].xyz[1] (rand() % 100) / 50.0 - 1; gt_pts[i].xyz[2] 4 (rand() % 100) / 50.0; } // 生成观测 for (int i 0; i num_cams; i) { Eigen::Quaterniond q(gt_cams[i].q[0], gt_cams[i].q[1], gt_cams[i].q[2], gt_cams[i].q[3]); Eigen::Vector3d t(gt_cams[i].t[0], gt_cams[i].t[1], gt_cams[i].t[2]); for (int j 0; j num_pts; j) { Eigen::Vector3d P(gt_pts[j].xyz[0], gt_pts[j].xyz[1], gt_pts[j].xyz[2]); Eigen::Vector3d Pc q * P t; double u fx * Pc.x() / Pc.z() cx; double v fy * Pc.y() / Pc.z() cy; Observation o; o.cam_id i; o.pt_id j; o.x u noise(rng); o.y v noise(rng); obs.push_back(o); } } vectorCamera est_cams gt_cams; vectorPoint3D est_pts gt_pts; // 添加初始噪声 for (auto c : est_cams) { for (int k 0; k 3; k) c.t[k] noise(rng) * 0.1; } for (auto p : est_pts) { for (int k 0; k 3; k) p.xyz[k] noise(rng) * 0.1; } cout Initial RMSE: ComputeRMSE(est_cams, est_pts, obs, fx, fy, cx, cy) endl; ceres::Problem problem; ceres::Manifold* q_manifold new ceres::QuaternionManifold(); for (int i 0; i num_cams; i) { problem.AddParameterBlock(est_cams[i].q, 4, q_manifold); problem.AddParameterBlock(est_cams[i].t, 3); } for (auto o : obs) { ceres::CostFunction* cost ReprojectionError::Create(o.x, o.y, fx, fy, cx, cy); problem.AddResidualBlock(cost, nullptr, est_cams[o.cam_id].q, est_cams[o.cam_id].t, est_pts[o.pt_id].xyz); } // Fix first camera problem.SetParameterBlockConstant(est_cams[0].q); problem.SetParameterBlockConstant(est_cams[0].t); ceres::Solver::Options options; options.linear_solver_type ceres::SPARSE_SCHUR; options.minimizer_progress_to_stdout true; options.max_num_iterations 50; ceres::Solver::Summary summary; ceres::Solve(options, problem, summary); cout summary.BriefReport() endl; cout Final RMSE: ComputeRMSE(est_cams, est_pts, obs, fx, fy, cx, cy) endl; cout \nPose error\n; for (int i 0; i num_cams; i) { cout cam i : PoseError(gt_cams[i], est_cams[i]) endl; } return 0; }在这段代码实现中需要注意如下关键机制参数化与流形注册使用 AddParameterBlock 指定参数块的更新规则如绑定流形、设为常量等使用 AddResidualBlock 则将所引用的参数内存注册为优化变量默认采用欧氏流形无需额外声明本文理论推导采用李代数参数化以简化扰动模型实际代码实现中我们使用四元数平移并通过ceres::QuaternionManifold处理旋转约束二者在优化效果上等价。相机旋转以四元数q[4]存储并通过ceres::QuaternionManifold约束其单位性平移t[3]和 3D 点xyz[3]属于欧氏空间无需特殊流形虽然 3D 点未显式调用AddParameterBlock但 Ceres 会在AddResidualBlock中自动将其识别为优化变量默认欧氏流形。仅当需要覆盖默认行为如固定、加边界、非欧结构时才需显式注册。残差函数设计旋转变换使用了 Ceres 提供的ceres::QuaternionRotatePoint(q, point, p)而非直接调用 Eigen 的q * point。需要说明的是从自动微分的角度看Eigen 的四元数乘法本身是可导的Ceres 的AutoDiffCostFunction完全能够正确处理它——因此并非“不能用矩阵乘法”。使用 Ceres 专门提供的QuaternionRotatePoint这类底层几何操作函数主要出于以下工程考量数值鲁棒性该函数内部会对输入四元数进行归一化处理即使在优化过程中因浮点误差导致四元数轻微失范|q| ≠ 1仍能保证旋转结果有效求导链路优化作为标量函数实现其雅可比推导路径更短、更稳定避免了 Eigen 模板在Jet类型上实例化带来的潜在数值噪声或性能开销编译效率不依赖 Eigen 的泛型模板减少编译时间与二进制体积接口一致性与ceres::QuaternionManifold配套使用确保参数更新与几何操作遵循相同的四元数约定w, x, y, z。消除零空间自由度调用SetParameterBlockConstant固定第一帧相机的位姿q和t。这是 BA 能收敛的必要条件由于整个场景在 3D 空间中可任意刚体变换而不改变重投影误差Hessian 矩阵天然奇异。固定一个相机相当于设定世界坐标系原点消除 6 个不可观测自由度3 旋转 3 平移。稀疏求解器选择设置options.linear_solver_type ceres::SPARSE_SCHUR启用基于 Schur Complement 的稀疏求解策略。Ceres 会自动识别“相机-点”二分图结构构建并高效求解约简系统规模仅 6N×6N6×6大幅加速大规模问题求解。程序输出结果如下Initial RMSE: 30.1646 iter cost cost_change |gradient| |step| tr_ratio tr_radius ls_iter iter_time total_time 0 4.549507e05 0.00e00 1.87e06 0.00e00 0.00e00 1.00e04 0 6.63e-04 3.06e-03 1 8.934163e02 4.54e05 6.91e04 0.00e00 9.99e-01 3.00e04 1 3.16e-03 6.44e-03 2 3.666374e02 5.27e02 5.55e02 2.76e-01 1.00e00 9.00e04 1 6.72e-04 7.77e-03 3 3.664255e02 2.12e-01 1.75e02 8.00e-02 1.00e00 2.70e05 1 6.67e-04 8.90e-03 4 3.664170e02 8.57e-03 2.01e01 2.69e-02 1.00e00 8.10e05 1 6.15e-04 9.82e-03 Ceres Solver Report: Iterations: 5, Initial cost: 4.549507e05, Final cost: 3.664170e02, Termination: CONVERGENCE Final RMSE: 0.856057 Pose error cam 0 : 0.081944 cam 1 : 0.0811149 cam 2 : 0.0821392 cam 3 : 0.083811 cam 4 : 0.0855873从这个输出结果可以看到重投影误差显著下降初始 RMSE 高达30.16 像素严重失准经 5 次迭代后降至0.86 像素达到亚像素级精度表明 BA 成功校正了初始估计中的系统性偏差。位姿恢复准确各相机的位姿误差旋转角距离 平移范数稳定在 0.08 量级。注意第 0 帧误差非零是因为我们固定了其初始含噪估计值作为世界坐标系而非真实值其余帧均相对于此参考系优化因此误差具有可比性。

相关文章:

最小二乘问题详解15:束平差原理与基础实现

初始两帧的 E 矩阵分解可能存在错误解或尺度模糊;三角化结果受位姿误差和图像噪声影响;PnP 的位姿估计会继承并放大前期误差。 随着图像数量增加,这些局部误差会不断累积,导致最终重建结果出现尺度漂移、结构扭曲甚至拓扑错误。要…...

记录生活中的一件小事(佚名整理)

(转发需官方授权)记录生活中的一件小事(佚名整理)(佚名整理)记录生活中的一件小事,如果喊错了那才是麻烦事情的开始:曾经有一个人家里有两个姐姐,这个人上高中的时候和两…...

olonCode v0.0.20 发布 - 编程智能体(新增子代理和浏览器能力)

关于 SolonCode(编程智能体)SolonCode 是由杭州无耳科技有限公司,基于 Java 8 Solon AI 开发的 “Claude Code” 国产开源实现版本。它不仅是一个 AI 终端智能助手(帮你查资料、写报告、发邮件,生成图片、视频&#x…...

别再乱用get()了!Python字典setdefault()的3个进阶技巧(含性能对比)

别再乱用get()了!Python字典setdefault()的3个进阶技巧(含性能对比) 字典操作是Python开发中最频繁的基础动作之一,但很多中高级开发者依然停留在get()方法的舒适区。本文将带你突破常规用法,探索setdefault()在真实项…...

新手怎么部署OpenClaw?2026年本地1分钟超速搭建OpenClaw及大模型百炼APIKey配置

新手怎么部署OpenClaw?2026年本地1分钟超速搭建OpenClaw及大模型百炼APIKey配置。OpenClaw(原Clawdbot)作为2026年主流的AI自动化助理平台,可通过阿里云轻量服务器实现724小时稳定运行,并快速接入钉钉,让AI…...

新手怎么安装OpenClaw?2026年新手10分钟部署OpenClaw及百炼APIKey配置指南

新手怎么安装OpenClaw?2026年新手10分钟部署OpenClaw及百炼APIKey配置指南。OpenClaw(原Clawdbot)作为2026年主流的AI自动化助理平台,可通过阿里云轻量服务器实现724小时稳定运行,并快速接入钉钉,让AI在企业…...

从引脚定义到PCB布线:硬件工程师的SATA接口设计避坑指南(附信号完整性实测)

从引脚定义到PCB布线:硬件工程师的SATA接口设计避坑指南(附信号完整性实测) 在当今数据驱动的硬件设计中,SATA接口依然是存储设备连接的中坚力量。作为一名经历过无数次深夜调试的硬件工程师,我深知一个看似简单的SATA…...

Linux依赖冲突实战:deepin-wine疑难杂症排查指南

1. 当deepin-wine遇上依赖地狱:报错现场还原 第一次在Ubuntu上安装deepin-wine时,那个满屏飘红的依赖错误让我至今记忆犹新。终端里不断刷新的"但是它将不会被安装"提示,像极了游戏里的连环陷阱。这类问题通常发生在混合安装32位/6…...

AGX Orin 部署PyTorch生态:从JetPack适配到torchvision编译避坑指南

1. AGX Orin开发环境初始化 刚拿到AGX Orin开发套件时,很多开发者会直接开始安装PyTorch,但往往忽略了基础环境配置的重要性。我去年在部署一个工业质检项目时就踩过这个坑——当时为了赶进度跳过了JetPack版本检查,结果导致后续torchvision编…...

为什么芯片工程师都在学Chisel?从Verilog到高级硬件设计的跃迁指南

为什么芯片工程师都在学Chisel?从Verilog到高级硬件设计的跃迁指南 在半导体行业,设计效率正成为决定产品成败的关键因素。传统Verilog开发中,工程师们常常需要花费70%的时间调试RTL代码中的低级错误,而非专注于架构创新。这种现状…...

ESP32自动登录校园网实战:绕过网页认证,实现设备永久在线(附完整Arduino代码)

ESP32校园网自动登录全攻略:从逆向分析到模块化封装 校园网环境下的IoT设备部署常面临一个棘手问题——每次断电重启后都需要手动登录网页认证系统。想象一下凌晨三点实验室的温湿度监测系统突然掉线,而你不得不顶着寒风跑去教学楼重新登录的场景。本文将…...

Multisim中在一个项目中添加多页

Multisim中在一个项目中添加多页 新建多页 新建支电路 参考 Multisim电路模块化设计的三种方式_multisim模块封装-CSDN博客 Multisim创建子电路图-百度经验...

Multisim仿真固定偏置电路

Multisim仿真固定偏置电路 Multisim软件版本 依次点击帮助→关于 NI Multisim 14.0 Multisim Power Pro Edition Multisim中绘制电路图 元器件 电源VCC VCCNPN晶体管 BJT_NPN 2N2222A偏置电阻RB Resistor集电极电RC Resistor接地GND DGND 仿真 万用表测量电压结果 电流测…...

IDM激活开源工具:永久使用Internet Download Manager的完整指南

IDM激活开源工具:永久使用Internet Download Manager的完整指南 【免费下载链接】IDM-Activation-Script IDM Activation & Trail Reset Script 项目地址: https://gitcode.com/gh_mirrors/id/IDM-Activation-Script 当你发现下载工具突然停用&#xff0…...

3步解锁群晖Photos人脸识别:让DS918+等设备重获AI能力

3步解锁群晖Photos人脸识别:让DS918等设备重获AI能力 【免费下载链接】Synology_Photos_Face_Patch Synology Photos Facial Recognition Patch 项目地址: https://gitcode.com/gh_mirrors/sy/Synology_Photos_Face_Patch 还在为群晖DS918、DS3615xs等设备无…...

解决RDK X5(ARM64架构)板卡Remote-SSH运行Antigravity AI崩溃(SIGILL):Samba网络盘本地挂载方案

一、前言最近在折腾 D-Robotics 的 RDK X5 板卡(搭载 Sunrise X5 芯片,ARM Cortex-A55 架构)。在尝试使用强大的 Antigravity IDE 通过 Remote-SSH 远程连接板卡进行开发时,遇到了一个极其头疼的问题:AI 侧边栏完全不可…...

C++资源控制哲学:从push_back与emplace_back看左值右值

一、从问题开始std::vector<Person> people; Person bob("bob", 22);people.push_back(bob); // 左值 people.push_back(Person("alice", 25)); // 右值 people.emplace_back("charlie", 30); // 直接构造为什么需要这么多插入…...

OpenClaw、Agent、Skill、MCP 深度解读与区分分析

引言&#xff1a;AI从"对话"到"行动"的范式转移在人工智能的发展历程中&#xff0c;我们正经历一场深刻的范式转移。传统的AI工具&#xff08;如早期ChatGPT&#xff09;主要扮演"建议者"角色&#xff0c;能生成文本、提供建议&#xff0c;但无法…...

WorkBuddy 实用培训课程内容体系:从入门到精通的“数字员工”养成指南

构建的 WorkBuddy&#xff08;基于OpenClaw架构&#xff09;实用培训课程内容体系。本体系深度解构了OpenClaw的技术原理、生态应用与安全实践&#xff0c;旨在培养具备专业能力的“数字员工”管理者与开发者。课程前言&#xff1a;AI 范式转移——从“建议者”到“执行者”在人…...

APM基础概念普及:应用性能管理的全面解析

在当今数字化时代&#xff0c;企业应用的性能直接影响着用户体验和商业成功。应用性能管理&#xff08;Application Performance Management&#xff0c;APM&#xff09;作为保障应用稳定运行的关键技术&#xff0c;已成为现代IT运维不可或缺的工具。本文将全面解析APM的基础概…...

夸克网盘自动化助手:彻底告别手动转存的智能管理方案

夸克网盘自动化助手&#xff1a;彻底告别手动转存的智能管理方案 【免费下载链接】quark_auto_save 夸克网盘签到、自动转存、命名整理、发推送提醒和刷新媒体库一条龙 项目地址: https://gitcode.com/gh_mirrors/qu/quark_auto_save 还在为每天重复的夸克网盘转存操作而…...

解锁Intel GPU的CUDA能力:从零开始的跨硬件计算实践

解锁Intel GPU的CUDA能力&#xff1a;从零开始的跨硬件计算实践 【免费下载链接】ZLUDA CUDA on non-NVIDIA GPUs 项目地址: https://gitcode.com/GitHub_Trending/zl/ZLUDA 当实验室电脑只有Intel集成显卡却需要运行CUDA加速程序时&#xff0c;当笔记本的Iris Xe显卡面…...

入门首选:8bit逐次逼近型SAR ADC电路设计成品,基于SMIC 0.18工艺,3.3V供...

8bit逐次逼近型SAR ADC电路设计成品 入门时期的第三款sarADC&#xff0c;适合新手学习等。 包括电路文件和详细设计文档。 smic0.18工艺&#xff0c;单端结构&#xff0c;3.3V供电。 整体采样率500k&#xff0c;可实现基本的模数转换&#xff0c;未做动态仿真&#xff0c;文档内…...

脉冲注入法与电感法无刷电机BLDC控制器方案

脉冲注入法&#xff0c;持续注入&#xff0c;启动低速运行过程中注入&#xff0c;电感法&#xff0c;ipd&#xff0c;力矩保持&#xff0c;无霍尔无感方案&#xff0c;媲美有霍尔效果。 bldc控制器方案&#xff0c;无刷电机。 提供源码&#xff0c;原理图。一、文档引言 本文基…...

基于注意力机制的多尺度卷积神经网络在滚动轴承故障诊断中的应用

基于注意力的多尺度卷积神经网络轴承故障诊断 针对传统方法在噪声环境下诊断精度低的问题&#xff0c;提出了一种多尺度卷积神经网络的滚动轴承故障诊断方法 首先&#xff0c;构建多尺度卷积提取不同尺度的故障特征&#xff0c;同时引入通道注意力自适应地选择包含故障特征的通…...

无人船编队 无人车编队 MPC 模型预测控制 多智能体协同控制 一致性 MATLAB 无人车 USV

无人船编队 无人车编队 MPC 模型预测控制 多智能体协同控制 一致性 MATLAB 无人车 USV 带原文献一、代码核心定位与应用场景 本套MATLAB源码针对自主水下航行器&#xff08;AUV&#xff09;、无人船&#xff08;USV&#xff09;、无人车等多智能体系统&#xff0c;实现了基于事…...

MDIN380芯片高清视频处理方案:SDI转VGA与LVDS转换,专业PCB设计与源码集成

MDIN380 SDI转VGA 转LVDS VGA转SDI 高清视频处理 MDIN380芯片 PCB代码方案资料 3G-SDI转VGA ?3G-SDI转LVDS ?高清视频 MDIN380、GV7601 芯片方案(PCB图和源码)。 此方案是韩国视频处理芯片MDIN380的整合应用方案。 3G-SDI转VGA或3G-SDI转LVDS。 方案共有两块电路板(一块底板…...

字符串题目

字符串输入char s[10];fgets(s,10,stdin);int lenstrlen(s);if(s[len-1]\n){s[len-1]0;}len--;拼数#include <stdio.h> #include <string.h>#define MAX 100005char res[MAX][20]; int n;int cmp(const void *a,const void *b) {char *pa(char*)a;char *pb(char*)b…...

如何快速掌握DownKyi:从新手到专家的完整视频下载指南

如何快速掌握DownKyi&#xff1a;从新手到专家的完整视频下载指南 【免费下载链接】downkyi 哔哩下载姬downkyi&#xff0c;哔哩哔哩网站视频下载工具&#xff0c;支持批量下载&#xff0c;支持8K、HDR、杜比视界&#xff0c;提供工具箱&#xff08;音视频提取、去水印等&#…...

RK3399 DRM显示框架实战:从零开始搭建多图层视频播放器

RK3399 DRM显示框架实战&#xff1a;从零构建多图层视频播放器 在智能终端设备开发领域&#xff0c;如何高效实现多媒体内容的叠加显示一直是工程师们面临的挑战。想象一下&#xff0c;当我们需要在教育平板上同时播放教学视频、展示动态课件和实时标注内容时&#xff0c;传统的…...