广告行业中那些趣事系列26:基于PoseNet算法的人体姿势相似度识别

2022-05-05 13:28:45 浏览数 (1)

摘要:本篇从理论到实践分享了基于PoseNet算法的人体姿势相似度识别项目。首先介绍了项目背景,因为部门搞活动需要大家去模仿夸张搞笑的表情和姿势来提升活动的可玩性,所以需要利用CV算法对图片进行相似度打分;然后详细讲解了人体姿势相似度识别算法,主要包括基于PoseNet算法来识别姿势和计算姿势相似度两个流程;最后基于已有的开源项目进行二次开发实现了人体姿势相似度识别项目。对于以前从未接触过CV项目的我来说既是挑战也是契机。因为之前主要做NLP相关的项目,而实际业务场景中经常会有NLP和CV交叉相关的项目,所以就需要对CV也有一定的了解。通过这个项目相当于慢慢入了CV的门,最终的目标是不变的,将更多更好的机器学习算法落地到实际业务产生更多的价值

下面主要按照如下思维导图进行学习分享:

01项目背景介绍

1.1 为啥要做人体姿势相似度识别

还是惯例讲下为啥要学习人体姿势相似度识别的背景,一方面让大家了解下我做这件事的原因,另一方面对于想借鉴该项目的小伙伴会有所帮助。因为年底了部门想搞一个活动,就是提前准备一些夸张搞笑的表情和姿势,然后大家来进行模仿,根据模仿的相似度来打分,分数越高对应的礼物越好,主要作用是增加活动的可玩性,带动更多的小伙伴参与进来。下面是表情和姿势的模仿效果图:

图1 夸张搞笑表情和姿势的效果图

因为表情和姿势的识别其实是两个模型,我主要负责姿势相似度识别,所以本文主要讲下如何识别姿势的相似度。关于表情的相似度打分后面研究下再分享出来。

1.2 学点CV知识是为了在NLP走的更远

上面讲了下为啥要做人体姿势相似度识别的业务背景。因为我其实之前主要是做NLP相关的工作,CV这块接触的实在很少。但是因为我们今年会做一些广告文案自动生成相关的业务,就是根据一定的生成条件比如标签分类来自动生成广告文案。比如现在要创建一个传奇游戏标签类型的广告,我们会将传奇游戏标签作为条件来自动生成一批广告文案提供给广告主选择,这样广告主就不需要自己写文案了,直接从文案库里选一条用就行了。有条件广告文案生成模型的好处在于一方面可以节约广告主撰写广告文案的成本,另一方面可以提升平台的服务水平,吸引更多的广告主来我们平台投放广告。因为广告文案生成模型可能会涉及到将广告素材图片也作为生成条件,属于NLP领域和CV领域的交叉,所以需要学习和储备一点CV知识,后面可以更好的去完成将广告素材图片也作为条件去生成广告文案。整体来说就是“学点CV知识是为了在NLP走的更远”。

02 人体姿势相似度识别算法详解

2.1 项目目标和效果图

人体姿势相似度识别项目的目标其实非常简单,就是输入两张人体姿势的图片,输出姿势相似度的得分。经过调研,发现TensorFlow开源的PoseNet模型可以很好的满足我们的需求。下面是我们项目完成之后的效果图:

图2 瑜伽姿势相似度识别:标准姿势和不标准姿势

我们提供一张标准的瑜伽姿势图,也就是上图中蓝色衣服的图片。然后分别提供一张模仿的比较像(灰色衣服)和不像的(白色衣服)两张图片进行对比,灰色衣服是模仿的比较像的,所以相似度得分比较高在0.95以上,而白色衣服是模仿的不像的,所以相似度得分比较低仅在0.7左右。这就是项目目标和效果图说明。

2.2 项目整体流程

项目整体流程分成两步,第一步是基于Tensorflow的PoseNet模型识别出人体姿势,第二步就是计算两个人体姿势的相似度得分。下面会对两个步骤进行详细说明。

2.3 基于PoseNet算法识别人体姿势

2.3.1 算法原理

基于PoseNet算法识别人体姿势通俗的理解就是输入一张图片,模型会返回图片中人的姿势。这里姿势主要包括17个关键点。需要说明的是因为模型主要目标是识别图片中人的姿势,也就是人身体的关键位置点,所以并不会关注图中的人是谁,也就是说不会进行人脸识别(好处在于可以保护人的隐私)。PoseNet算法会识别出人的姿态,具体如何刻画这个姿态主要是通过人的17个关键部位,每个部位会得到一个检测结果的信任值,信任值范围在0-1之间,1代表检测结果的信任值是最高的。下面是PoseNet算法可以检测的17个关键点图:

