szjuliet 发表于 2021-2-13 23:36:12

【AI2+AI】人工智能舞姿识别app








## 人工智能舞姿识别APP

**难度:** 中级

**课程类型:** 教程

**学科:** 计算机科学

**年级水平:**

- 9~12年级

**本教程由Youth Mobile Power提供**

教程地址: (http://ai2.appinventor.mit.edu/?locale=en&repo=http://appinventor.mit.edu/yrtoolkit/yr/aiaFiles/aiDance/AIDance_Starter.asc)

我们在YR Media的朋友发表了一个有趣的关于人工智能的互动故事,题为“你能教人工智能跳舞吗?”这引起了我们的思考。有没有一种算法来描述、识别或测量一种美妙的舞蹈?舞蹈动作可以量化和测量吗?人工智能可以帮助我们提高舞蹈技巧吗?在这个项目中,你将学习如何使用新的AI技术PoseNet来跟踪身体的关键点,创建骨骼模型,并开发一些基本方法来量化、测量和识别一些舞蹈动作。

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112834xss1qut1imthui7l.gif)

## 1. 项目简介

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112834a161n14yee1t6et1.png)

你喜欢跳舞吗?你擅长吗?你想要提高吗?有没有一种算法来描述、识别或测量一种美妙的舞姿?舞蹈动作可以量化和测量吗?人工智能可以帮助你提高你的舞蹈技巧吗?在这个项目中,我们将学习如何使用新的AI技术PoseNet来跟踪身体的关键点,创建骨骼模型,并开发一些基本方法来量化、测量和识别一些舞蹈动作。

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112834l6d765iur6d4m65d.gif)

**重要**: 这个项目不能使用模拟器来测试app,因为模拟器不能运行MIT App Inventor扩展,比如PoseNet扩展。要确保你的移动设备具备PoseNet所需的硬件功能,请在附件中的.aia测试文件上使用AI2伴侣进行测试。

## 2. 图形用户界面(GUI)

在启动文件中已经创建了一个GUI。可以更改组件的属性来得到你想要的外观和感觉。但不要重命名组件,因为本教程会使用操作指南中给出的名称。

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112834p36364gw83ewso6o.png)

**SwapCameraButton**按钮可以根据用户的意愿切换前置或后置摄像头。**CanvasLiveButton**将画布背景从纯黑色切换到实时摄像机视图。**ResetButton**设置Dance Score得分为零。

**WebViewer**组件![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112834k4ar4pcfhhoz81r2.png)用来显示摄像头视图,**Canvas**组件![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112834qn6is17xiri7444i.png)是在黑色背景或实时摄像机视图背景上创建身体骨架模型的地方。**WebViewer**组件![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112834k4ar4pcfhhoz81r2.png)和**Canvas**组件![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112834qn6is17xiri7444i.png)的尺寸必须匹配,以便对身体进行跟踪。建议不要更改启动文件中给出的默认尺寸。

注意,组件面板最底部是![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112834vk8k19i7g9cg8x1c.png)**PosenetExtension**,这是我们用来跟踪身体关键点的AI技术,它可以帮助你构建身体的骨骼版本。

## 3. PoseNet 关键点

PoseNet追踪的身体关键点是:眼睛、耳朵、鼻子、肩膀、手肘、手腕、臀部、膝盖和脚踝。

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/165124hz4l2l0llbzue2lr.png)

如果PoseNet能够跟踪主体关键点,它就会返回一个包含两个元素的列表,这两个元素表示关键点的x坐标和y坐标。当PoseNet无法跟踪主体关键点时,它会返回一个空列表。

## 4. 初步的GUI代码

初始文件中已经提供了一些GUI的初步代码。研究这些代码可以让你对它们的作用有一个大致的了解。

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112834r02de0dmqn9vu2yl.png)

上面这两组代码块用于将PoseNet的状态传达为“就绪”,或者在出现错误时显示错误消息。

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112835eshlb7163k3mk0kp.png)

每次点击**ResetButton**时,重置Dance Score为零。

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112835sd49iuuumn77tut5.png)

**swapcamera**按钮将相机视图从默认的“前置”视图切换到“后置”视图,反之亦然。

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112835u6jcrsg0s1a1c10g.png)

**CanvasLiveButton**调整一个布尔变量的值,该变量用来在实时背景或纯黑色背景上显示PoseNet构造的骨骼。

## 5. 辅助函数(1)

初始文件中还有一些辅助性的函数。

**getX**和**getY**函数提取给定点的x和y坐标。某个点是一个由PoseNet返回的两个元素组成的列表,它们表示给定点位置的x和y坐标。

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112835uwoiha6tayoizlzt.png)

