本文为稀土掘金技术社区首发签约文章,30天内禁止转载,30天后未获授权禁止转载,侵权必究!
从事人工智能之前,我做了8年的前端开发。我所说的前端并非特指Web前端
,而是与服务后端相对,Android
、iOS
这类用户直接看到并交互的部分也算前端。
有老战友就找我聊:“唉!现在我们公司上下都在搞AI,我这个Android是干着急,也插不上手”。
我说,不是啊,AI
并非是后端的特权。咱前端也有很多“端侧”的AI,而且种类丰富,小巧灵活。
一、前端也可以运行AI
下图是TensorFlow
的Lite
版本,它支持Android
、iOS
、Raspberry Pi
平台。这些AI
能力,可以在用户的设备上直接运行。
如果你是Web
前端的话,也有TensorFlow.js
可以在浏览器上跑。
二、姿势预测
看着老战友怀疑的眼神,我决定给他演示一个姿态(姿势)估计(预测)
的例子。
利用它,我们可以检测人体关键点的位置和动态,效果如下:
有了上图的数据,可应用的场景就多了。比如下面这个体育动作计数和计时。
除此之外,老人跌倒检测、学生坐姿纠正、工人违规操作等,都可以实现。
TensorFlow
官网关于它的介绍。
开篇它就提供了实例代码。我们就跟着它,下载一个Android示例
运行一下。
链接是 tensorflow.google.cn/lite/exampl…
打不开的话,后面有网盘地址。我怎么会让你得不到代码。
2.1 从运行示例代码起步
假设我们都是第一次下载这个项目(我肯定是假装的)。后面我讲的,更多的是面对新事物的探究方法。
下载完了项目代码,一般情况下我们会一脸茫然。
这时我们突然发现android
文件夹下有一个README.md
。打开它,阅读它。英文的,去翻译。但凡规范的示例项目,都会在README.md
中说明环境要求、操作步骤。
从上面的说明中,我们可以看到要求Android Studio 4.2
及以上,最低SDK是API 21
。它甚至提到打开Android Studio
软件,从欢迎页面选择“打开已有项目工程”。
所以,不用怕,它很细致,“点击运行按钮”它都写上了。此处不是我有意简写,是我真的没法比它更具体,我再重复一遍算抄袭。
看,这就是让你感到恐惧的陌生知识!尽管它非常友好,你却开局想抵触它。我们不应该这样。
你只需关注下编译时appdownload.gradle
是否被执行,它的作用是下载模型文件到appsrcmainassets
下。我导入项目后,一路运行到底,除了需要等待,没有遇到任何问题。
虽然官方提供了很多运行效果图,但我还是坚持出镜展示一下。这表示TF男孩不是拿官方图糊弄读者。他也在操作,并且理论和实践都可行。
为了让新手读者体验这个乐趣,并且避免等待。我把完整的
Android
项目材料打包好了(包含预置模型,可直接安装的apk文件)。文末会附上下载链接。
到这里,我想表达,其实AI
在前端是可以流畅运行的。
不止能运行,客户端一侧的AI
,反而具有得天独厚的优势。主要表现在以下几点:
- 信息采集零延迟:手机都带摄像头,说拍照就拍照,拍完立马能提供给
AI
处理。 - 客户端边缘计算:不用上传数据到云服务器,减轻负载压力,而且现在客户端的算力不容小觑。
- 更本地化的渲染:信息的采集、处理全在本地设备,有助于结果的流式呈现(边处理边渲染)。
前端的朋友们,看看开头那几十项前端可用的AI能力。谁还敢说我们无法助力企业的AI
进程!
我们只需要稍微了解一下AI
的工作原理,再加上我们前端的优势,势必会如虎添翼!
下面我就讲解它的工作原理!
2.2 工作原理
代码跑起来并使用,肯定是没问题的。不管是安卓
、iOS
还是树莓派
,甚至浏览器
。我正好有树莓派
设备,也试了试,没问题。
如果你想定制化需求,将这项能力融入到自家的产品中,那就需要了解它的工作原理了。
讲解原理,用Python
更合适。
不用着急。了解TF男孩的朋友能猜到,后面他会提供简洁又完整还带注释的源码。
2.2.1 关于模型版本
前端的AI能力,一般是在本地加载成品模型直接运行。所以,我们首先要认识这些模型。
这个姿势预测,谷歌很早就开发出来了。2017年发布了第一代模型叫PoseNet
。后来,又推出第二代叫MoveNet
。今天我们只看第二代。
第二代MoveNet
又分为好多版本:
- Thunder:准确、精细,但是速度慢。适合判断瑜伽动作是否到位。
- Lightning:轻量、迅速,但是准确度低。适合拳击、跳绳等高频统计。
- Multipose:主打一个人员多、背景杂。比如排球比赛监测众多球员。
对于很多事情,我以前不理解,比如为什么要那么多分支、版本?都弄成一个不好吗?
后来自己做模型时就明白了:资源就那么多,你是想投入到速度还是精度?
2.2.2 关于出入参数
这几个前端平台,甭管Android
还是iOS
,他们的模型都是同一个,因此出入参数也一样。你学会了一个,相当于全会了。
MoveNet
的输入,支持实时相机数据,也支持图片。后面我们会拿图片做演示。
它的输出是身体上检测到的17个点。它们分别是:
0 鼻子 | 1 左眼 | 2 右眼 | 3 左耳 |
---|---|---|---|
4 右耳 | 5 左肩 | 6 右肩 | 7 左肘 |
8 右肘 | 9 左腕 | 10 右腕 | 11 左胯 |
12 右胯 | 13 左膝 | 14 右膝 | 15 左踝 |
16 右踝 |
具体对应人体部位如下:
2.3 代码讲解
为了便于讲解代码,我特别写了一个精简的Python
项目。地址如下:
github.com/hlwgy/jueji…
仓库文件结构说明:
tflite 模型文件
|--- movenet_lightning.tflite 轻量级模型,它快
|--- movenet_thunder.tflite 精准级别模型,它准
|--- classifier.tflite 分类模型,这是一个瑜伽动作的分类模型
|--- labels.txt 分类模型的种类列表
data.py 数据定义
classifier.py 动作分类库
movenet.py 姿势预测类库
main.py 演示入口类,调用类库
test.jpeg 测试图片
以上代码文件来自官方示例。虽然官方的示例很规范,但对初学者还是不够简洁。官方总是想把所有功能都展示出来,而我只想讲其中的某个点。于是我从几十个文件中,抽出两条主线,组了这个项目。以此来演示如何提取身体的节点数据,以及对结果数据进行应用。
环境支持:python 3.8
类库支持:numpy、cv2
pip install numpy
pip install opencv-python
2.3.1 姿态数据提取
import cv2 # 用于图片处理
from movenet import Movenet # 导入类库
# 构建模型
pose_detector = Movenet('tflite/movenet_thunder')
# 读入图片
input_image = cv2.imread('test.jpeg')
# 将图片交给模型检测
person = pose_detector.detect(input_image)
print(person) # 获得提取结果
通过Movenet
类从路径加载模型。
通过cv2.imread
从路径加载图片数据。
将图片数据交给模型的detect
方法去检测。模型会返回检测结果Person
类。这个Person
就是在data.py
中定义的。
我们打印person
结构如下:
Person(
bounding_box=Rectangle(start_point=Point(x=140, y=72),
end_point=Point(x=262, y=574)),
score=0.61832184),
keypoints=[
KeyPoint(body_part=<BodyPart.NOSE: 0>,
coordinate=Point(x=193, y=85),
score=0.5537756)
……
KeyPoint(body_part=<BodyPart.RIGHT_ANKLE: 16>,
coordinate=Point(x=150, y=574),
score=0.83522)
]
它的内容分为两个部分:
bounding_box
是识别出的人形区域。看来它是先找到人,然后再进行分析。这里包含score
得分,还有矩形框start_point
、end_point
起始点的坐标。
keypoints
是一个数组,里面是身上那17个点
的信息。包含score
得分,body_part
身体部位名称,coordinate
是这个点在图上的(x, y)
坐标。
这样还是太抽象。我们可以把结果画到图片上。
bounding_box = person.bounding_box
keypoints = person.keypoints
# 把人体框选出来
start_point = bounding_box.start_point
end_point = bounding_box.end_point
cv2.rectangle(input_image, start_point, end_point, (255, 0, 0), 2)
# 把识别的17个点画出来
for i in range(len(keypoints)):
cv2.circle(input_image, keypoints[i].coordinate, 2, (0, 0, 255), 4)
运行一下,看看效果:
左边是官方提供的图片,一个外国人。右边是我的靓照,一个中国人。官方给的示例总是完美的。而我扛着扫帚的那只手的手腕,没有识别到,应该是受到了扫帚干扰导致的。
上面演示的是图片作为输入源。其实摄像头也一样。尽管不同终端调用摄像头的代码不一样,但最终都是要获取图像数据并传给模型。以下是一个示例:
……
# 构建摄像头
cap = cv2.VideoCapture(camera_id)
while cap.isOpened():
# 获取图片
success, image = cap.read()
image = cv2.flip(image, 1)
# 将图片讲给模型处理
person = pose_detector.detect(image)
……
2.3.2 姿态数据的应用
获取到17个点
有什么用?怎么用?
这类语言,容易把一个技术人员给问懵。因为程序员常常沉浸在代码的成就中,并以此为豪。
TensorFlow的作者谷歌也想到了这一点。于是它们又提供了一个姿势数据应用的示例:瑜伽动作分类
。
瑜伽有很多动作。比如我们的“金鸡独立”他们叫树式(tree)。这个动作像大树般稳定,在站立时需要向下扎根踩稳,并且保持身体直挺向上延伸。
但凡是一个动作,它就有判别标准。比如坐姿,肯定是膝和腰部近似垂直。而这些是可以转化为数据进行计算的。
我提供的示例项目中有一个classifier.py
文件,模型文件中也有classifier.tflite
和labels.txt
。这就是谷歌针对瑜伽动作的示例。
# 导入类库
from classifier import Classifier
# 构建分类模型
classifier = Classifier('tflite/classifier', 'tflite/labels.txt')
# 将姿势数据传入模型,person结果数据可由上一步获得
categories = classifier.classify_pose(person)
# 给出分类结果
class_name = categories[0].label
print(class_name)
示例中test.jpeg
就是张瑜伽照片,我们来看看效果。
结果识别出这个动作是tree
。
如果你想要定义专属的动作,TensorFlow
也支持你训练自己的数据(文末有链接)。
我还能想到很多的应用。比如你的肢体动作,让另一个动漫形象表现出来。就是你在这招手,模型获取到动作数据,然后把动作用一个可爱的二次元渲染出来。这样你就有了一个替身。
不管怎样,前端并没有被人工智能抛弃。甚至五六年前,TensorFlow
就已经在做这方面的工作了。
如果你是前端,可以去学一学,用AI
加持下自己的技能。在工作上,不管是“先涨工资,再好好干”,还是“好好干,后涨工资”。前提都是你干得了。有钱不花与没钱可花,是两种境界。
三、源码、模型和资料
为了简洁讲解,上面演示的是python
代码。以下是其他前端平台的代码,供朋友们下载和使用。如果你把上面讲的原理和出入参数看懂了,再去干涉以下代码应该很简单。
JueJin_MoveNet
|--- tflite模型文件
|--- movenet_lightning.tflite 轻量级模型,它快
|--- movenet_thunder.tflite 精准准级别模型,它准
|--- movenet_multipose.tflite 多人模型,最多支持6人检测
|--- classifier.tflite 分类模型,这是一个瑜伽工作分类
|--- labels.txt 分类模型的种类列表
|--- posenet.tflite 上一代老前辈posnet,这一代叫movenet
|--- android源码(含模型)
|--- tf_app-release.apk
|--- ios源码
- tflite模型文件:包含多种类型的movenet模型,可选择使用。
- ios源码:需要参照文档,将模型引入。
- android源码(含模型):Android项目,已包含模型。
- tf_app-release.apk:可直接运行的Android示例程序。
四、参考和引用资料
以下是文中所讲的依据,以及部分截图的来源。供有意向进一步学习和研究的朋友查阅。
Pose Estimation 姿态预测的介绍
tensorflow.google.cn/lite/exampl…
Pose Classification 姿势分类的介绍
www.tensorflow.org/lite/tutori…
TensorFlow.js TensorFlow前端版本
blog.tensorflow.org/2021/05/nex…
Github-TensorFlow-pose 姿势预测的官方示例代码库
目前为止,得有十多名掘友问过我:TF男孩,你这个TF
是什么意思?看我通篇讲TensorFlow
,再看我的头像,你应该猜到了吧!
发现没有,上面讲的python
例子,可以脱离tensorflow
环境运行。它并不要求你pip install tensorflow
。同时,它也考虑前端平台的运用。我想,这是一种胸怀吧。向TF学习!