图3 PoseNet算法可以检测的17个关键点

只要你的电脑上安装了摄像头就可体验Tensorflow官方提供的PoseNet算法,下面是PoseNet算法的demo,有兴趣的小伙伴可以感受下,支持单目标姿势和多目标姿势,下面是体验demo的链接和体验效果图:

https://storage.googleapis.com/tfjs-models/demos/posenet/camera.html

图4 PoseNet算法同时支持单人和多人姿势识别

2.3.2 人体姿势识别流程

人体姿势识别流程整体分成两步,第一步是将图片作为特征输入到CNN卷积神经网络中;第二步就是利用单姿势或多姿势解码算法输出姿势、姿势置信度得分、关键点位置以及关键点置信度得分。下面是PoseNet模型的姿势检测流程:

图5 PoseNet模型的姿势检测流程

姿势、姿势置信度得分、关键点位置以及关键点置信度得分是PoseNet刻画人体姿势的重点,下面通过一张示例图进行详细说明:

图6 PoseNet如何刻画人体姿势

PoseNet模型可以说是从高低两个层次来刻画人体姿势,具体是先识别出人体的17个关键点,然后根据所有关键点来刻画人的整体姿势。先来看看高层次的抽象姿势以及姿势置信度得分。上图中左边部分PoseNet算法识别出两个人,其中person1的姿势置信度得分为0.8,person2的姿势置信度得分为0.7。姿势是PoseNet算法返回的最高层次的目标,刻画的是某个人整体的情况,姿势的置信度得分越高,说明模型越有把握识别当前这个人的姿势,那么对应的可靠性就会越好。而具体模型是如何认为识别的把握越高则主要通过这个人对应的17个关键位置点的置信度情况。可以这么简单的理解,如果一个人对应的17个关键点越清晰,模型就认为这个人整体的姿势越清晰。从上图中也可以发现person1相比于person2来说关键点位置会更加丰富,所以对应的置信度得分也会越高;

然后再看看关键点位置以及各个关键点的置信度得分。上图中右边部分显示了person1的两个关键点位置以及对应的关键点置信度得分。关键点位置主要通过二维坐标来显示,分别显示了左肘(left elbow)和右肩(right shoulder)。其中左肘的置信度得分是0.9,说明模型认为是左肘的可信度很高,而右肩的置信度得分是0.6,模型认为是右肩的可信度则没那么高了。

2.3.3 模型输入

模型输入主要包括以下四部分:

  • 输入图像:输入图像是指需要检测的图片;
  • 图像比例因子:图像比例因子主要用于控制图片缩放的比例,范围是0.2-1,默认值为0.5。当通过网络传输图片时会根据实际业务需求对需要检测的图片进行缩放。如果线上实时要求较高可以对图片进行更高比例的缩小,那么网络的传输速度就会更快,但是模型识别的准确率可能会有所下降。其实质是调节线上识别速度和模型效果准确率;
  • 水平翻转:水平翻转主要是控制对检测的图片是否进行水平翻转,默认是false;
  • 输出步幅:输出步幅会影响神经网络中层的高度和宽度。输出步幅越低,模型的准确率就会越高,但是相对的线上识别速度就会越慢。通俗的理解其实有点像图片的分辨率问题,步幅越低,图片的分辨率就越高,分辨率越高可以认为是图片更高清了,那么模型的识别准确度就会越高,对应的模型的识别速度就降低了。下面是同样一张照片使用不同步幅对模型准确率和识别速度的对比图:

图7 不同输出步幅对模型准确率和识别速度的对比

2.3.4 模型输出

模型输出主要包括两大块,第一块是代表整体的姿势以及姿势的置信度得分,第二块则是代表部分的每个姿势的17个关键点位置以及对应的关键点置信度得分。下面是一个输出示例图:

图8 PoseNet模型输出示例

通过上图输出示例可以看出这个姿势的整体置信度 为0.6694,这个姿势包含17个关键点,每个关键点会有对应的名称、二维坐标位置以及关键点对应的置信度得分。比如第一个关键点是鼻子(nose),对应的置信度得分是0.8434,并且还会返回鼻子对应的二维坐标。

