资讯动态

头部姿态估计:欧拉角、旋转矩阵与PnP/端到端回归实践

发布时间:2026/10/28 3:31:27 来源:尧图企业网站定制
简介面向计算机视觉与深度学习方向的研究者和开发者这份头部姿态估计专题文献包聚焦从图像或视频推断头部三维角度与位置的核心问题覆盖虚拟现实、自动驾驶、智能监控与人机交互等应用背景。包内共5个文件以4篇PDF论文和1份XML文档为主压缩包约13.11MBPDF便于系统阅读方法细节XML文档则补充结构化信息方便归档检索。已有352人学习下载具备一定领域关注度。内容涉及卷积网络与迁移学习、传统特征与深度特征、3D几何模型、开源代码、MSE与角度误差等评估标准也讨论光照、遮挡、表情变化带来的挑战及未来趋势其中无关键点细粒度估计、四元数姿态回归、野外场景姿态估计等代表性工作可帮助读者快速梳理2015—2018年前沿进展为算法选型、实验设计和项目落地提供参考。1. 头部姿态估计为什么“三个角度”比一整张人脸更难估头部姿态估计head pose estimation常被当作人脸检测的附赠功能人脸框已经出来了顺便回归三个角度就行。实际顺序恰好相反检测框偏几个像素没人在意姿态偏 10° 在注意力判断里就是完全相反的结论。更麻烦的是输出空间——yaw 从 179° 到 −179° 只差 2°数值上却是 358 的跳变roll 接近 ±90° 时另外两个角开始互相纠缠。这类“标签本身带拓扑结构”的回归任务损失函数、数据分布、后处理三个位置都容易出错而且错误很隐蔽loss 曲线看起来很漂亮指标就是上不去。下面按“角度怎么表示 → 两条路线怎么算 → 标签怎么造 → 哪里会出错”的顺序拆开。2. 旋转的三种写法欧拉角为什么会在 ±180° 处翻车网络吐出三个浮点数标签也是三个浮点数看起来就是最普通的回归问题搭个 L2 损失就能训。前几个 epoch 的 loss 确实降得漂亮然后验证集 MAE 卡在 9° 附近不动某几个样本的预测值还会在 170° 和 −170° 之间来回跳。这不是模型容量不够是欧拉角这种表示方式本身的问题——它把一个环形的连续空间强行拉直成一条线段头尾接不上。头部姿态的欧拉角约定通常是 yaw绕垂直轴左右转头、pitch绕横轴点头、roll绕前后轴歪头。三个角的组合顺序必须显式固定是 XYZ 还是 ZYX是内旋绕自身轴还是外旋绕世界轴结果完全不同。同一组角度值换一种顺序解释画出来的姿态能差出几十度。很多“训练正常但精度就是不行”的现场最后都挖出标签生成端和训练端的顺序不一致。这件事没有中间态要么对齐要么全线崩。2.1 万向节锁与角度回绕L2 损失在边界处发生了什么先说回绕。标签是 179°预测是 −179°肉眼一看只差 2°但 L2 给出的惩罚是 (358)²比预测成 0° 的惩罚大三个数量级。网络为了降低平均损失会做一件很“聪明”的事把所有接近边界样本的预测往 0 的方向拉。结果就是边界附近的样本被系统性地压扁模型在大角度上永远欠拟合。这个问题在训练集里大角度样本少的时候格外明显因为梯度被大量正面样本稀释了少数边界样本的异常梯度只表现为“训练有点抖”。再说万向节锁。当 pitch 接近 ±90° 时yaw 轴和 roll 轴在空间上重合三个自由度退化成两个同一个姿态对应无穷多组 (yaw, roll) 组合。此时标签在数值上是不唯一的网络面对完全相同的输入却被要求输出不同的值只能学出一个“平均值”误差天然存在。真实场景里人很少把头顶到 90°但合成数据会——随机采样姿态时如果不做限制一定会造出贴着奇异点的样本然后这些样本就成为训练集里的噪声源。还有个更不易察觉的点同样的角度误差在不同姿态下代表的物理偏差不一样。yaw 差 5° 在正面时只是轻微偏头在侧脸 80° 时可能意味着关键点已经完全跑到轮廓另一侧。用统一的 L2 损失等于假设整个姿态空间的误差是等价的这个假设本身就不成立。2.2 SO(3) 上的测地线距离把损失定义在旋转矩阵上绕开这个问题的办法是换表示。旋转矩阵 R 是 3×3 正交阵、行列式为 1它和真实旋转一一对应没有奇异点也没有回绕。两个旋转之间的“角度差”可以直接算R_pred 转置乘 R_gt 得到一个相对旋转它的迹和旋转角 θ 满足 tr 1 2cos θ。这个 θ 就是测地线距离也是真正该被优化的量。import numpy as np def geodesic_loss(R_pred, R_gt, eps1e-7): # R_pred / R_gt: (N, 3, 3)都是合法的旋转矩阵 # tr(R_pred^T R_gt) 1 2 * cos(theta) Rt np.transpose(R_pred, (0, 2, 1)) trace np.trace(np.matmul(Rt, R_gt), axis11, axis22) cos_theta np.clip((trace - 1.0) / 2.0, -1.0 eps, 1.0 - eps) return np.mean(np.arccos(cos_theta)) # 返回弧度 def chordal_loss(R_pred, R_gt): # Frobenius 弦距离与测地线单调等价但没有 arccos 的梯度奇点 return np.mean(np.linalg.norm(R_pred - R_gt, axis(1, 2)))geodesic_loss里的eps截断不能省。arccos 的导数是 −1/√(1−x²)当两个旋转几乎相同时 x→1梯度直接冲向无穷大。训练初期预测值还很随机问题不大到了收敛阶段大量样本的 θ 接近 0这个梯度尖峰会让优化器反复越过最优点表现为 loss 在最后一位小数上抖个不停。chordal_loss是工程上更常用的替代弦距离是测地线的单调函数最小值位置一样但它在 θ0 和 θπ 两端都平滑梯度有界。用旋转矩阵当回归目标还有个隐性成本网络要输出 9 个数而这 9 个数必须满足正交约束。直接回归再做事后正交化SVD 取最近的正交阵是常见做法但正交化本身不可导训练和推理之间会有一道缝。比较讲究的实现会在损失里加一项正交性惩罚或者干脆用四元数。四元数是 4 维单位向量天然满足约束代价是双覆盖——q 和 −q 表示同一个旋转直接对四元数做 L2网络会在符号翻转的位置收到巨大惩罚。处理办法是取内积的绝对值或者训练前按符号对齐。提示如果沿用弦距离训练评估时仍然要用 arccos 算出真实角度误差再报指标。弦距离的数值没有物理单位直接当 MAE 报出去会得到一个看起来很小但毫无意义的数字。2.3 分 bin 分类加期望回归工程上最稳的折中还有一条路把连续回归改造成分类。把 360° 切成若干个 bin网络输出每个 bin 的概率推理时取 softmax 期望当作角度值。这个思路朴素但极其有效因为它从根上消灭了回绕179° 和 −179° 落在相邻的两个 bin 里分类损失完全不知道它们数值上差了 358只当是两个不同的类别。import numpy as np BIN_WIDTH 3.0 # 每格 3 度 NUM_BINS int(360 / BIN_WIDTH) # 120 个 bin覆盖整个圆周 def bin_centers(): # bin i 的中心角度映射到 [-180, 180) return (np.arange(NUM_BINS) 0.5) * BIN_WIDTH - 180.0 def to_bin_index(angle): # 连续角度 - bin 索引取模保证 179.9 和 -179.9 落在相邻 bin idx np.floor((angle 180.0) / BIN_WIDTH).astype(np.int64) % NUM_BINS return idx def soft_argmax_angle(logits): # logits: (N, NUM_BINS) logits logits - logits.max(axis1, keepdimsTrue) p np.exp(logits) p p / p.sum(axis1, keepdimsTrue) # 每个样本一个 120 维分布 centers bin_centers()[None, :] return (p * centers).sum(axis1), p # 期望角 分布本身期望回归的精度能超出 bin 宽度前提是概率分布跨两个相邻 bin 呈钟形——此时加权平均会落在两个 bin 中心之间。但如果网络训得太“自信”分布尖锐地集中在一个 bin 里输出就只能等于该 bin 的中心值精度退化到 BIN_WIDTH 的一半。所以实践里会在期望值后面再接一个残差回归头最终角度 期望角 残差残差只需要在 ±1.5° 的小范围内学习难度低得多。代价是这套方案会多出两件事bin 数量和 bin 宽度的权衡bin 太细分类样本不均衡且边界样本多bin 太粗残差头负担重以及相邻 bin 之间的标签平滑——因为角度是连续的把 89.9° 硬打成第 90 个 bin 的 one-hot会让网络在边界处学到不必要的锐利边界。常见的缓解是对相邻两个 bin 做软标签。3. 两条解法关键点加 PnP 与端到端回归各自在算什么损失函数解决了“怎么比”还没解决“从什么算”。目前主流就两条路线一条是先用关键点检测拿到人脸上一组 2D 点再和 3D 模板做配准反解姿态另一条是让网络直接从图像回归角度。这两条路线的误差结构完全不同选型时最该看的不是论文里的平均精度而是误差在什么条件下会失控。3.1 六点 PnP从 2D 关键点反解刚体变换PnPPerspective-n-Point解决的是一个几何问题已知 n 个 3D 点和它们在图像上的 2D 投影求相机的位姿也就是旋转加平移。放到头部姿态上3D 点是人脸模板鼻尖、双眼外角、两嘴角、下巴这些位置固定的参考点2D 点是检测器给出的对应像素坐标。import numpy as np # 3D 人脸模板参考点单位毫米头部坐标系原点取鼻尖 MODEL_POINTS np.array([ [-32.0, 0.0, 0.0], # 左眼外角 [ 32.0, 0.0, 0.0], # 右眼外角 [ 0.0, 0.0, 0.0], # 鼻尖 [-28.0, -35.0, 6.0], # 左嘴角 [ 28.0, -35.0, 6.0], # 右嘴角 [ 0.0, -60.0, 12.0], # 下巴 ], dtypenp.float64) def estimate_head_pose(landmarks_2d, camera_matrix, solver): # landmarks_2d: (6, 2)顺序必须与 MODEL_POINTS 严格一一对应 ok, rvec, tvec solver.solve( object_pointsMODEL_POINTS.reshape(-1, 1, 3), image_pointslandmarks_2d.reshape(-1, 1, 2), camera_matrixcamera_matrix, flagssolver.SOLVEPNP_EPNP, # 闭式解不需要初值不卡局部极小 ) if not ok: return None R, _ solver.rodrigues(rvec) # 旋转向量 so(3) - 旋转矩阵 SO(3) return R, tvec几个参数值得掰开看。MODEL_POINTS的尺度其实不影响旋转结果——把整个模板等比放大等价于把平移量同比缩放旋转的解不变。所以模板用毫米还是用归一化坐标都行但平移向量的物理含义会跟着变做距离判断时不能混用。真正影响旋转精度的是模板里点的相对位置是否贴合真实人脸拿一个成年人的模板去解算儿童的脸或者用中性表情的模板套在夸张表情上会引入系统性偏差。SOLVEPNP_EPNP只需要 4 个以上点就能给出闭式解适合点少、怕初值不好的场景。缺点是闭式解对噪声的抑制能力弱实际部署里常见做法是先用它拿初值再切到迭代法做几轮 LM 精化。迭代法需要至少 6 个点这也是“六点法”这个名字的由来——够用、稳定、代价可控。最容易出错的地方在最后一行。PnP 解出的 R 是“模板坐标系到相机坐标系”的变换而欧拉角该从哪个方向取、图像坐标系 y 轴朝下导致 pitch 符号要不要翻这两件事一旦搞反训练出来的关键点检测器和姿态解算之间就永远差一个转置。验证方法很简单拿一张正面正对相机的图正确解算出来的三个角都应该接近 0如果 pitch 是 180°那就是方向反了取 R 的转置即可。3.2 端到端回归输出维度怎么和坐标系绑定端到端这条路线省掉了模板和内参这两个依赖。骨干网络抽完特征接一个回归头直接出 3 个数或者出 9 个数旋转矩阵再正交化或者出 120×3 个 bin 的 logits 走上一章的期望回归。结构上没有秘密难点全在“网络看到的东西”和“标签定义的东西”之间的一致性上。一个反直觉的点裁剪crop本身不改变头部旋转。把头从整图里裁出来送进网络旋转还是那个旋转所以理论上训练和推理用不同的裁剪策略不会导致标签错误。但实际会——裁剪比例、是否保持长宽比、padding 填什么颜色都会改变网络看到的上下文范围进而改变特征分布。训练时用 1.5 倍人脸框、推理时用 1.2 倍同一个头姿在两种视野下的表观大小和边缘截断情况完全不同模型的输出会系统性偏移几度。这类误差不会在训练日志里暴露只会在换预处理的那次发版后突然出现。回退到前面说的两种表示如果输出欧拉角网络必须在输出层隐式学会“这个角度是环形的”这件事而全连接层做这件事非常吃力所以才会需要 bin 分类那种显式结构。如果输出旋转矩阵回归头要拟合的是 9 个强相关的数值多余的三个自由度会让训练变慢但收敛后的精度往往更稳。另一个容易被忽略的细节是辅助监督。单纯回归角度梯度信号非常稀疏——整张图只有一个监督值。常见做法是加一个关键点热图的辅助分支让骨干网络在学姿态的同时被迫关注五官位置这种多任务结构在小数据集上提升明显。代价是标注成本翻倍而且关键点标注的噪声会同时污染两个任务。3.3 误差来源拆解两条路线分别在什么条件下失控把两种方案的误差拆开看会发现它们应对的是完全不同的场景。维度关键点 PnP端到端回归额外依赖3D 模板、相机内参无大角度表现一侧关键点被遮挡后急剧退化取决于训练集是否有大角度样本精度上限受关键点定位精度限制受标签噪声和分布覆盖限制误差可解释性高能逐点回看低只能看最终角度单帧耗时两段式多一次解算一次前向PnP 的失效模式很集中关键点飘了姿态就飘而且姿态误差和关键点误差之间是放大关系。在 yaw 超过 60° 之后一侧眼睛和嘴角基本不可见检测器只能靠先验“猜”猜出来的点位置偏差可能到 10 个像素以上反解出来的角度直接崩掉。这也是为什么做 PnP 方案时遮挡处理比精度优化更值得投入。端到端回归的失效模式更分散一个方向是长尾分布压不住头部从没偏向某一侧模型就永远学不会那一侧另一个方向是过拟合到背景和光照换一个场景就退化。它没有显式的几何约束兜底所有合理性都来自数据本身。好处是对遮挡更宽容——只要训练集里有足够多的侧脸样本网络能从剩余可见区域推断姿态这一点比 PnP 强不少。4. 标签从哪来合成数据如何把大角度样本造出来头部姿态的标注成本比想象中高。让人工去标一张侧脸图的三维角度误差通常在 5° 到 10°比模型本身的误差还大。所以这个领域长期依赖合成数据做法是把一张正面人脸拟合成可驱动的三维模型然后按已知角度渲染出各个姿态的图像。标签是渲染参数直接给的精确到小数点后好几位。4.1 三维拟合加随机渲染把角度当成生成参数流程大致分三步。先用一个三维形变模型把形状和表情拆成若干基向量通过拟合系数还原具体人脸对输入的正脸做拟合得到带纹理和几何细节的网格。再从一个预设的角度分布里采样一组 (yaw, pitch, roll)对这个网格做刚体旋转。最后用弱透视或者完整透视投影把网格投到图像平面加背景、加光照输出图像和对应的旋转矩阵。采样分布的设计直接决定模型的能力边界。均匀采样看起来公平但会让接近万向节锁的样本占比过高前面说过那批样本的标签本身不稳定。更常见的做法是按区间加权大角度侧脸多给一些样本——因为真实场景里正面样本满地都是侧脸样本稀缺。yaw 覆盖到 ±90° 是基本要求pitch 到 ±45° 就够用了再往上人体的生理结构本身就不自然。这里真正的风险是域间隙。合成图像的纹理来自单张正面照光照模型很简化背景通常是纯色或简单噪声。网络在合成数据上训到 3° 的误差换到真实监控画面里可能直接 15°。业界通行的做法是混合训练合成数据占大头负责覆盖角度空间真实标注数据虽然量少但负责纠正表观分布。再加一层风格增强——随机改光照方向、加运动模糊、贴真实背景——缩小两边的统计差异。还有个不容易发现的问题合成图像里人脸总是居中、尺度统一、几乎不旋转出画面。网络很容易学到“脸在哪”这个捷径而不是真的在看五官形变。一旦推理时人脸偏出画面中心精度就掉。缓解办法是渲染时随机平移和缩放把位置信息打散。4.2 标签对齐一个转置能毁掉整轮训练合成数据的标签是旋转矩阵训练目标可能是欧拉角、四元数或者分 bin 的索引。每一次转换都是一次出错机会而且错了之后模型照样能训只是精度上不去非常难查。需要逐项确认的至少有这几条旋转顺序是 XYZ 还是 ZYX是内旋还是外旋给出的是“世界到相机”还是“相机到世界”两者互为转置欧拉角单位是度还是弧度图像坐标系 y 轴朝下pitch 的正负方向要不要翻转roll 的取值范围是 [−180, 180] 还是 [0, 360]。一个很实用的自检办法构造几个已知答案的极端样本——正脸朝前、纯 yaw 90°、纯 roll 45°——把整条标签流水线跑一遍看输出和预期是否一致。这件事花十分钟能省掉后面两天的排查。我见过最典型的翻车是标签生成端用了“相机到世界”训练端按“世界到相机”解析模型训出来的东西在验证集上看着还行因为验证集走了同一条错误链路一上真实数据整体偏转像是头一直歪着。4.3 指标怎么读MAE 会骗人尤其是在长尾分布上指标衡量什么什么情况下会骗人三角度平均 MAE整体偏移水平正面样本占绝大多数时尾部误差被稀释掉阈值准确率误差 15°工程可用率阈值宽松10° 和 14.9° 都算对掩盖分布形状按 yaw 分桶的 MAE长尾表现桶内样本太少时方差极大单次结果不可信跨数据集 MAE泛化能力两边标签约定不一致时这个数完全没有意义最该警惕的是只报一个平均 MAE。头部姿态的误差分布是典型的长尾正面样本误差 3°侧脸样本误差 20°平均下来 6°看起来很不错但真实业务里出问题的全是那批侧脸。分桶统计加阈值准确率一起看才能判断模型到底能不能用。跨数据集对比还有个前提两个数据集的真值定义得一致。不同来源的标注在坐标系约定、角度范围、甚至“什么算 0°”上都有差异直接相减得到的数字可能大部分来自约定差异而不是模型能力。做跨集评估前先用一批重叠样本对齐一下偏移量或者干脆只用相对排名做比较。5. 排查记录训练不收敛与角度跳变的五个现场下面这些是从实际调试里攒下来的按发生阶段分。每一条都遵循同一个模式先看到什么现象再往下挖到什么原因最后怎么解决的。5.1 训练阶段loss 在降指标不动现象一训练 loss 平稳下降验证集 MAE 卡在 9° 左右怎么调学习率都不动。原因基本可以锁定在标签坐标系上。训练集和验证集的标签来自同一条流水线所以两边一致loss 该降还是降但这条流水线本身可能和图像内容差了一个转置或者一个符号。模型学到的是一个自洽但错误的映射在自家验证集上表现正常换一批数据立刻露馅。解决方式拿十个样本人工确认姿态方向比如“这张是向左转头 30°”然后把预测值打印出来对比。如果发现 yaw 符号全反就是转置问题如果 pitch 恒定偏 180°是旋转方向搞反。确认之后统一在标签生成端修正不要在网络输出端打补丁否则后面每换一个模型都要重新打一次。现象二某些 batch 的 loss 突然飙到正常值的几十倍然后又回落。这是典型的角度回绕。那批样本的标签刚好在 ±180° 附近预测落在另一侧L2 给出了一个天文数字。梯度回传之后把这一批的权重带偏下一个 batch 又拉回来表现为周期性震荡。解决方式把损失换成测地线或者弦距离或者在算 L2 之前先做角度归一化把差值映射到 [−180, 180]。前者更彻底后者改动量小但只对欧拉角有效且归一化本身在边界处不可导还是会留下一个小尖峰。现象三模型在正面样本上误差 3°在侧脸样本上误差 25°且侧脸样本的 loss 几乎不下降。两个可能叠在一起训练集里侧脸样本太少以及侧脸时关键点被遮挡导致特征质量差。前者是分布问题后者是信息问题。解决方式先按 yaw 分桶统计样本量和 MAE确认是不是长尾。如果是加合成数据补足角度分布同时用加权采样让侧脸样本在 batch 里的占比提上来。如果样本量已经够了但误差还是大检查一下裁剪策略——侧脸时人脸框会变得很窄固定比例的 padding 可能把半个头切掉网络看到的信息本来就不完整。5.2 推理与部署换台机器精度就变现象四同一段视频在不同分辨率的摄像头上跑姿态角整体偏移 5° 到 8°。如果走的是 PnP 路线八成是内参没跟着换。相机内参和分辨率强相关换分辨率不重新标定焦距和主点还是旧的解出来的旋转就有系统偏差。如果走的是端到端路线问题出在预处理人脸框的绝对像素尺寸变了缩放之后的表观清晰度和纹理细节跟着变模型没见过这个尺度。解决方式PnP 路线强制要求内参随分辨率一起更新或者干脆用弱透视近似把焦距设成图像宽度的常数倍牺牲一点精度换鲁棒性。端到端路线把预处理固定死——不管输入多大统一 resize 到固定尺寸再裁剪让网络看到的永远是同一种尺度。现象五离线评估 4° 误差上线之后角度高频抖动帧间跳变能到 10°。这是单帧独立预测的必然结果。模型在相邻两帧上的输入差异极小但输出的角度会因为特征里的微小扰动而跳动肉眼看就是“抖”。这不是模型精度问题是缺少时序约束。解决方式加滤波但要注意滤波的对象。直接对欧拉角做低通在 ±180° 附近会炸正确做法是对旋转做平滑——四元数用 slerp 插值旋转向量做加权平均或者干脆对旋转矩阵做正交化后的插值。滤波强度是个取舍下一章细说。6. 平滑的代价实时系统里单帧结果该信几分滤波这件事做与不做带来的效果差得很大但做得过头会把系统变得不可用。我一般用 One Euro 滤波器作为默认起点它的思路是让截止频率随信号速度自适应头不动的时候用很低的截止频率把抖动压死快速转头的时候把截止频率提上来减小相位滞后。import math class OneEuroFilter: def __init__(self, freq30.0, min_cutoff1.0, beta0.02, d_cutoff1.0): self.freq freq # 采样率必须和实际帧率一致 self.min_cutoff min_cutoff # 静止截止频率越小越稳越大越跟手 self.beta beta # 速度系数越大快速运动时滞后越小 self.d_cutoff d_cutoff self.x_prev None self.dx_prev 0.0 staticmethod def alpha(cutoff, freq): tau 1.0 / (2 * math.pi * cutoff) te 1.0 / freq return 1.0 / (1.0 tau / te) def __call__(self, x): if self.x_prev is None: self.x_prev x return x dx (x - self.x_prev) * self.freq a_d self.alpha(self.d_cutoff, self.freq) dx_hat a_d * dx (1 - a_d) * self.dx_prev cutoff self.min_cutoff self.beta * abs(dx_hat) # 速度越大截止频率越高 a self.alpha(cutoff, self.freq) x_hat a * x (1 - a) * self.x_prev self.x_prev, self.dx_prev x_hat, dx_hat return x_hat三个参数各有自己的作用范围。min_cutoff决定静止时的抖动幅度调到 0.5 以下会明显变“肉”转头时像在水里beta决定跟随性调到 0.1 以上基本等于没滤波freq必须和真实帧率对上填错了滤波器的时间常数会整体偏移表现为延迟忽大忽小。这三个数没有普适值得按业务对延迟的容忍度来定——注意力监测能忍 100ms 的滞后交互类场景超过 50ms 用户就能感觉到。真正的取舍在平滑对象上。对欧拉角逐个滤波实现最简单但只要有一个角跨过 ±180°滤波器会把这次跳变当成巨大的速度beta项瞬间把截止频率拉满等于这一帧完全不滤波抖动原样透传。更稳的做法是把旋转转成四元数用 slerp 做插值平滑或者对旋转向量滤波后再转回矩阵——后者在角度接近 180° 时也需要小心因为旋转向量在那附近不是连续的。还有一个不那么技术但更重要的判断什么时候该不平滑。如果系统要判断的是“有没有转头”这种瞬态事件滤波会把事件的上升沿抹平等到输出超过阈值时动作已经发生了。这种场景下我一般会保留一路未滤波的原始值专门喂给事件检测滤波值只用于显示和连续量的统计。两路并行成本很低但能避免那种“看着一直在看路其实已经走神两秒了”的问题。从那以后我每次接头部姿态相关的活都强制先用一批已知姿态的样本把标签流水线走一遍——正脸、纯 yaw 90°、纯 roll 45°三个样本跑通再谈模型。这一步花的时间比后面调参省下来的多得多。希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