可在前端本地运行的AI能力众多,以姿态估计举例

7,364 阅读11分钟

本文为稀土掘金技术社区首发签约文章,30天内禁止转载,30天后未获授权禁止转载,侵权必究!

从事人工智能之前,我做了8年的前端开发。我所说的前端并非特指Web前端,而是与服务后端相对,AndroidiOS这类用户直接看到并交互的部分也算前端。

有老战友就找我聊:“唉!现在我们公司上下都在搞AI,我这个Android是干着急,也插不上手”。

我说,不是啊,AI并非是后端的特权。咱前端也有很多“端侧”的AI,而且种类丰富,小巧灵活。

一、前端也可以运行AI

下图是TensorFlowLite版本,它支持AndroidiOSRaspberry 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软件,从欢迎页面选择“打开已有项目工程”。

所以,不用怕,它很细致,“点击运行按钮”它都写上了。此处不是我有意简写,是我真的没法比它更具体,我再重复一遍算抄袭。

看,这就是让你感到恐惧的陌生知识!尽管它非常友好,你却开局想抵触它。我们不应该这样。

你只需关注下编译时app\download.gradle是否被执行,它的作用是下载模型文件到app\src\main\assets下。我导入项目后,一路运行到底,除了需要等待,没有遇到任何问题。

虽然官方提供了很多运行效果图,但我还是坚持出镜展示一下。这表示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_pointend_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.tflitelabels.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 姿势预测的官方示例代码库

github.com/tensorflow/…

目前为止,得有十多名掘友问过我:TF男孩,你这个TF是什么意思?看我通篇讲TensorFlow,再看我的头像,你应该猜到了吧!

发现没有,上面讲的python例子,可以脱离tensorflow环境运行。它并不要求你pip install tensorflow。同时,它也考虑前端平台的运用。我想,这是一种胸怀吧。向TF学习!