概述
PoseNet是Google开发的实时人体姿态估计模型,可以检测人体的17个关键点。在App Inventor中通过PoseNet扩展使用。
关键点列表
| 编号 | 部位 | 编号 | 部位 |
|---|---|---|---|
| 0 | 鼻子 | 9 | 右手腕 |
| 1 | 左眼 | 10 | 左臀 |
| 2 | 右眼 | 11 | 右臀 |
| 3 | 左耳 | 12 | 左膝 |
| 4 | 右耳 | 13 | 右膝 |
| 5 | 左肩 | 14 | 左脚踝 |
| 6 | 右肩 | 15 | 右脚踝 |
| 7 | 左手肘 | 16 | — |
| 8 | 右手肘 | — | — |
扩展来源
PoseNet扩展来自MIT App Inventor社区或DeepHost:
- MIT社区搜索 “PoseNet extension”
- DeepHost: https://app.deephost.in/
基本用法
界面设计
Screen1
├── 照相机1(或选择图片按钮)
├── 画布1(绘制关键点)
├── 图像1(显示检测结果)
├── PoseNet1(扩展)
├── 按钮_开始检测
└── 标签_结果
检测姿态
when 按钮_开始检测.Click {
照相机1.TakePicture()
}
when 照相机1.AfterPicture(图片路径) {
图像1.Picture = 图片路径
PoseNet1.检测姿态(图片路径)
}
when PoseNet1.检测完成(关键点列表, 置信度) {
// 关键点列表包含17个点,每个有x, y, score
标签_结果.Text = "检测到 " + 列表长度(关键点列表) + " 个关键点"
标签_置信度.Text = "置信度:" + 数学.保留小数(置信度 * 100, 1) + "%"
// 在Canvas上绘制关键点
画布1.Clear()
var i = 1
while i <= 列表长度(关键点列表) {
var 点 = 列表第i项(关键点列表)
var x = 点.get("x")
var y = 点.get("y")
var score = 点.get("score")
if score > 0.5 { // 置信度阈值
画布1.DrawCircle(x, y, 8, color_red)
}
var i = i + 1
}
// 绘制骨骼连线
绘制骨骼(关键点列表)
}
绘制骨骼连线
procedure 绘制骨骼(关键点列表) {
// 定义骨骼连接关系 [起点, 终点]
var 骨骼连接 = [
[6, 5], // 左肩-右肩
[6, 8], // 右肩-右肘
[8, 10], // 右肘-右臀(注:实际是手腕)
[5, 7], // 左肩-左肘
[7, 9], // 左肘-左手腕
[6, 12], // 右肩-右臀
[5, 11], // 左肩-左臀
[12, 14], // 右臀-右膝
[14, 16], // 右膝-右脚踝
[11, 13], // 左臀-左膝
[13, 15] // 左膝-左脚踝
]
var i = 1
while i <= 列表长度(骨骼连接) {
var 连接 = 列表第i项(骨骼连接)
var 起点 = 列表第1项(连接)
var 终点 = 列表第2项(连接)
var 点1 = 列表第(起点+1)项(关键点列表)
var 点2 = 列表第(终点+1)项(关键点列表)
var s1 = 点1.get("score")
var s2 = 点2.get("score")
if s1 > 0.5 and s2 > 0.5 {
画布1.DrawLine(点1.get("x"), 点1.get("y"), 点2.get("x"), 点2.get("y"))
}
var i = i + 1
}
}
实战案例:姿势识别
判断举手
function 是否举手(关键点列表) {
var 右手腕 = 列表第10项(关键点列表)
var 右肩 = 列表第6项(关键点列表)
var 手腕Y = 右手腕.get("y")
var 肩膀Y = 右肩.get("y")
var 结果 = ""
// 如果手腕在肩膀上方(Y值更小)
if 手腕Y < 肩膀Y {
var 结果 = "右手举起"
}
return 结果
}
判断站立/坐着
function 判断姿势(关键点列表) {
var 左臀 = 列表第12项(关键点列表)
var 右臀 = 列表第13项(关键点列表)
var 左膝 = 列表第14项(关键点列表)
var 臀部平均Y = (左臀.get("y") + 右臀.get("y")) / 2
var 膝盖Y = 左膝.get("y")
var 膝臀差 = 膝盖Y - 臀部平均Y
var 姿势 = "坐着"
if 膝臀差 > 50 {
var 姿势 = "站立"
}
return 姿势
}
性能说明
| 模式 | 帧率 | 适用 |
|---|---|---|
| 单张图片检测 | 1-3秒/张 | 照片分析 |
| 实时视频流 | 2-5fps | 简单交互 |
| 降低分辨率 | 5-10fps | 对实时性要求不高 |
注意:PoseNet在手机端的帧率较低,不适合需要高实时性的应用。
常见问题
Q1: PoseNet检测不到人?
- 确保图片中人物清晰可见
- 全身照比半身照检测效果好
- 光线充足时检测更准确
- 人物距离适中(不要太远或太近)
Q2: 关键点位置偏移?
PoseNet的坐标基于输入图片尺寸,需要缩放到Canvas的实际尺寸:
global 缩放比X = 画布1.Width / 图片宽度
global 缩放比Y = 画布1.Height / 图片高度
global 实际X = 原始X * 缩放比X
global 实际Y = 原始Y * 缩放比Y
总结
| 能力 | 支持 |
|---|---|
| 单张图片检测 | ✅ |
| 实时视频检测 | ⚠️ 帧率低 |
| 17个关键点 | ✅ |
| 骨骼绘制 | ✅ |
| 姿势识别 | ✅ 需自己写逻辑 |
| 多人检测 | 部分扩展支持 |
扫码添加客服咨询