从零开始玩人工智能—人脸 API—02

前文介绍了人脸API,但没有一个完整的功能实现,各个功能的API始终如散开的珍珠一样,不能串成珠链。到底这套API是如何工作的呢?Person、Person Group、FaceList、Face这些不同的对象是怎么发生联系的呢?

于是,我决定写一个相对完整的简单程序,完成一个对人脸进行识别的功能。

仔细看了看文档,琢磨了一下。为了实现人脸识别,需要实现以下几个步骤:

1、创建一个Person Group。人需要通过组来进行管理组织。每个组最多有1000个人,免费的每个订阅最多1000人,S0订阅的每个组10000人,每个订阅上限1M组、100M人。

2、创建一个Person。人是Face的拥有着。每个人最多有248张脸的图片。和人关联的脸是持久化的persistedFace,而使用detect等api读取的是非持久的Face。

3、为Person提供几张不同的Face。除了Face,还有FaceList对象,但更多用于分辨类似的脸。我估计要进行人脸识别,用Face对象就可以。

4、对提供的几张Face进行训练。人工智能需要对输入进行训练,利用认知服务进行分析并得到结果。理论上提供训练的数据越多,结果越准确。

5、提供一张用于比对的Face。上传一张图片,让人工智能判断是不是同一个人。

开始之前我要首先熟悉一下示例代码。前文提供的示例代码和Face API的示例代码使用了不同的模块。示例代码引入了requests这个库,使用它可以更灵活的完成有关HTTP的各类方法特别是传递数据。所以:

pip install requests

因为有两种不同的数据headers提交方式json和octet-steam,所以分开写了两个不同的headers头部定义。为了便于使用,把订阅的Key和访问的基础链接分别使用变量进行提供。

image

正式开干~首先是创建Person Group。和别的对象不同,PersonGroup的名字和ID都是字符串,只接受小写英文字符和‘-’、‘_’,不多于64个字符。

image

其他对象的ID都是类似GUID的形式。通常在创建对象的时候由服务返回。由于Person Group是首先创建的,所以其ID由用户指定也很合乎情理。创建Person Group之后,就可以在组里面创建人了。

image

每一部我都是用了print来输出获得的json数据。由于添加Face需要提供Person ID,所以在这里我从json里面取出了personId的数据。

Python里面处理json可以用dump、dumps、load、loads不同的方法。loads能够把获得的json数据转成dict或者list,这在我踩过list的坑之后才想明白。一旦json中的数据分层了,转化出来的就是list了,这时就需要逐层处理数据。可以参考Python的手册: 18.2. json— JSON encoder and decoder:https://docs.python.org/2/library/json.html

image

有了personId,就可以为特定的人添加Face了。官方示例代码给的是通过json传递一个图片的url。有很多人在下面问,怎么使用本地的照片呢?其实利用文件,然后使用octet-steam发送给Azure就可以了。经过一番对requests.request()参数的猜测和对文件的尝试,果然就能够把图片传上去了。persistedFaceId其实后面没有直接使用,为了学习我还是把它提取出来了。

为了训练机器,继续传了几张我的帅照……

image

当一个人有了几分脸面之后……哈哈,我们应该训练人工智能了。直接POST特定URL即可。

到了关键的时候了,我们要检验认知服务的效果了。先使用Detect方法输入一张照片。

image

这里其实不需要所有参数,只需要返回faceId就可以。所以把params里面的数据删了也无所谓。不过我想看看完整的输出是怎样的,就全写出来了。

于是就遇到了前面说的坑,使用dict的方法,没法获得list里面的数据。要是一层一层分析…好麻烦啊,转念一想,输出的格式是固定的,因此偷了个懒,直接用list的下标获取faceId的dict,然后再get出faceId。

最后,就是调用Verify方法,确认提供的照片是不是我们之前使用几张照片训练过的人的了。这句话好长去……

image

为了容易体现结果,我还特意用了中文……

image

按照文档说的,高于0.5的评分就可以视作通过,所以属性isIdentical的值为True,直接拿来做条件。

照片是我本人吗?当然,是。

利用Azure的Face API,完成一个人脸识别,很简单吧。