- 它能做什么
- 准备工作
- 案例一:识别照片里的手势
- 案例二:用关键点数手指
- 案例三:摄像头实时识别,和手机玩石头剪刀布
- 案例四:指尖星星:把贴图贴在手上
- 结果数据说明
- 常见问题
- 完整 .aia 源码与操作指导
机器学习套件(ML Kit)组件在在线版和教育版中提供,离线版(含机房版)不包含。
它能做什么
手势识别找出画面里的手(最多 4 只),给出每只手是左手还是右手、21 个关键点(手腕和每根手指的指根、关节、指尖),以及 7 种内置手势:握拳、张开手掌、食指向上、拇指向下、点赞、剪刀手、我爱你。既能识别图片,也能打开摄像头实时识别,还能把贴图贴在手上。基于 Google MediaPipe,模型随 App 打包,完全离线。
它是 MIT 社区 HandPose 方案(TensorFlow.js + CustomWebView 拓展)和 MIT 石头剪刀布教程(用 Teachable Machine 训练手势)的本土化简化版(全程离线运行):内置组件,不用导入拓展、不依赖网页引擎和国外服务,常用手势不用训练直接认。
准备工作
- 取数据:识别完成后调「手势」(英文代码,适合做判断)、「手势名称」(中文,适合显示)、「左右手」、「关键点」,手序号从 1 开始。「关键点」直接返回
[x, y, z]列表,可用名字见「关键点名称」属性。 - 实时识别:在设计器里放一个垂直布局当「预览容器」,「打开实时摄像头」后画面上直接画出手部骨架、标出手势。
- 系统要求:Android 7.0 以上。
- 联机调试:安卓上用 AI 伴侣调试需要安装 MLKit 版 AI 伴侣(应用宝,包名 cn.fun123.appinventor);普通版伴侣不含识别引擎,调用时会触发「屏幕.出现错误时」(错误码 4722)。直接打包 APK 安装测试不受影响。
- 安装包体积:只有用到本组件的 App 才会打包它的识别引擎与模型,体积以编译结果为准。
- 鸿蒙:暂不支持:鸿蒙系统没有开放手部关键点与手势识别接口,图片识别、实时摄像头都会触发「检测失败时」并说明原因。
案例一:识别照片里的手势
选图或拍照后调「识别图片文件」。「获得手势」事件给出手的数量,在事件里用「左右手」「手势名称」取每只手的结果:
procedure 识别(路径) {
图像_原图.Picture = 路径
标签_状态.Text = "识别中…"
手势识别1.DetectFromFile(路径)
}
when 图像选择器_相册.AfterPicking() { 识别(图像选择器_相册.Selection) }
when 照相机1.AfterPicture(图像位址) { 识别(图像位址) }
when 手势识别1.GotHands(手数, 结果JSON) {
标签_状态.Text = join("找到 ", 手数, " 只手")
标签_结果.Text = join(手势识别1.Handedness(1), ":", 手势识别1.GestureName(1))
}
when 手势识别1.NoHandFound(操作) {
标签_状态.Text = "没找到手"
}
案例二:用关键点数手指
手指竖起来时,指尖(_TIP)在中间关节(_PIP)上方,也就是 y 坐标更小。逐根比较食指、中指、无名指、小指,就能数出竖起几根(手要大致朝上;拇指是横着伸的,要另外比 x 坐标,这里不算):
global 手指数 = 0
procedure 数手指() {
手指数 = 0
foreach 手指 in split("INDEX_FINGER,MIDDLE_FINGER,RING_FINGER,PINKY", ",") {
var 指尖 = 手势识别1.KeyPoint(join(手指, "_TIP"), 1)
var 关节 = 手势识别1.KeyPoint(join(手指, "_PIP"), 1)
if select(指尖, 2) < select(关节, 2) {
手指数 = 手指数 + 1
}
}
}
when 手势识别1.GotHands(手数, 结果JSON) {
数手指()
标签_结果.Text = join(手势识别1.Handedness(1), ":", 手势识别1.GestureName(1), ",竖起 ", 手指数, " 根手指")
}
案例三:摄像头实时识别,和手机玩石头剪刀布
「打开实时摄像头」后,在「实时检测到手」事件里把手势代码换成石头、剪刀、布存进全局变量:石头 = Closed_Fist,布 = Open_Palm,剪刀 = Victory。点「出拳」时手机随机出一个,按规则判输赢:
global 我出 = ""
when 按钮_实时.Click() {
手势识别1.PreviewContainer = 垂直布局_预览
手势识别1.StartLiveCamera()
}
when 手势识别1.LiveHands(手数, 图片宽度, 图片高度, 结果JSON) {
if 手数 == 0 {
我出 = ""
} else {
var 手势 = 手势识别1.Gesture(1)
我出 = choose(手势 == "Closed_Fist", "石头", choose(手势 == "Open_Palm", "布", choose(手势 == "Victory", "剪刀", "")))
}
}
when 按钮_出拳.Click() {
if 我出 == "" {
标签_结果.Text = "先对着镜头比出石头、剪刀或布"
} else {
var 手机出 = randomItem(split("石头,剪刀,布", ","))
if 我出 == 手机出 {
标签_结果.Text = "平局"
} else if (我出 == "石头" and 手机出 == "剪刀") or (我出 == "剪刀" and 手机出 == "布") or (我出 == "布" and 手机出 == "石头") {
标签_结果.Text = join("手机出", 手机出, ",你赢了")
} else {
标签_结果.Text = join("手机出", 手机出, ",手机赢了")
}
}
}
案例四:指尖星星:把贴图贴在手上
锚点用手部关键点名(如 INDEX_FINGER_TIP 食指尖、WRIST 手腕、MIDDLE_FINGER_MCP 掌心附近),宽度和偏移按手掌宽度(食指根到小指根的距离)计,贴图随手的方向旋转(手指朝上时不转)。纵向偏移为负往指尖方向挪:
when 按钮_星星.Click() { 手势识别1.AddSticker("星星", "star.png", "INDEX_FINGER_TIP", 0.8, 0, -0.3) }
when 按钮_摘下.Click() { 手势识别1.ClearStickers() }
when 按钮_保存.Click() { 手势识别1.CaptureLiveFrame() }
when 手势识别1.LiveFrameCaptured(图片地址) {
图像_照片.Picture = 图片地址
}
结果数据说明
手势代码:Closed_Fist 握拳、Open_Palm 张开手掌、Pointing_Up 食指向上、Thumb_Down 拇指向下、Thumb_Up 点赞、Victory 剪刀手、ILoveYou 我爱你,没认出是 None。关键点坐标是图片像素,z 是相对手腕的深度(越小越靠近镜头)。「结果JSON」里每只手含 handedness、gesture、gestureName、gestureScore 和 21 个 landmarks(index、name、x、y、z)。左右手是被拍人自己的左右。
常见问题
| 现象 | 原因与处理 |
|---|---|
| 找不到手 | 手太小、太暗或被挡住;让手占画面三分之一左右,光线充足 |
| 手势一直是「无」 | 手势要做到位、手掌对着镜头;7 种以外的手势都返回 None,可以用关键点自己判断 |
| 手指数不对 | 数手指的方法要求手指朝上;手横着或倒着时改为比较 x 坐标 |
| 普通版伴侣里调用报错 4722 | 请安装 MLKit 版 AI 伴侣,或直接打包 APK 测试 |
| 实时预览黑屏、看不到画面 | 「预览容器」要选布局组件并给明确宽高(如宽度充满、高度 300 像素);第一次打开要允许摄像头权限 |
| 实时检测时界面卡 | 调大「实时事件间隔」,事件里少做事;画面上的标注不受间隔影响 |
完整 .aia 源码与操作指导
导入 HandGestureDemo.aia 后可以直接打包 APK 运行;用 AI 伴侣联机调试请安装 MLKit 版 AI 伴侣。源码文件已通过正式编辑器载入、后台导入和 APK 编译校验;真机识别效果请以实际设备为准。
| 功能 | 操作 | 预期结果 |
|---|---|---|
| 识别照片 | 从相册选一张有手的照片或拍照 | 显示左右手、手势名称和竖起的手指数;两只手时下方显示第二只 |
| 无手 | 选风景照 | 提示没找到手 |
| 实时识别 | 点「实时识别」,对着前置摄像头比手势 | 预览区画出手部骨架、左上角标出手势;状态栏实时显示左右手和手势 |
| 石头剪刀布 | 实时识别时比出石头、剪刀或布,点「出拳」 | 手机随机出拳并判定输赢,比分累加 |
| 指尖星星 | 实时识别时点「指尖星星」,移动食指 | 星星跟着食指尖移动,随手的方向转动;「摘下」清掉 |
| 保存照片 | 贴上星星后点「保存照片」 | 下方显示刚才的画面(含贴图),前置摄像头与预览一样是镜像 |
案例界面与积木源码在仓库 docs/markdown/reference/components/guide/examples/HandGestureDemo/,SHA-256:713b8f351a60db068fd5ede9df2e1475c2ed2fd31245636108d25b3ec318ea0c。
扫码添加客服咨询