- 它能做什么
- 准备工作
- 案例一:识别关键点
- 案例二:按名称取点,判断左右手是否举起
- 案例三:打开摄像头实时检测,举手立刻有反应
- 案例四:给画面里的人戴礼帽(复刻 MIT TophatMe)
- 结果数据说明
- 常见问题
- 完整 .aia 源码与操作指导
机器学习套件(ML Kit)组件在在线版和教育版中提供,离线版(含机房版)不包含。
它能做什么
姿势检测从一张照片里找出一个人的身体关键点:鼻子、眼、耳、肩、肘、腕、髋、膝、踝等共 33 个,每个点给出原图像素坐标 x、y 和「这个点确实在画面里」的可信度。常用于健身动作计数、体感游戏、举手检测。
准备工作
- 只识别一个人:画面里有多人时只取最显著的一个。
- 精确模式:打开后换用精确模型,关键点更准但更慢;实时检测建议用默认的基础模型。
- 实时检测:在设计器里放一个垂直布局当「预览容器」,「打开实时摄像头」后画面上直接画出骨架。
- 联机调试:安卓上用 AI 伴侣调试需要安装 MLKit 版 AI 伴侣(应用宝,包名 cn.fun123.appinventor);普通版伴侣不含识别引擎,调用时会触发「屏幕.出现错误时」(错误码 4722)。直接打包 APK 安装测试不受影响。
- 安装包体积:只有用到本组件的 App 才会打包它的识别引擎与模型,体积以编译结果为准。
- 鸿蒙:部分支持:鸿蒙系统给出 17 个主要关键点,编号与名称沿用这里的 33 点体系,眼角、嘴角、手指、脚跟等点不出现在结果里;「精确模式」不切换模型;实时摄像头检测暂不支持,「打开实时摄像头」会触发「检测失败时」。
案例一:识别关键点
检测成功事件给出关键点数,数为 0 表示没找到人:
procedure 检测(路径) {
图像_预览.Picture = 路径
姿势检测1.DetectFromFile(路径)
}
when 图像选择器_相册.AfterPicking() { 检测(图像选择器_相册.Selection) }
when 照相机1.AfterPicture(图像位址) { 检测(图像位址) }
when 姿势检测1.DetectionSuccess(结果JSON, 关键点数) {
标签_状态.Text = choose(关键点数 > 0, join("识别到 ", 关键点数, " 个关键点"), "没有找到人")
}
案例二:按名称取点,判断左右手是否举起
写一个函数按名称找点,再比较手腕和肩膀的 y:y 越小越靠上,手腕在肩膀上方就算举起:
function 取点(点表, 名称) {
var 结果 = makedict()
foreach 点 in 点表 {
if dictget(点, "name", "") == 名称 {
结果 = 点
}
}
return 结果
}
when 姿势检测1.DetectionSuccess(结果JSON, 关键点数) {
var 点表 = dictget(Web客户端1.JsonTextDecodeWithDictionaries(结果JSON), "landmarks", list())
var 左腕 = 取点(点表, "LEFT_WRIST")
var 左肩 = 取点(点表, "LEFT_SHOULDER")
标签_结果.Text = join("左手:", choose(dictget(左腕, "y", 99999) < dictget(左肩, "y", 0), "举起", "放下"))
}
案例三:打开摄像头实时检测,举手立刻有反应
点「实时检测」时把垂直布局设为「预览容器」再「打开实时摄像头」,画面上直接画出骨架(关键点与连线)。「实时检测到姿势」的结果格式与「检测成功」相同,所以可以复用案例二的「取点」函数,把举手判断抽成过程两处共用:
procedure 显示举手(点表) {
var 左腕 = 取点(点表, "LEFT_WRIST")
var 右腕 = 取点(点表, "RIGHT_WRIST")
var 左肩 = 取点(点表, "LEFT_SHOULDER")
var 右肩 = 取点(点表, "RIGHT_SHOULDER")
标签_结果.Text = join("左手:", choose(dictget(左腕, "y", 99999) < dictget(左肩, "y", 0), "举起", "放下"), " 右手:", choose(dictget(右腕, "y", 99999) < dictget(右肩, "y", 0), "举起", "放下"))
}
when 按钮_实时.Click() {
姿势检测1.PreviewContainer = 垂直布局_预览
姿势检测1.StartLiveCamera()
}
when 按钮_停止.Click() { 姿势检测1.StopLiveCamera() }
when 姿势检测1.LivePose(关键点数, 图片宽度, 图片高度, 结果JSON) {
if 关键点数 == 0 {
标签_状态.Text = "实时:画面里没有人"
} else {
显示举手(dictget(Web客户端1.JsonTextDecodeWithDictionaries(结果JSON), "landmarks", list()))
}
}
案例四:给画面里的人戴礼帽(复刻 MIT TophatMe)
姿势检测也能贴图:锚点用关键点名,头部的点按两耳距离缩放、按两眼连线旋转。礼帽贴在 NOSE 上方 1.1 个两耳距离处,人走到哪帽子跟到哪;不用画布、不用自己换算坐标:
when 按钮_帽子.Click() { 姿势检测1.AddSticker("礼帽", "tophat.png", "NOSE", 1.6, 0, -1.1) }
when 按钮_摘下.Click() { 姿势检测1.RemoveSticker("礼帽") }
when 按钮_保存.Click() { 姿势检测1.CaptureLiveFrame() }
when 姿势检测1.LiveFrameCaptured(图片地址) {
图像_照片.Picture = 图片地址
}
结果数据说明
结果JSON:{"landmarks":[{"type":11,"name":"LEFT_SHOULDER","x":312.5,"y":420.1,"z":-35.2,"inFrameLikelihood":0.99}, …]}。常用名称:NOSE 鼻子、LEFT_SHOULDER/RIGHT_SHOULDER 肩、LEFT_WRIST/RIGHT_WRIST 腕、LEFT_HIP/RIGHT_HIP 髋、LEFT_KNEE/RIGHT_KNEE 膝、LEFT_ANKLE/RIGHT_ANKLE 踝。深蹲计数可以比较髋和膝的 y。
常见问题
| 现象 | 原因与处理 |
|---|---|
| 关键点数总是 0 | 人太小或遮挡太多;换人像占画面较大的照片 |
| 坐标和图像组件对不上 | 坐标是原图像素,图像组件按缩放显示,需按比例换算 |
| 鸿蒙上少了手指、脚跟等点 | 鸿蒙系统只提供 17 个主要关键点 |
| 实时预览黑屏、看不到画面 | 「预览容器」要选布局组件并给明确宽高(如宽度充满、高度 300 像素);第一次打开要允许摄像头权限 |
| 实时检测时界面卡 | 调大「实时事件间隔」,事件里少做事;画面上的标注不受间隔影响 |
完整 .aia 源码与操作指导
导入 PoseDetectorDemo.aia 后可以直接打包 APK 运行;用 AI 伴侣联机调试请安装 MLKit 版 AI 伴侣。源码文件已通过正式编辑器载入、后台导入和 APK 编译校验;真机识别效果请以实际设备为准。
| 功能 | 操作 | 预期结果 |
|---|---|---|
| 从相册选图 | 选一张全身或半身照 | 显示关键点数,左右手是否举起,鼻子和双肩坐标 |
| 拍照 | 举起一只手拍照 | 对应的手显示「举起」 |
| 无人照片 | 选一张风景照 | 提示没有找到人 |
| 实时检测 | 点「实时检测」,站在摄像头前举手 | 预览区画出骨架,左右手举起/放下实时刷新 |
| 戴礼帽 | 实时检测时点「戴礼帽」,在画面里走动 | 礼帽跟着头移动、随歪头旋转;「保存照片」连帽子一起存下来 |
| 精确模型 | 勾选「精确模型」再检测 | 关键点更贴合,检测稍慢 |
案例界面与积木源码在仓库 docs/markdown/reference/components/guide/examples/PoseDetectorDemo/,SHA-256:b0add47a201811ad899e663562efaf8ef9c7f914fce1032a98dba3c4a151a244。
扫码添加客服咨询