2.4 计算姿势相似度

上面是通过PoseNet模型如何得到人体姿势以及姿势包含的17个关键点流程。通过整体的姿势和局部的17个关键点我们就能很好的刻画人体的姿势。通过PoseNet算法我们可以分别拿到两张图片中人的姿势数据,接下来就是如何计算两个姿势的相似度问题。下面通过一个实际的例子进行说明。

第一步先拿到两张图片对应的姿势pose1和pose2:

图9 两张图片返回的人的姿势数据

需要说明的是基于PoseNet算法对于图片中的每个人会返回17个关键点,这里为了简单说明仅选用其中三个关键点;

第二步将姿势数据打平,得到每个姿势的坐标以及置信度得分:

图10 将姿势数据打平

因为有三个关键点,每个关键点包含二维坐标和置信度得分,将坐标位置向量打平就得到了6维向量vectorPose1XY,而置信度得分向量vectorPose1Scores是4维,其中前三维是三个关键点对应的置信度得分,最后一维是关键点打分的总和,比如2.5=0.9 0.9 0.7;

第三步进行标准化操作:

图11 标准化操作

标准化操作分成两阶段,第一阶段会分别对每个关键点的横坐标X和纵坐标Y进行如下操作,比如第一个姿势的第一个关键点对应的横坐标x1变成了(x1-x_min)/xy_max;第二个阶段则会进行L2规范化操作;

最后一步就是根据得到的向量计算两张图片中姿势的相似度得分,主要是利用余弦相似度公式计算,姿势越相似,那么得分越高,最高分为1。

03 项目实战

3.1 借鉴开源项目

因为这个人体姿势相似度识别项目主要是用于部门活动,需要在不影响当前工作的前提下利用业余时间完成,并且时间非常紧。一句话形容就是不仅不能占用正常的工作时间,而且还需要快速搞出来,所以最有效的方法就是看看有没有类似的开源项目进行二次开发。经过调研主要基于以下两个开源项目完成:

开源项目1:https://github.com/tensorflow/tfjs-models/tree/master/posenet

开源项目2:https://github.com/freshsomebody/posenet-similarity

先介绍下这两个开源项目。开源项目1就是TensorFlow的PoseNet模型,通过这个模型苏输入一张图片就会返回图片中人的姿势、姿势置信度得分、关键点位置以及关键点置信度得分;开源项目2是基于开源项目1开发的,先基于PoseNet算法得到两张图片人的姿势,然后提供了三种计算相似度的算法策略就可以返回姿势的相似度得分,这三种相似度算法策略分别是weightedDistance、cosineDistance、cosineSimilarity。实际项目中我主要使用的是cosineSimilarity余弦相似度策略。整体来说非常简单,通过TensorFlow.js的方式传入两张图片的地址就会返回相似度得分,开源项目2提供的源码如下:

图12 开源项目posenet-similarity对应的源码

3.2 开源项目存在的问题及解决策略

上述源码存在两个重要的问题,经过一番折腾,下面是解决的策略:

  • 图片输入的时候会报异常script error,解决策略是添加crossorigin='anonymous'就可以了;
  • 实际应用中会发现传入同样两张图片得到的姿势相似度得分可能不同。经过排查发现主要是因为图片加载速度导致。因为模型是通过js直接部署在网页上,所以需要保证两张图片加载完成之后再调用模型计算姿势的相似度得分就可以解决了。

最后代码开源到我的github上了,有兴趣的小伙伴可以下下来玩玩:

https://github.com/wilsonlsm006/posenet-similarity

总结及反思

本篇从理论到实践分享了基于PoseNet算法的人体姿势相似度识别项目。首先介绍了项目背景,因为部门搞活动需要大家去模仿夸张搞笑的表情和姿势来提升活动的可玩性,所以需要利用CV算法对图片进行相似度打分;然后详细讲解了人体姿势相似度识别算法,主要包括基于PoseNet算法来识别姿势和计算姿势相似度两个流程;最后基于已有的开源项目进行二次开发实现了人体姿势相似度识别项目。对于以前从未接触过CV项目的我来说既是挑战也是契机。因为之前主要做NLP相关的项目,而实际业务场景中经常会有NLP和CV交叉相关的项目,所以就需要对CV也有一定的了解。通过这个项目相当于慢慢入了CV的门,最终的目标是不变的,将更多更好的机器学习算法落地到实际业务产生更多的价值

0 人点赞