## 6. 辅助函数(2)

**defined**是一个布尔函数,如果给定点是一个包含两个元素的列表(表示该点位置的x和y坐标),则返回true,否则返回false。如果PoseNet无法检测到身体关键点中的任何一个,则为每个缺失的关键点返回一个空列表。

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112835o76p31je9tk3ette.png)

**allDefined**是一个布尔函数,用于检查给定点列表中的*所有*点是否都已定义。如果*所有*点都已定义,则返回true,否则如果*任意*点未定义,则返回false。我们将使用这个辅助函数来共同检查身体的某些关键点是否被PoseNet扩展正确地跟踪并返回。如果身体的姿势由于光线不好、背景凌乱、衣服松垮等可能原因导致PoseNet无法追踪到身体的任何关键点,将返回一个空列表,说明未能检测到这个关键点。

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112835xszoc5x888npz2fo.png)

## 7. 辅助函数(3)

**distance**是一个函数,当画布上的两个点被定义后,该函数用于计算定义这两个点之间的距离。它使用毕达哥拉斯Pythagorean公式:

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112835peu2u3y92069y9y9.png)

上面的公式也许会让你回忆起高中的几何和代数。

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112835ax5cc1cy70mzy5xw.png)

## 8. 辅助函数(4)

**drawPoint**过程在画布上给定的定义点的位置绘制一个半径为4像素的小圆。这个过程帮助我们画出身体的关键点如关节。我们设置点的半径为4像素,这样关键点肉眼可见。

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112835x1h8j8nkzkjhybnt.png)

**drawLine**过程在画布上的两个定义点之间画一条线段。我们使用这个过程来绘制骨架中的骨骼来代表身体。

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112835wqhls1nfhdbtgx3l.png)

## 9. 姿态更新

当PoseNet扩展 检测到它所跟踪的对象改变了位置时,会触发**PosenetExtension1.PoseUpdated**事件。这个事件处理程序的代码在初始文件中已经创建了,虽然每个被调用的过程(**drawKeyPoints**, **drawBody**, **drawHead**等)的代码都是空的,但接下来你可以很快创建。注意如果用户单击**CanvasLiveButton**时,事件处理程序中的**if then**语句可以确保摄像机实时画面会在画布上播放,画布默认为纯黑色背景。

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112835i85ajuqaav8kzq8k.png)

## 10. 构建骨架
现在我们来编写一些过程。

**drawKeyPoints**过程用来绘制一个红色圆圈来表示PoseNet返回的身体的每个关键点:

+ 设置画布画笔颜色为红色(或其他特别的颜色)

+ 对**PoseNetExtension1.KeyPoints**列表中PoseNet返回的每个点,使用前面提及的辅助过程**drawPoint**绘制一个点。

**提示**

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112835cisoiirdb2izijos.png)

**解决方案**

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112835lm2ky1zay78kikz2.png)

先尝试自己编写代码,如果遇到困难可以参考提示。

**drawBody**过程会画出身体的骨架,通过适当关键点之间画黄线来勾勒骨架:

+ 设置画布的画笔颜色为黄色(或者其他与关键点不同的颜色)

+ 对于**PosenetExtension1.Skeleton**列表中的每块骨骼,使用前面提及的辅助过程**drawLine**在骨骼的两端之间绘制一条直线。

注意:**PosenetExtension1.Skeleton**返回一个“骨骼”列表,其中每个“骨骼”都是一个包含两个关键点的列表,这两个关键点是骨骼两端的点。比如在骨骼中,小腿的骨头是一个由脚踝关键点和膝盖关键点组成的列表。

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112835a3mggcuunlf3foo3.png)

**提示**

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112835iczv34q3kwqr4m22.png)


**解决方案**

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112836mvpd6cvuvvgo0dav.png)

先尝试自己编写代码,如果遇到困难可以参考提示。

## 11. 绘制圆形的头部(可选)

如果想在骨骼肩膀上有一个圆形的头,可以编写**drawHead**过程。否则在肩膀上方只有一些标明耳朵、眼睛和鼻子的关键点,没有圆形的头部,就像在前面动画中所示。

**drawHead**过程:
+ 设置画布的画笔颜色为绿色(或其他一些独特的颜色)
+ 检查是否已定义**LeftEar**和**RightEar**关键点。
+ 用代数的中点公式,以两耳连接线的中点为圆心画一个圆:

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112836tczqmdm29qp77gdd.png)

+ 选择圆的半径为两个耳朵之间距离的一半,确保圆穿过两只耳朵。

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112836csl1olmor3z6ml6g.png)

