手势识别与眼动追踪交互设计

本文讲解 XR 中手势识别与眼动追踪的交互设计,回答手部追踪能做什么不能做什么、手势怎么从关节点判定、注视加捏合为何成为默认范式、Midas Touch 问题怎么消解等实战问题。覆盖手部数据模型与关节点、模板匹配与分类器两条手势路线、捏合与抓取的实现、手部追踪的遮挡与抖动、眼动输入化、注视加捏合、消歧策略、疲劳与无障碍,并给出代码、对比表、权衡与常见坑。

引言

XR 交互的终极形态是「没有控制器」:手就是输入设备,眼睛就是光标。这条路在硬件上已经走通(Quest 3、Vision Pro 都支持手部与眼动追踪),但在交互设计上远未成熟,因为手和眼睛的物理特性与鼠标键盘完全不同。

工程上的三个核心矛盾:手部追踪精度不足以做精细操作(抖动、遮挡、深度歧义)、注视不等于意图(Midas Touch 问题)、长时间举手会疲劳(Gorilla Arm)。任何忽略这三点的设计,演示时惊艳,实际使用十分钟就会被用户放弃。

本文按「手部原理 → 数据模型 → 手势识别 → 手部限制 → 眼动输入化 → 注视加捏合 → 消歧 → 协同设计 → 疲劳与无障碍」的顺序展开,重点给出可实现的判定逻辑与调参经验。手部与眼动的硬件原理见 XR 显示光学与头部眼动追踪 ,接入 Unity 的具体组件见 Unity XR Interaction Toolkit 交互体系 。

目录

  1. 手部追踪的技术原理
  2. 手部数据模型与关节点
  3. 手势识别的两条路线
  4. 关键手势的实现
  5. 手部追踪的工程限制
  6. 眼动追踪的输入化
  7. 注视加捏合范式
  8. Midas Touch 与消歧
  9. 眼动的其他用途
  10. 手眼协同设计
  11. 疲劳与无障碍
  12. 评估与调参
  13. 权衡取舍
  14. 常见坑清单
  15. 小结

1. 手部追踪的技术原理

主流手部追踪是基于单目或多目相机的关节点回归,而不是戴手套的传感方案:

输入:头显侧向/下向摄像头图像(Quest 3 有 2 个手部相机)
模型:CNN 主干 + 关节点热力图回归(或直接回归 3D 坐标)
输出:21 个关节点的 3D 位置 + 置信度
频率:通常 30~60 Hz(低于头部追踪的 1000 Hz)

模型结构上,主流方案沿用了人体姿态估计的思路:用 CNN 提取特征,再回归关节热力图,最后通过 PnP 或直接回归得到 3D 坐标。单目方案的深度本质上是估计值,这正是手部追踪在 Z 方向精度差的根源。相关的视觉算法基础可参考 Vision Transformer 与视觉骨干 与 目标检测与 YOLO 系列工程落地 。

2. 手部数据模型与关节点

OpenXR 与各平台统一使用 21 关节点模型(每只手):

0  Wrist          手腕
1  ThumbMetacarpal
2  ThumbProximal
3  ThumbDistal
4  ThumbTip
5  IndexMetacarpal
6  IndexProximal
7  IndexIntermediate
8  IndexDistal
9  IndexTip
10 MiddleMetacarpal
11~14 Middle*
15 RingMetacarpal
16~19 Ring*
20 PinkyMetacarpal
21 Pinky*  (不同实现略有差异,主流为 26 点含指尖)

Unity 侧通过 XRHandSubsystem 读取:

// 读取关节点位姿
var subsystem = hands[0];
if (subsystem.leftHand.isTracked) {
    var joint = subsystem.leftHand.GetJoint(XRHandJointID.IndexTip);
    if (joint.TryGetPose(out Pose pose)) {
        Vector3 tipWorld = pose.position;   // 世界坐标
        Quaternion rot = pose.rotation;
    }
}

工程要点:

  • 必须检查 isTracked:手出画或被遮挡时位姿会变成零值或残留旧值。
  • 置信度字段:部分平台提供每关节置信度,低置信度关节应做平滑而非直接使用。
  • 坐标空间:位姿相对哪个参考空间(local / local-floor)要明确,否则手会出现在错误高度。

2.1 手部追踪的性能特征

指标典型值说明
更新频率30~60 Hz低于头部追踪,快速挥动会「拖影」
端到端延迟30~80 ms明显高于手柄
关节数21~26平台差异,注意统一
深度误差1~5 cm单目估计,前后方向最差
视野覆盖约 60° 锥体头显正前方
算力占用移动端 1~3 ms/帧与渲染争抢预算

