人体姿态搜索完整指南:用浏览器三分钟找到你想要的任意姿势
【免费下载链接】pose-searchx6ud.github.io/pose-search项目地址: https://gitcode.com/gh_mirrors/po/pose-search
pose-search 是一个完全运行在浏览器端的开源人体姿态搜索工具:你只需要摆出一个姿势,它就能在一张照片库里自动找到最接近的动作参考,全程无需后端服务器。它把「人体姿态识别」「姿态特征提取」「几何匹配算法」全部打包进一个前端项目里,无论你是插画师找参考、健身教练做动作比对,还是开发者想给应用加上「按姿势搜图」的能力,这套开源方案都值得你花十分钟读完并上手一试。
一张找不到的参考图,逼疯了多少创作者
先说一个几乎人人都经历过的场景。
你是一名插画师,正在画一个「单膝跪地、双手上举」的动态,但自己摆不出来,脑子里也只有模糊的画面。于是你打开素材网站,输入 "kneeling"、"raising arms"……翻了几百页,出来的不是站姿就是坐姿,唯一一张接近的还带着水印。两小时过去,参考图没找到,灵感先没了。
问题出在哪里?图片搜索用的是文本标签,而你想要的是动作本身。标签是人写的,不同人用词不一样,一张「下蹲」的照片可能被标注成 "crouch",也可能是 "squat",甚至是 "sit"。关键词的鸿沟,让「按姿势找图」这件事变得异常痛苦。
有没有可能——直接"用姿势搜姿势"?
pose-search 就是为这个想法而生的。它把 MediaPipe Pose 的姿态识别能力搬进浏览器,用几何算法比较照片之间的动作相似度,让你在本地照片库里完成基于姿势的人体姿态搜索。没有服务器,没有上传,没有等待。
三分钟跑起来:把姿态搜索部署到本地
读到这里你能获得:亲手启动这个项目的能力。全程只需要三条命令,比你配置一个普通前端工程还要快。
git clone https://gitcode.com/gh_mirrors/po/pose-search cd pose-search npm install依赖装好后,启动开发服务器:
npm run dev浏览器会自动打开项目首页,在地址栏进入搜索页后,你会看到左侧一个可拖拽旋转的 3D 人体骨架,右侧是一大片待检索的照片墙。选中某个身体部位,点一下 Search,几秒内结果就出来了。
整个过程用到的核心技术栈非常轻:Vue 3 + TypeScript 提供界面与类型安全,MediaPipe Pose 负责从图像里提取关键点,WebGL 负责 3D 骨骼渲染,Web Workers 负责让模型加载与推理不阻塞页面。这些后面会逐层拆开讲。
原理第一层:给每张照片盖上一枚"姿态指纹"
读到这里你能获得:看懂整个项目最核心的数据抽象——姿态是怎么被"存档"的。
要让计算机理解"一个人的动作长什么样",第一步是把身体抽象成一组可计算的数字。MediaPipe Pose 模型从单张图像中检测出33 个人体关键点,覆盖鼻子、肩膀、手肘、膝盖、胯部等主要关节,每个点都带有三维坐标和可见度置信度。
关键设计在于,项目为每个关键点保存了两套坐标:
| 坐标系 | 含义 | 用途 |
|---|---|---|
| 归一化坐标(normalizedLandmarks) | 关键点在图片平面上的位置,范围 0~1 | 屏幕空间的 2D 显示与分析 |
| 世界坐标(worldLandmarks) | 以髋部为原点的 3D 空间坐标 | 保留真实的肢体朝向关系,用于姿态匹配 |
为什么需要两套?打个比方:归一化坐标像是照片上的"投影",会随拍摄角度和人物远近变化;世界坐标则是人物本身的"骨架模型",不会因为相机位置不同而失真。搜索时用世界坐标比较动作,显示时用归一化坐标对齐画面,各取所长。
把这套检测能力封装成一个 Promise 接口,整段代码不过几十行:
// src/utils/detect-pose.ts export function detectPose(image) { return new Promise(async function (resolve) { const pose = await getInstance(); // 复用同一个 Pose 实例,避免重复加载模型 pose.reset(); onResultsCallback = resolve; await pose.send({image}); // 送入图像,推理完成后通过回调 resolve }); }每一次检测,就相当于给这张照片盖上了一枚独一无二的"姿态指纹"。而PhotoDataset这个类(src/utils/PhotoDataset.ts)会把所有照片的指纹批量压缩进一个landmarks.dat二进制文件里,加载照片库时一次性读入内存,几十万张图片的检索也能在毫秒级完成。
原理第二层:几何匹配,姿势相似度如何量化
读到这里你能获得:理解 pose-search 最巧妙的部分——把"像不像"翻译成数学语言。
有了姿态指纹,下一个问题来了:怎么判断"这张照片的姿势"和"我摆的姿势"像不像?
pose-search 的答案是一组姿态匹配器(PoseMatcher),每个匹配器负责一个身体部位。你可以翻一下src/Search/impl/目录,会发现MatchShoulder、MatchElbow、MatchKnee、MatchHip、MatchFace、MatchChest等十几个实现,肩、肘、膝、髋一应俱全,甚至还有专门忽略相机角度的变体(如MatchShoulderCameraUnrelated)。
以MatchShoulder为例,它的思路可以概括成三步:
- 提取方向向量:用左右肩、髋部等关键点,计算躯干方向和肩部朝向,得到几个代表动作的"骨架向量";
- 转换到局部空间:把世界坐标下的向量换算到以躯干为基准的局部坐标系,从而排除人物高矮胖瘦的干扰;
- 比较角度差:分别计算"世界空间角度误差"和"视图空间角度误差",误差越小说明动作越接近,最终按综合分数排序。
// src/Search/impl/MatchShoulder.ts(核心逻辑节选) const error = angleBetweenVec3(dirL, this.shoulderLocalDir); // 世界空间的角度误差 const viewError = angleBetweenVec3(trunkUpView, this.trunkViewUp); // 视图空间的朝向误差 return { score: (Math.PI - error) * (Math.PI - viewError), // 误差越小,分数越高 center: normalized[11].point, // 结果缩略图的聚焦中心 related: [...], // 关联关键点,用于裁剪对齐 };这里的score不是玄学,而是多个角度差的乘积——任何一个维度过大,都会让总分迅速坍缩,保证返回的永远是"所有部位都接近"的结果,而不是某个单点碰巧吻合的误导项。
搜索的编排逻辑也相当干净。所有匹配器统一实现PoseMatcher接口(定义在src/Search/impl/search.ts),一个filterAndSort函数完成"逐张比对 → 过滤不合格 → 按分数降序"的完整流程:
export function filterAndSort(photos, model, matcher) { matcher.prepare(model); // 先根据当前骨架姿态做预处理 photos.forEach(photo => { const r = matcher.match(photo); // 逐张照片计算匹配分数 if (r != null) ret.push({...r, photo}); }); ret.sort((a, b) => -a.score + b.score); // 分数越高排越前 return ret; }这套prepare / match两段式设计非常值得借鉴:prepare只算一次"目标姿势"的几何特征,match则对每张照片复用,把 O(N) 次重复计算压成了 O(1) 预计算 + O(N) 轻量比对,这才是它能秒级扫完整个图库的底气。
亲手体验:搜索"左膝跪地"是种什么感觉
读到这里你能获得:对项目交互与视觉呈现的整体印象。
启动项目后,你可以这么玩:用鼠标拖拽左侧的 3D 骨架,把左膝弯下去,模拟一个单膝跪地的姿势;然后在部位下拉框里选择 "Left Knee",点 Search。右侧照片墙会瞬间刷新,每一张缩略图都自动以"膝盖"为中心裁剪对齐,并且自动标记出左腿的关键点连线。
上面这张截图来自项目仓库自带的editor.jpg,展示的是编辑器页面——左侧是原图与叠加的骨架标注,右侧是元数据面板,你可以在这里给照片打标签、标记性别、运行姿态模型并写入数据库。配合搜索页使用,你既能消费现成的图库,也能亲手扩建自己的图库。
一个很贴心的细节是:如果你不希望结果受"人物面向"影响,可以切到Camera Ignored(忽略相机方向)模式。此时匹配器会自动换成CameraUnrelated变体,只比较动作本身、不比较朝向,相当于告诉系统"我要的是这个动作,背对还是面对镜头都行"。
性能与架构:为什么浏览器端能扛得住
读到这里你能获得:这套"纯前端姿态识别"方案在性能上的底气来源。
你可能会担心:把姿态识别和整库比对都塞进浏览器,卡不卡?pose-search 的架构给出了三层保障:
- MediaPipe 的 WASM 优化:模型文件经过预编译和体积压缩,加载快、推理快,专为 Web 场景打磨;
- Web Workers 后台推理:
public/worker/detect-pose.worker.js把检测逻辑放到独立线程,避免模型推理卡死界面; - WebGL 混合渲染:2D 关键点用 Canvas 绘制,3D 骨骼用 WebGL 着色器渲染(
src/components/SkeletonModelCanvas/下的light.vert、line.frag等着色器就是见证),把 GPU 的资源充分利用起来。
更重要的是,数据库的匹配计算根本不涉及 GPU——姿态指纹是提前算好存进landmarks.dat的,搜索时只是做纯内存里的向量角度比较。这意味着照片再多,搜索也只是"扫一遍浮点数",而不是真的对每张图重新跑一次神经网络。
顺带一提,3D 骨骼渲染用到了gl-matrix做矩阵运算,模型节点体系抽成了BodyPart、SkeletonModelNode这样的类,把"骨骼"和"节点"的概念分得很清楚。如果你以后想加"脖子匹配器""手腕匹配器",照着现有类的结构扩展即可。
想把它改造成自己的工具?给你两条路
读到这里你能获得:项目预留的扩展接口在哪儿,以及两条可行的二次开发路线。
路线一:换数据源。PhotoDataset已经支持从photos.json和landmarks.dat加载数据,writeToFile()还能把数据写回。配合编辑器页面的 "Run Model" 和 "Add Record" 按钮,你可以用自己的照片库重建一套姿态数据集,让搜索针对你的领域数据生效。
路线二:换匹配算法。实现PoseMatcher接口,自定义prepare和match逻辑,然后把它注册到src/Search/Search.ts的matchers注册表里,页面上就会自动出现新的部位选项。比如你想搜"腰部侧屈幅度",完全可以仿照MatchShoulder写一个MatchWaist。
对,就是这么轻。整个项目的核心逻辑集中在src/Search/(搜索)与src/components/SkeletonModelCanvas/(骨架渲染)两个目录里,架构清晰到"花一个晚上就能通读"的程度。
省下翻图的时间,把精力还给创作
回到开头那个插画师的困境。有了 pose-search,她的工作流会变成:打开项目,拖拽骨架摆出想要的姿势,点击搜索,几秒钟后参考图已经躺在屏幕上了。省下的是两小时的翻图时间,保住的是创作状态里最宝贵的心流。
这个项目带给你的价值可以归结为三句话:
- 如果你是创作者:一个免费、离线、本地运行的"姿势素材检索器",找参考再也不用靠猜关键词;
- 如果你是开发者:一套可复用的浏览器端人体姿态识别与几何匹配的完整参考实现,
PoseMatcher接口就是你的扩展起点; - 如果你在评估技术选型:它用事实证明了"纯前端完成实时姿态检测与智能搜索"完全可行,零服务器成本、零隐私风险。
接下来要做什么,路径已经给你铺好了:
- 执行
git clone https://gitcode.com/gh_mirrors/po/pose-search && npm install && npm run dev,亲手体验一次姿态搜索; - 通读
src/Search/impl/下的匹配器代码,体会几何算法如何量化"动作相似度"; - 如果你有更好的思路,按照
PoseMatcher接口写一个新的匹配器提交上来,让这个开源项目因为你而更强。
别再让"想找的姿势"和"搜到的图"之间隔着一道关键词的墙了。这一次,用你的身体去搜索。
【免费下载链接】pose-searchx6ud.github.io/pose-search项目地址: https://gitcode.com/gh_mirrors/po/pose-search
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考