**提示**

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112836bmogvgzopv3v4gs4.png)

**解决方案**

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112836olxgnwwlxcw3cc9b.png)

注意:如果水平方向的代码太长,可以使用“外接输入项”菜单选项(通过右键单击)来缩小操作所需的空间。要回到默认选项,可使用“内嵌输入项”,如下所示。

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112836eo4gi2a2lt22xnll.png)

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112836m308zwl0vn3v8o33.png)

先尝试自己编写代码,如果遇到困难可以参考提示。

## 12. 测试应用

现在我们使用AI伴侣来测试应用是否运行良好。注意,不能在测试中使用模拟器,因为它不支持MIT App Inventor扩展,如PoseNet。

检查你的app是否可以跟踪你或他人的身体,并可以正确构建骨骼连接身体的关键点。为了获得最佳的PoseNet效果,确保身体部分光线充足,并且背景是纯色。松松垮垮的衣服也可能会干扰对身体关键点的追踪。

如果你用的是手机而不是平板电脑,屏幕可能太小,无法一次显示所有内容。在本例中,由于该项目默认选中了屏幕的“Scrollable”属性,可以通过滚动屏幕来显示想要的内容。也可以选择隐藏**HorizontalArrangement1**组件(该组件用于显示影子舞者的图像)。如果仍然缺少屏幕空间,还可以不勾选**webviewwer1**的Visible属性将其隐藏。如果进行了上述操作,要注意**Canvas1**的尺寸(2500x300)仍然必须完全匹配**WebViewer1**的尺寸。

## 13. 检测舞步

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112838qkxdgjpnxk148gt4.gif)

我们探讨一些简单的舞蹈动作:

**“手在空中”舞步**

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112837tnupa21hnror2pri.png)

**“膝盖向上”舞步I, II**

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112836dd294gl7xk4x9vud.png)

**“特拉沃尔塔”舞步I, II**

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112836dtzt2tcqhpcwqtaa.png)

约翰·特拉沃尔塔著名的《狂热周六夜》舞步

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112837hs6r7yd7ei1965at.png)

“T形”舞步

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112836ldly2qv0vp44pyne.png)

现在我们编写代码来检测这些舞蹈动作。当这些舞蹈动作被检测到时,被跟踪的舞者的舞蹈分数Dance Score将自动增加。

## 14. “手在空中”舞步

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112837g9vftnvnnnajnbbi.png)

过程**checkForHandsintheAirMove**:
+ 首先检查PoseNet返回的以下关键点是否定义:左右手腕和左右耳朵。
+ 定义“手在空中”舞步的一种方法是确保两个手腕点都在各边耳朵点的上方。要做到这一点,只需比较右手腕和右耳的y坐标,并对左手腕和左耳做相似的事情。画布上的x轴和y轴的位置如下图所示,原点在画布的左上角。所以右手腕在右耳上方意味着右手腕的y坐标小于右耳的y坐标。左手腕和左耳也是如此。

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112838k5razg2icfh6affq.png)

+ 如果两个手腕都在各边耳朵之上,则增加Dance Score。

**提示**

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112837pb2mzsab17xixixk.png)

**解决方案**

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112838of5ilif8fdfwsi5f.png)

先尝试自己编写代码,如果遇到困难可以参考提示。

## 15. “膝盖向上”舞步

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112838r7h5h70eiyhhjf7h.png)

过程**checkForKneeUpMove**:

+ 首先检查PoseNet返回的以下关键点是否定义:右膝,右臀,左膝,左臀。
+ 定义“膝盖向上”舞步的一种方法是:或者右膝盖点在右臀部点之上,或者左膝盖点在左臀部点之上。要确定这一点,只需比较右膝盖的y坐标和右臀部的y坐标,并对左膝盖和左臀部做相似的事情。
+ 如果任何一个膝盖在其对应的臀部之上,那么增加Dance Score。

**提示**

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112838bouvorzbouqmmqvm.png)

**解决方案**

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112838vujsuw3ittvjnubn.png)

先尝试自己编写代码,如果遇到困难可以参考提示。

## 16. “特拉沃尔塔”舞步

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112838svt04ta3z2z0vxz2.png)

现在你为什么不试着自己定义“特拉沃尔塔”舞步和**checkfortravoltammove**过程呢?

**提示**

定义“特拉沃尔塔”舞步的一种方法是,右手腕在右耳之上,同时左手腕在左肩膀之下;或者左手腕在左耳之上,同时右手腕在右肩膀之下。

**解决方案**

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112839kabj40vlll2bzcez.png)