延迟 30 到 80 ms 意味着快速挥手时手的位置会明显滞后,因此手势判定不能只看瞬时姿态,要结合运动轨迹做预测或加宽判定窗口。

3. 手势识别的两条路线

从关节点到「捏合」「握拳」这类语义,有两条路线:

路线方法优点缺点
几何规则关节点距离/角度阈值无训练、可解释、低延迟泛化差、需手调
模板匹配与录制姿态比对实现简单对速度与姿态敏感
分类器特征 + 小型 MLP/SVM泛化好需采集数据
端到端图像直接输出手势最鲁棒算力与数据需求高

实践中 90% 的场景用几何规则就够了,因为 XR 需要的手势种类很少(捏合、握拳、指向、张开、点赞),而规则法的延迟最低、最可控。

// 几何规则:捏合判定
bool IsPinching(XRHand hand, float threshold = 0.02f) {
    if (!TryTip(hand, XRHandJointID.ThumbTip, out var thumb)) return false;
    if (!TryTip(hand, XRHandJointID.IndexTip, out var index)) return false;
    float d = Vector3.Distance(thumb, index);
    // 用相对手掌宽度的比例而非绝对值,适配不同手型
    float scale = PalmWidth(hand);
    return d / scale < threshold;
}

用相对比例而非绝对距离是关键:不同人的手大小差异可达 40%,用绝对阈值会导致「大手用户永远捏不上、小手用户一直触发」。

3.1 分类器路线的最小实现

当手势种类变多(超过 6 到 8 种)时,规则法会变得难以维护,此时改用小型分类器:

import numpy as np

def features(joints):
    # joints: (21, 3) 关节点,以手腕为原点、手掌尺度归一化
    wrist = joints[0]
    local = joints - wrist
    scale = np.linalg.norm(joints[9] - joints[0])  # 中指指尖距离
    local = local / (scale + 1e-6)
    # 归一化后展平成 63 维特征
    return local.flatten()

分类器本身极小:63 维输入、隐藏层 64、输出 N 类,移动端单帧推理通常低于 0.2 ms,不会成为瓶颈。

要点:

  • 必须归一化:以手腕为原点消除位置差异,以手掌尺度消除手型差异,否则分类器会把「大手张开」识别成「小手握拳」。
  • 时序信息:单帧特征无法区分「正在捏合」与「已经捏住」,需叠加最近若干帧形成时序特征,或对分类结果做时间平滑(连续 N 帧同类才确认)。
  • 类别不平衡:静态手势容易采集,动态手势难采集,训练时需按类加权。

4. 关键手势的实现

各手势的判定依据与阈值参考:

手势判定依据参考阈值
捏合(Pinch)拇指尖与食指尖距离小于手掌宽度的 25%
握拳(Fist)四指指尖到手腕距离均小于手掌宽度的 60%
指向(Point)食指伸展,其余弯曲食指伸直度大于 0.8
张开(Open Palm)五指均伸展五指伸直度均大于 0.7
捏合保持捏合持续时长大于 300 ms
伸直度(Extension)定义:
  对每个手指,计算指尖到手腕的距离与
  「完全伸直时指尖到手腕的距离」之比
  1.0 = 完全伸直,0.5 = 弯曲

4.1 抖动抑制

原始关节点抖动明显,直接用于交互会「跳」,必须做滤波:

// 指数平滑(一阶低通)
Vector3 Smooth(Vector3 current, ref Vector3 state, float alpha) {
    state = Vector3.Lerp(state, current, alpha);   // alpha 取 0.3~0.5
    return state;
}

滤波的代价是延迟:alpha 越小越平滑但越滞后。交互关键点(指尖)用较大 alpha 保响应,非关键点用较小 alpha 保稳定,是常见的折中做法。

5. 手部追踪的工程限制

必须认清的四个限制:

  1. 深度精度差:单目估计的 Z 误差可达数厘米,前后移动的交互(如推拉)不可靠。
  2. 视野边界:手离开摄像头视野即丢失,头部正前方约 60 度范围外追踪质量骤降。
  3. 遮挡歧义:手指互相遮挡时关节点会「穿透」,表现为手指穿过手掌。
  4. 双手交叉:两手重叠时容易串台,左手关节点被识别为右手。

对应的设计对策:

深度差      → 避免依赖前后移动的交互,改用捏合/张开
视野边界    → 交互区域限制在头显正前方 45 度锥体内
遮挡歧义    → 关键手势(捏合)不依赖被遮挡的关节
双手交叉    → 避免设计需要双手重叠的操作

6. 眼动追踪的输入化

眼动的精度与延迟在近年已达到「可做输入」的水平:

指标消费级高端
精度1.5~3°0.5~1.5°
采样率60~90 Hz90~120 Hz
延迟20~50 ms10~20 ms
标定耗时5~15 s自动,几乎无感

