ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

AI+3D人体可视化:从姿态估计到Three.js实时驱动

AI+3D人体可视化:从姿态估计到Three.js实时驱动 最近在开源社区里翻3D人体可视化这个方向发现一个很有意思的变化以前你搜3D human visualization出来的多是静态模型查看器加载一个扫描好的三维网格转一转、看一看顶多再量量尺寸。今年不一样了AI能力被直接塞进了人体可视化的链路里摄像头拍一段视频浏览器里就能把人体姿态、骨骼角度、动作类型实时映射到三维模型上。这类项目在GitHub上越来越多标题里带AI的明显变多说是又一个项目其实就是这个技术拐点的集中体现。这篇文章不打算只贴一个仓库链接我想把这类AI3D人体可视化项目从架构拆解到落地运行完整讲一遍。适合谁看想自己做运动分析、虚拟试穿、数字人动画或者单纯好奇现代浏览器怎么把人体变成三维数据的同学都可以参考。我会把环境配置、核心代码、常见坑位和几个真实场景都交代清楚让零基础的读者也能顺着这个思路把项目跑起来。1. 从展示模型到理解人体这波3D人体可视化项目的进化逻辑1.1 老一批3D人体可视化项目的共同局限如果往回看三四年GitHub上大多数3D人体可视化项目可以概括成三个关键词加载、渲染、交互。输入是一份现成的glTF、OBJ或者FBX格式的人体网格模型项目做的事情就是在网页里把网格画出来提供旋转、缩放、切换材质、查看骨骼层级这类操作。有的项目做得好看一点加上环境贴图和后期特效但本质上它们解决的都是同一个问题如何把一个静态的三维人体模型在浏览器里呈现得足够真实。这种项目的瓶颈非常明显。模型是死的没有反馈没有理解也没有数据闭环。你看到的是一具雕塑不是一个人。哪怕模型做得再精细、贴图再高清它也只是一份静态资产跟一张照片的区别只是多了深度信息。我前几年用这类项目做技术展示时最深的感受是功能列表写起来很漂亮实际演示却很尴尬因为用户最想知道的这个人现在在做什么动作这个动作哪里不对——它一个都答不上来。1.2 AI加入后可视化链路被彻底改写AI能力进来之后事情开始起变化。人体可视化从渲染问题变成了理解问题。我把这一批新项目的能力变化拆成三部分姿态自动提取。通过MediaPipe、MoveNet或者更高精度的3D姿态估计模型项目可以从单目摄像头画面里直接检测出人体的2D关键点甚至带深度的3D关键点。这一步以前需要穿戴动捕设备才能做到现在纯靠视觉算法就能覆盖。模型实时驱动。拿到关键点坐标之后不是简单地画一堆圆点而是把坐标映射成骨骼关节的旋转直接驱动一个带蒙皮的SkinnedMesh三维人体模型。人的动作和三维模型的动画实时同步视觉冲击力很强。语义理解与量化分析。检测到膝关节角度、肩关节角度、动作类型甚至把一段动作识别成深蹲挥手走路然后把数值和标签直接叠加到三维场景里。这三部分加起来项目的身份就从查看器变成了分析工具。用户看到的不再是一具静止的雕塑而是一个能反馈、能量化、能被进一步理解的三维人体。1.3 又一个背后为什么最近这类项目成批出现标题里用又一个这个词不完全是调侃。这类项目集中出现的底层原因我理解是三层叠加。第一底层开源模型成熟了。BlazePose、MoveNet、MediaPipe这些模型都提供了浏览器端可运行的版本还带WASM和GPU加速开发者不需要自己从零训练模型拿来就能用。第二三维Web生态也越来越稳定。Three.js长期维护glTF/GLB成为通用交换格式加载一个带动画的骨骼模型只要几行代码复杂的蒙皮和骨骼系统也不再需要自己造轮子。第三应用场景被AI能力催熟了。因为姿态识别能做了运动康复、虚拟试穿、数字人这些赛道才真正有了落地可能GitHub上自然就冒出一批带垂直场景的项目。所以又一个并不是坏事。它说明整个方向的基数在变大重复造轮子的部分在变少更像是在同一个地基上长出不同的房子。2. 拆开这类项目的技术底盘Three.js负责渲染AI推理负责看懂2.1 浏览器里的完整数据流大多数这类项目的架构本质上可以浓缩成一条数据流摄像头画面或视频文件 → 2D人体关键点 → 3D关键点/关节旋转 → 驱动3D模型 → 叠加语义信息从工程实现上看具体会拆成几步。第一步获取图像源。用navigator.mediaDevices.getUserMedia()打开摄像头或者用video元素加载视频。注意这一步只是把视频流交给AI模块不需要把每一帧画面都传到服务端浏览器端推理天然对隐私友好这也是这类项目容易被用户接受的一个原因。第二步姿态估计。这里可以用MediaPipe的Pose Landmarker也可以考虑TensorFlow.js生态里的MoveNet。两者都输出人体关键点常见的是33个关键点包括鼻子、双眼、双耳、肩膀、手肘、手腕、髋部、膝盖、脚踝等每个点包含x、y、z坐标和可见度。注意这里的z不是相机直接测出来的真实深度而是模型预测的相对深度信息做可视化的时候要做尺度控制否则模型会看起来很怪异。第三步坐标映射。AI模型输出的坐标在图像坐标系里x向右、y向下、z朝向相机而Three.js的默认坐标系是x向右、y向上、z朝外。直接赋坐标一定出问题轻则模型翻转重则骨骼完全错位。常规做法是先做一次坐标系翻转再把像素坐标归一化到Three.js场景里的某个单位范围内。第四步驱动模型。拿到关键点之后有两种做法低精度方案是直接把关键点坐标算成线段和球体拼一个火柴人胜在简单高精度方案是把关键点坐标转化成关节的欧拉角或四元数设置到骨骼bone上再由骨骼驱动蒙皮网格形变也就是SkinnedMesh。后面这一种才是真正意义上的3D人体可视化视觉效果和物理合理性都远超线框模型。2.2 为什么前端渲染选Three.js而不是其他方案现在这类项目里最常见的渲染库是Three.js这有它的历史必然性。Three.js对glTF/GLB的支持非常成熟GLTFLoader加载一个带动画的模型再配一个AnimationMixer动画播放就能跑起来。骨骼系统、SkinnedMesh、顶点权重这些底层能力都齐全不需要自己写底层图形代码。也有项目用Babylon.js它自带更强的场景编辑器工业可视化场景里更有优势。还有使用Unity WebGL导出的方案适合需要物理引擎和复杂交互的项目不过包体通常很大而且与浏览器原生生态的衔接比较别扭。个人实测下来的体感是如果只想快速跑通人体可视化Three.js学习曲线最平缓周边资料最多团队协作时也最容易互相接手。如果项目偏数字孪生或者重型仿真Babylon.js更值得研究。技术方案优势缺点适合场景Three.jsglTF支持成熟、生态大、上手快大规模物理模拟需要额外集成人体可视化、Web展示、数据可视化Babylon.js编辑器完善、内置物理引擎社区资料相对少一些数字孪生、复杂场景Unity WebGL工具链成熟、3A管线完整包体大、加载慢需要重型物理和渲染的项目2.3 AI推理模块怎么接入这层选择其实决定了项目跑不跑得动。我比较推荐MediaPipe的Pose Landmarker因为它不是纯2D而是基于BlazePose的架构可以直接输出带深度信息的关键点做三维映射会省事不少。如果不想被平台绑定MoveNet和PoseNet也是备选后两者在TensorFlow.js里都有现成封装。跑推理的方式也要留意。浏览器端的AI推理本质上是把模型加载成WASM或者WebGL/WebGPU程序在GPU delegate下速度最快但兼容性差一些CPU delegate最稳但帧率会下降。我建议默认先用GPU跑起来出错了再降级到CPU并且给用户一个手动切换的选项。这种细节在真实项目里会很加分因为不同电脑的显卡支持情况差异很大。2.4 一段能直接改的启动代码下面这段代码基本是这类项目的最小骨架我按照实际能跑的水平整理过import * as THREE from three; import { GLTFLoader } from three/addons/loaders/GLTFLoader.js; import { OrbitControls } from three/addons/controls/OrbitControls.js; import { PoseLandmarker, FilesetResolver } from mediapipe/tasks-vision; // 1. 基础场景 const scene new THREE.Scene(); const camera new THREE.PerspectiveCamera(45, innerWidth / innerHeight, 0.1, 1000); camera.position.set(0, 1.5, 3); const renderer new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(innerWidth, innerHeight); document.body.appendChild(renderer.domElement); new OrbitControls(camera, renderer.domElement); // 2. 加载带骨骼的人体模型 let mixer null; const loader new GLTFLoader(); loader.load(/models/human.glb, (gltf) { scene.add(gltf.scene); mixer new THREE.AnimationMixer(gltf.scene); }); // 3. 初始化姿态检测 const vision await FilesetResolver.forVisionTasks( /wasm ); const poseLandmarker await PoseLandmarker.createFromOptions(vision, { baseOptions: { modelAssetPath: /models/pose_landmarker_lite.task, delegate: GPU }, runningMode: VIDEO, numPoses: 1 }); // 4. 每帧处理 function update(now) { if (video.readyState 2) { const result poseLandmarker.detectForVideo(video, now); // 这一段把2D/3D关键点映射到模型骨骼 applyLandmarksToSkeleton(result.landmarks[0]); } if (mixer) mixer.update(0.016); renderer.render(scene, camera); requestAnimationFrame(update); } requestAnimationFrame(update);applyLandmarksToSkeleton这个函数就是前面说的坐标映射那一步不同项目实现细节不同但核心都是同一个问题建立AI坐标系与Three.js骨骼坐标系之间的转换。你不需要一步到位写出通用方案先针对一个模型写死映射关系跑通了再抽成配置。3. 从零复现这类项目的完整过程环境、模型与数据处理3.1 环境准备Node、Vite、Three.js、MediaPipe本地复现我建议用Vite而不是直接双击打开一个html页面。原因之一是MediaPipe需要加载WASM文件和模型文件对静态资源路径和MIME类型有要求file://协议很容易撞上资源找不到和跨域问题用本地开发服务器最省心。安装步骤比较简单npm create vitelatest human-view -- --template vanilla cd human-view npm install three mediapipe/tasks-vision npm install vite-plugin-static-copy --save-dev然后把模型文件放进public/models目录把MediaPipe的WASM文件放进public/wasm目录。这里要注意如果你用的是新版本的threeGLTFLoader已经调整为按需引入不要依赖全局THREE而是从three/addons里导入上面的代码就是这么写的。如果遇到加载报错先看控制台是模型路径404还是WASM加载失败两者处理方式完全不同。我见过很多新手在这上面浪费时间其实九成都是路径问题并不是代码逻辑问题。3.2 人体模型与动作数据怎么准备模型格式我强烈建议使用GLB。为什么不是glTFGLB是把整个glTF资源打成一个二进制文件的格式只有一个文件路径依赖简单网络加载也少一次请求。glTF是JSON加外部资源的形式适合调试但不适合上线。如果你的素材是FBX先用Blender转换一下。导入Blender后保留骨骼和动画导出为GLB。注意导出时最好勾选压缩选项或者后续用gltf-transform工具处理一遍控制文件体积。一个高精度人体模型动辄十几MB对Web端来说有点重叠加Draco压缩后通常能降到一半甚至三分之一。Draco压缩在Three.js里要额外引入DRACOLoader默认GLTFLoader不会自动处理这个一定要记得配否则模型可能完全加载不出来。动作数据方面离线动作一般用BVH或FBX。BVH是纯文本格式记录了骨骼层级的关节旋转序列解析起来很直观适合做动作数据的离线处理和可视化。FBX则更常用于游戏行业转换后交给Three.js的AnimationClip播放。我个人的建议如果你做的是动作分析类项目先用BVH因为它透明可见中途出问题好排查如果做的是游戏化展示直接用FBX转GLB更省事。3.3 几个必须绕开的坑从实测来看这类项目最容易踩的坑集中在四块。第一块是坐标系不一致。AI关键点坐标和Three.js世界坐标之间要先做一次镜像和翻转。具体做法通常是把x取反或者把y取反取决于你的模型默认朝向。这个坑不踩一次很难凭直觉避开我一开始就是整个场景上下颠倒调了半天才意识到是坐标系的问题不是模型问题。第二块是GPU delegate不稳定。部分显卡和浏览器组合下WebGL上下文和MediaPipe WebGL会出现冲突表现是渲染黑屏或者推理掉帧。遇到这种情况把delegate切到CPU再用一个专门的canvas承载摄像头预览可以规避掉大部分问题。第三块是推理与渲染打架。很多人习惯把AI推理和Three.js渲染写在同一个requestAnimationFrame循环里觉得这样简单。实际操作下来AI推理一帧在低端设备上可能要花60ms以上渲染又需要16ms两个挤在一起直接掉到20fps以下。正确思路是把推理频率降到15FPS左右用一个独立定时器驱动给渲染循环留出缓冲。第四块是骨骼对应关系。AI输出的33个关键点和模型骨骼节点名基本对不上需要建立一张手动映射表。例如MediaPipe的12号关键点是左髋模型骨骼里可能叫LeftUpLeg也可能叫LeftHip。别指望自动匹配老老实实配一张映射表最稳。4. AI能力催生的新场景以及每个场景怎么落地4.1 运动康复与健身指导把姿态变成角度和次数这类场景现在是离钱最近的方向之一。拿到关键点之后最直接的应用就是计算关节角度。比如判断深蹲是否标准只需要看髋关节和膝关节角度在最低点是否达到90度左右判断肘关节是否锁死看肘关节角度即可。计算方式很简单取三个关键点构造两条向量套用向量夹角公式。function jointAngle(a, b, c) { const v1 { x: a.x - b.x, y: a.y - b.y, z: a.z - b.z }; const v2 { x: c.x - b.x, y: c.y - b.y, z: c.z - b.z }; const dot v1.x * v2.x v1.y * v2.y v1.z * v2.z; const len1 Math.hypot(v1.x, v1.y, v1.z); const len2 Math.hypot(v2.x, v2.y, v2.z); return Math.acos(Math.min(1, Math.max(-1, dot / (len1 * len2)))); }实际项目里还会把连续帧的角度变化做成折线图自动统计次数比如角度低于某个阈值记一次有效动作。有一类运动康复项目就是这样做的用户对着摄像头做康复动作系统把每一次动作的角度变化曲线画出来和标准动作曲线对比偏差一目了然。这个场景里3D人体可视化的价值在于让用户直观看到自己的关节位置而不是面对一堆冷冰冰的数字。4.2 虚拟试穿与人体测量电商和服装行业对3D人体可视化的需求很直白测量。传统量体需要人工测或者靠用户自己报身高体重误差很大。基于AI姿态估计可以较准确地估计肩宽、臂长、腿长等关键尺寸然后把这些尺寸实时映射到一个三维人体模型上让用户转着圈看衣服合不合身。这里技术栈会额外加两个东西一是人体尺寸估计算法二是AR相机预览。前者的数据来源可以是单目摄像头精度有限但对服饰推荐已经够用后者把摄像头画面、3D服装模型和人体姿态结合在一起实现实时虚拟试穿。这类项目在GitHub上数量不少但普遍有个通病布料模拟是瓶颈衣服看起来像贴在身上一样。如果不想做那么重可以从服装模型的贴合度近似开始不做物理模拟先用3D卡通风格服装人体轮廓把产品闭环跑通后续再优化。4.3 数字人、动画生产与动作迁移数字人是AI能力进入3D人体可视化后最出效果的方向。传统三维动画制作流程里让角色做一个动作需要手K关键帧或者去动捕棚里录制成本很高。现在有了AI姿态估计只需要一段普通视频就能把视频里人物的肢体动作迁移到三维虚拟角色身上。动作迁移的技术核心叫retargeting也就是把源骨骼的旋转数据重新映射到目标骨骼。源骨骼和目标骨骼的层级、朝向、比例往往不一致算法要做的是保持根骨位置和关节转角不变再换算到目标骨骼树上。简单方案可以直接用Three.js的世界矩阵做父子级链式换算复杂方案可以接AI动作生成模型比如文本描述走路并挥手直接生成一段BVH动作序列。后者目前生成的序列质量还不稳定但作为动画师的灵感草稿已经非常好用。在这个环节有几类配套数据来源值得关注高精度人体重建会用到结构光相机或者3D点云去做初步建模点云不够完整时可以用3D卷积自编码器做补全和去噪得到相对干净的人体表面网格。过程虽然复杂但每一步都有现成的开源模型可以接工程实现比想象中快。4.4 教育教学与体感互动教育场景里3D人体可视化能做的事更轻量。生物课上可以用它演示人体解剖结构体育课上可以用它分析学生的动作标准度格斗、舞蹈教学也可以利用姿态识别给出实时反馈。体感小游戏本质上也属于同一个技术栈用户做出动作系统识别动作并反馈到游戏逻辑里。这类场景的工程量不大因为有Three.js的成熟生态渲染部分非常快主要工作量在交互设计和动作判定的规则算法上。还有个很实用的分支把姿态关键点序列喂给动作识别模型做健身姿势纠错或动作计数。动作识别可以用现成的分类器也可以把关键点序列做成特征向量用少量标注样本训练一个轻量分类器。这种方式对算力要求低手机浏览器都能跑很适合做成教学辅助工具也是很多学校实训项目愿意接手的方向。5. 实测总结这类项目值不值得跟以及往上还能怎么长5.1 跑通很轻松真正的瓶颈在模型和数据我花了一个晚上把完整链路跑通后一个很强烈的感受是工程层真的不难。浏览器端AI模型成熟、Three.js稳定组装一个Demo可能只要几百行代码。但要真正做成产品瓶颈集中在两个地方。第一个是模型的精度和稳定性。单目摄像头下的3D姿态估计存在深度歧义人体侧对相机时部分关键点会频繁抖动遮挡情况下更是直接飘走。为了保证稳定工业级方案通常要引入多视角相机、结构光深度相机或者IMU惯性动捕设备单目方案只适合对精度要求不高的场景。第二个是数据资产。可视化做得再好如果没有让人信服的人体模型、动作数据、场景配置项目依然没有说服力。我在实际项目里发现模型文件的管理往往比算法代码更耗时。素材格式混乱、骨骼命名不统一、动作数据帧率不一致这些问题会在集成阶段集中爆发所以在选素材时就要有意识地建立统一的命名规范。5.2 往上走的三条路WebGPU、AI Agent、跨端复用这个方向接下来有几条比较明确的路。第一条路是上WebGPU。浏览器图形渲染和AI推理都在往WebGPU迁移性能上限更高也能部分缓解3D人体网格和AI模型之间的算力争夺。Three.js已经提供WebGPURenderer的接入方式等兼容性再稳一些这类项目的体验会再上一个台阶。第二条路是接AI Agent。把人体姿态数据、动作识别结果交给大模型让它自动生成动作描述、训练建议或可视化配置可以极大降低使用门槛。比如用户问我哪次深蹲最标准AI Agent可以直接调历史姿态数据把结果映射到三维场景里回放。这个方向刚起步模板很少做出来会很有竞争力。第三条路是跨端复用。目前很多项目的代码还是Web专用但如果把AI推理和Three.js渲染封装成统一模块未来可以同时输出到小程序、桌面端甚至头显设备。3D人体可视化在AR/VR里的需求只会更多提前把渲染和逻辑分离能避免后期重构。5.3 给打算入坑的人的最后几条建议如果现在想动手做这类项目我建议按下面的顺序一步步来不要一上来就追求高精度3D重建。先跑通2D姿态检测用Canvas画线框人体确认摄像头、推理链路没问题。然后把2D关键点映射成一个简单的3D火柴人利用z方向粗略信息做进深先把空间感做出来。最后再上带蒙皮的3D人体模型把骨骼绑定、动画系统接进来。每一步都有明确的完成标志排查问题会容易很多。工程上记住一句话AI推理和渲染分离模型路径集中管理坐标系转换放到一个独立模块。这三个习惯能帮你省下大量排查时间。最后再分享一个小技巧在开发阶段把AI关键点和骨骼模型的对应关系做成可视化调试面板直接在页面上显示关键点编号和骨骼节点名。这样每次换模型都能快速确认映射是否正确不至于在看不见的地方埋雷。我后面还会继续在这个方向上折腾打算做一个动作回放AI点评的家庭健身工具到时候有实际结果了再回来分享。
返回列表