先尝试自己编写代码,如果遇到困难可以参考提示。

## 17. “T型”舞步

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112839a80ch3ghah3larbr.png)

如果你想要进行挑战,可以试着定义“T型”舞步,舞者水平伸展左右手,形成字母“T”的形状。

**提示**

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112839kbgojl4j2y0znve2.png)

为了确保双手与腕部和肩膀保持水平,两侧的手腕和肩膀的y坐标应该非常接近。同时以伸展的手臂而言,右手腕和右肩膀之间的距离应该非常接近右手腕到右肘部及右肘部到右肩膀的距离之和。左边也一样。

**解决方案**

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/112839q4leznc64lve4kik.png)

注意:如果你了解一些三角函数,可以利用关键点的角关系来简化一些代码。

先尝试自己编写代码,如果遇到困难可以参考提示。

## 18. 测试app

充分检查你的app,直到你(或你用PoseNet跟踪的其他人)做的任何舞蹈动作都会被正确检测到,且Dance Score会增加。正如前面所提到的,为了获得最佳的PoseNet效果,请确保身体光线充足,并且舞者是在纯色背景前。松松垮垮的衣服也可能会干扰对身体关键点的追踪。

在YouTube上找一些舞蹈视频,这些视频要满足只有一个舞者,且背景清晰,用这些视频测试你的app,看看你的应用如何能跟踪舞者。

恭喜你,你已经建立了你的第一个基于人工智能的app,它可以跟踪一个人的动作,并识别一些基本的舞蹈动作。

## 拓展你的app

当前版本的app,如果你保持某种舞姿,Dance Score会不断增加。添加一些智能代码,确保给定的舞蹈动作只会获得一次奖励,直到观察到新的舞蹈动作。

创建一个罚分系统,如果检测到糟糕的舞姿(比如虽然舞者做出了类似T形动作,但舞者的手臂没有水平伸展,形成字母Y而不是字母T的姿势,等等),则Dance Score会扣分。

想象一下这款应用的瑜伽版本,它可以检测不同的瑜伽姿势,并奖励正确的姿势。

你还能想到哪些可以用身体的关键点来描述和量化的嘻哈舞姿?在你的应用中实现这些想法。

还有什么其他的好主意?

## 关于Youth Mobile Power

我们很多人整天都在手机上度过,痴迷各种app。尽管我们知道手机会对我们的注意力、隐私甚至安全构成威胁,但我们还是继续打字和刷手机。但“口袋里的电脑”也为年轻人创造了未开发的机会,让他们学习、联系并改变我们的社区。

这就是为什么麻省理工学院和YR媒体联手推出了青年移动动力系列。YR青少年制作故事,突出年轻人如何以令人惊讶和强大的方式使用手机。与此同时,麻省理工学院的团队正在不断改进MIT App Inventor,让像你这样的用户能够创建像YR报道中提到的那样的APP。

回归初心:从故事中获得灵感,开始制作你自己的应用程序吧!

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/225122vhts3elzg3kelvez.png)

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/225202c28gpg6em8mgpn9z.jpg)

![](https://mc.dfrobot.com.cn/data/attachment/album/202102/13/225202ul44cgigez4s8qsz.png)


YR和麻省理工学院的合作部分得到了美国国家科学基金会的支持。本材料基于美国国家科学基金会在批准号下支持的工作。(1906895, 1906636)。本材料中所表达的任何意见、发现、结论或建议均为作者个人观点,并不一定反映美国国家科学基金会的观点。

点击[此处](https://yr.media/category/interactive/)查看更多由YR创建的应用程序和交互式新闻内容。

rzegkly 发表于 2021-2-14 06:42:20

创客和运动结合体,新年快乐

gada888 发表于 2021-2-14 08:39:55

这个牛

szjuliet 发表于 2021-2-14 09:28:37

rzegkly 发表于 2021-2-14 06:42
创客和运动结合体,新年快乐

康老师新年快乐~

抠脚大佬 发表于 2021-2-15 00:12:46

新年快乐

TuTu 发表于 2021-2-19 17:41:00

太有意思啦!! {:6_210:}

发表于 2021-2-20 17:51:59

新年快乐

熙然 发表于 2021-4-3 23:44:43

牛逼,太厉害了

wondering景 发表于 2021-4-6 11:13:24

好好学习,天天向上

kingrever 发表于 2021-6-18 17:17:21

非常好的课程。

DFHJ8EyC9q5 发表于 2022-7-2 19:01:04

为啥一直显示组件出错啊·
页: [1]
查看完整版本: 【AI2+AI】人工智能舞姿识别app