眼动作为输入的核心价值是「定位」而不是「确认」。人眼可以在 100 ms 内跳到目标,比手快得多;但眼睛无法表达「我要选它」,必须配合第二通道(捏合、停留、语音)确认。这一分工是理解所有眼动交互设计的基础。

眼动能力边界:
  定位快   → 适合做「指向」
  无法确认 → 必须配第二通道
  会扫视   → 需要「停留时长」或意图预测过滤
  精度有限 → 目标不能太小(视角 2° 以上)

6.1 眼动信号预处理

原始注视点必须过滤才能当输入用:

三类噪声:
  微颤(Tremor)  : 高频小幅抖动,1~2° 幅度,需低通滤除
  微跳(Microsaccade): 快速小幅跳动,< 1° 但速度高
  眨眼(Blink)    : 数据中断,需插值或标记无效

处理链:
  1. 无效帧剔除(置信度为 0 或数据中断)
  2. 中值滤波(窗口 3~5 帧)去脉冲噪声
  3. 一阶低通平滑(alpha 0.3~0.5)
  4. 扫视检测(速度阈值 30~100 °/s),扫视期间不触发选择

扫视检测很关键:人眼在扫视(Saccade)期间几乎不获取视觉信息,此时不应触发选择。加入扫视过滤后,误触发率通常能下降一半以上。

7. 注视加捏合范式

Gaze + Pinch 是目前公认最优的组合,也是 Vision Pro 的默认交互:

工作流:
  1. 眼睛看向目标 → 系统高亮候选
  2. 手指轻轻捏合(手可以自然放在腿上)
  3. 系统确认选择

为什么好:
  手不需要抬起(避免 Gorilla Arm)
  眼不需要精确停在目标上(捏合瞬间的注视点已足够)
  两者时间上解耦(可以先看再捏)

实现要点:

// 选择时取「捏合发生前 N 帧」的注视点,而非捏合瞬间
// 因为捏合动作本身会分散注意力,注视点可能已偏移
Vector3 GetSelectionGaze() {
    int idx = Mathf.Max(0, gazeHistory.Count - 5);   // 前 5 帧
    return gazeHistory[idx];
}

取历史注视点而非即时注视点是关键技术细节:捏合的物理动作会让人不自觉地移开视线,用即时注视点会导致选错目标。

8. Midas Touch 与消歧

Midas Touch 问题指「用户看向某物就被触发」,导致误操作。四种消歧策略:

策略机制优点缺点
停留时长注视超过 400~800 ms 触发无需第二通道慢,长列表累
第二通道确认捏合/按键/语音准确需另一只手
意图预测用眼动模式判断意图快准确率有限
显式激活进入「选择模式」后才响应可控模式切换成本

工程推荐是「第二通道确认」为主、「停留时长」为兜底:有手时用捏合,手不可用时退化为停留。停留时长建议 600 ms 起步,且必须配合进度指示器(环形进度条),否则用户不知道系统在等什么。

停留触发的可用性要点:
  必须显示进度反馈(否则用户会重复注视)
  目标不能太小(视角 3° 以上,否则注视点抖动导致离开)
  需要「离开取消」而非「一直累积」
  相邻目标间距要大于注视精度(避免误触发邻居)

9. 眼动的其他用途

除了选择,眼动还有四类高价值用途:

  • 注视点渲染:直接省 30% 到 50% GPU,见 一体机 XR 性能优化实战 。
  • 注意力分析:统计用户在看什么,用于内容优化与广告效果评估(注意隐私合规)。
  • 自动滚动:阅读长文本时按注视位置滚动,解放双手。
  • 化身眼部动画:社交 VR 中用眼动驱动 Avatar 的眼球与眨眼,显著提升真实感。
隐私红线:
  眼动数据属生物特征,多数司法辖区视为敏感信息
  必须明示采集目的、提供关闭选项、做匿名化
  不要将原始眼动轨迹上传云端

10. 手眼协同设计

把手和眼放在一起设计,而不是各自独立:

任务主通道辅通道说明
菜单选择眼捏合快速定位 + 确认
物体抓取手眼手精确操作,眼提供目标
远距离移动眼手柄注视目标点后传送
文本输入眼手/语音眼选键位,手确认
精细调整手眼手做微调,眼做校验

设计原则:用眼睛做「选哪里」,用手做「怎么做」。违反这条原则的设计(例如用手做长距离指向)会同时牺牲速度与舒适度。

10.1 交互区域的划分

把空间按舒适度分层,内容放置与交互设计都遵循这个分层:

┌─────────────────────────────────────┐
│  近场(0.3~0.7 m)                   │
│  手可及,直接抓取;视线自然聚焦        │
│  适合:手持物体、精细操作              │
├─────────────────────────────────────┤
│  中场(0.7~2.5 m)                   │
│  射线可达,注视选择;无需抬臂          │
│  适合:菜单、按钮、列表                │
├─────────────────────────────────────┤
│  远场(> 2.5 m)                     │
│  需注视或传送;手部追踪不可用          │
│  适合:导航目标、环境内容              │
└─────────────────────────────────────┘

中场是最舒适的交互区:可以用眼加捏合完成,手不必抬起。因此菜单、按钮这类高频操作应放在 1 到 2.5 米处,而不是贴在手上或放到远处。

11. 疲劳与无障碍

Gorilla Arm(大猩猩手臂) 是指手臂长时间悬空导致的酸痛,是免手柄交互最大的敌人。量化参考:

手臂前伸持物 1 分钟 → 肩部开始疲劳
手臂前伸持物 5 分钟 → 明显酸痛,动作精度下降
手臂自然下垂     → 可持续数小时

因此设计上应尽量让手处于自然下垂或搭在腿上的位置(Vision Pro 的做法),只在需要时抬起到交互区。

无障碍考虑:

  • 运动能力受限用户:必须提供不依赖精确手部动作的路径(语音、注视停留、头部指向)。
  • 色觉障碍:交互反馈不能只靠颜色,要加形状与音效。
  • 听力障碍:音效反馈必须有视觉替代。
  • 单手用户:所有操作应能用单手完成,不做双手强制手势。

12. 评估与调参

交互参数不能拍脑袋,要实测:

关键指标:
  首次成功率(First-try Success Rate)→ 目标 > 95%
  选择耗时(Time to Select)          → 目标 < 1.5 s
  误触发率(False Trigger Rate)      → 目标 < 2%
  疲劳自评(Borg CR10)               → 10 分钟使用后 < 3
  学习成本(首次使用达到熟练的尝试次数)→ < 5 次

方法:
  招募 8~12 名非开发者,做任务式测试
  记录成功率与耗时,而非只问「好不好用」

经验上,手势阈值需要在至少 8 名不同手型的测试者上标定,否则会偏向开发者自己的手型。

13. 权衡取舍

  • 几何规则与分类器:前者零训练、低延迟、可解释,后者泛化好但需数据,手势少时选前者。
  • 停留触发与捏合确认:前者无需第二通道但慢,后者快但要求手可用,常两者共存。
  • 高精度眼动与低成本眼动:前者支撑 DFR 与精细交互,后者只够做粗略注视,按场景选。
  • 滤波强度:强滤波稳定但滞后,弱滤波响应快但抖动,按交互类型分别设置。
  • 双手手势与单手设计:双手表达力强但要求双手可见,无障碍与稳定性都更差。
  • 眼动数据采集与隐私:采集提升体验但增加合规成本,必须明示并提供关闭项。

14. 常见坑清单

  • 用绝对距离判定捏合:不同手型差异大,必须用相对比例。
  • 不检查 isTracked:手出画后用残留位姿,物体乱飞。
  • 手部关键点不滤波:指尖抖动导致射线乱跳,体验崩坏。
  • 依赖前后移动的交互:单目深度估计误差大,推拉不可靠。
  • 注视即触发:Midas Touch 导致误操作,必须加确认或停留。
  • 取捏合瞬间的注视点:动作本身使视线偏移,应取历史帧。
  • 停留无进度反馈:用户不知系统在等待,重复注视造成抖动。
  • 要求长时间举手:Gorilla Arm 导致 5 分钟内放弃,应支持手放腿上。
  • 只用颜色做反馈:色觉障碍用户无法区分,需加形状与音效。
  • 阈值只用开发者手型调:上线后大量用户无法触发,必须多手型标定。

15. 小结

手眼交互的工程主线是:手部用几何规则做少量高价值手势(捏合为主)→ 用相对比例与滤波保证稳定性 → 眼动负责快速定位 → 用捏合或停留做确认 → 让手保持自然下垂 → 多手型标定阈值。核心洞见是「眼睛选哪里、手决定怎么做」,把两者放在各自擅长的维度上。

三个最容易见效的改动:捏合判定改用相对比例、注视选择取历史帧、允许手自然下垂。这三项通常能把首次成功率从 80% 提升到 95% 以上。

交互的舒适度约束在 VR 舒适度与晕动症工程对抗 里进一步展开;若要做空间中的内容持久化,读 空间锚点与跨会话持久化 。

延伸阅读

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「AR 与 VR」更多文章

  1. XR 培训与仿真应用
  2. XR 控制器与输入设备
  3. XR 内容分发与商店上架