手势识别论文解读

《Learning to Estimate 3D Hand Pose from Single RGB Images》2017.3

本文介绍了从2D彩色图像进行3D hand pose estimation的一种方法,总体来说方法很直观
project page

主要流程

这里写图片描述
如图所示,依次有以下几个环节:

  • 1)HandSegNet, 输入256x256x3, 输出256x256x1的一个hand mask。用一个FCN网络进行手的语义分割,分割之后的结果用来对手附近区域进行截图,以减少计算量及提高准确性
  • 2)PoseNet,用来计算手的21个keypoint, 输入256x256x3,输出32x32x21, 即21张不同keypoint的score map
  • 3)PosePrior,有两个子stream,每个的网络结构除了最后一层不一样其他都一样,输入32x32x21,输出两个层。一个是正则化的手的坐标,以手掌的点为原点,且长度进行了normalize, 即维度为21x3。另一个是相对于实际图片的空间的变换关系,即维度为3

在论文中还用这个结构进行了手语识别,手语识别的网络直接根据手的指示来, 是一个3层的全连接网络,输入维度63, 输出维度35

代码细节解读

使用自带的工具tfprof进行性能分析,发现主要的耗时在于, 2/3耗时在single_obj_scoremap中的tf.nn.dilation2d操作, 1/6耗时在HandSegNet,1/6耗时在PoseNet2D。
同时,为了复用前人训练好的网络参数,将手部截图重新上采样到256x256来使用PoseNet。可见整个网络还有很大的优化空间。cpu上做到实时也不是没有希望。

训练流程解读

《Two-Stream Convolutional Networks for Action Recognition in Videos》2014

框架

这里写图片描述
如上图所示,采用两个stream,一个用静态的单张图片来分类,另一个stream用累积的多张图片的信息来分类

两个stream

Spatial stream ConvNet

非常直观,直接用每张图片过cnn

Optical flow ConvNets

文中提到了两种方法,一种是光流Optical flow stacking,一种是轨迹Trajectory stacking
这里写图片描述

  • 光流采用x,y两个方向的光流,顾如果stack一共L张图片的信息,则有2L张的光流图
  • 轨迹也分x,y的两张图,但是区别是轨迹追踪的是同个点在不同帧上的位移,个人感觉没啥区别,对框架没有影响。

文中还讨论了一些方便用在学习中的特征,可以参考一下

train要点

  • 对于Spatial stream ConvNet, 可以在imageNet等大数据集上进行训练
  • 对于Optical flow ConvNets, 需要在video数据集上训练,文中用了UCF-101 ,HMDB-51这两个,如果你直接采用着两个数据集,需要手工去重,防止某些动作特别多照成过拟合, 文中提到了multi-task learning这种方法。参考《A unified architecture for natural language processing: deep neural networks with multitask learning》
  •  

《Convolutional Two-Stream Network Fusion for Video Action Recognition》2015

code
这篇文章主要是在《Two-Stream Convolutional Networks for Action Recognition in Videos》的基础上进行改进。主要针对其中的两个缺点:
* spatial 和 temporal 的feature没有在pixel层面上进行合作,只用了最后的score
* temporal的操作基本还是基于2d的conv

核心在于引入3d-conv , 3d-pooling,以及对网络结构进行fusion

框架

TODO

《Online Detection and Classification of Dynamic Hand Gestures with Recurrent 3D Convolutional Neural Networks》2016.11

这篇文章的思路就不一样,它主要在于训练一个end-to-end的手势识别结果,不进行具体的hand pose estimation。从视频效果来看也不错
大道至简,对于近距离的手势识别,觉得这个方案应该是目前比较靠谱的。
project page

框架

这里写图片描述
如上图所示基本框架很简单
3D-CNN + RNN + Softmax + CTC loss
文中采用了多模态数据,比如RGB,深度,红外,光流,但本身基于单数据源也效果很好

细节

数据源

project page上,有他们自制的训练数据,大概30G,包含25个预定义动作,20个训练人员,10秒不到的短视频,每个视频一个动作,视频中包含无动作开始+动作+无动作结尾。除此之外,在训练过程中还做了data augment,比如从120x160的尺寸中随机取112x112大小的数据,还有random spatial rotation (±15◦) and scal- ing (±20%), temporal scaling (±20%), and jittering (±3 frames).

3D-CNN

经过测试他们选取了一个clip 8帧来兼顾性能和速度,3D-CNN使用pretrain自C3D的一个比较大的运动数据集。然后在pretrain的weights的基础上直接加softmax算cross entropy的loss来fine tune 3D-CNN的参数。
用了8层conv和2层的全连接。

RNN

在准备好3D-CNN之后,加上RNN,用back-propagation-through-time(BPTT)来做gradient descent就行了。需要注意的是,在训练的过程中,我们主要考虑两个loss

  • cross entropy的loss, 用在entire video上,每段视频按照其中的概率的平均来算
    这里写图片描述
  • CTC(Connectionist temporal classification)的loss,用在online sequence。由于需要在分类结果中添加一个{no gesture}的类别,如果用在segmented video的分类时,需要去掉这歌类(因为视频总属于某个类)
    CTC常用在NLP当中,解决的问题是连续训练的时候不好标数据的问题。比如一段”This is a new world”的语音辨识训练样本,往往不能或者代价太大去辨识出具体哪个字母或者音素在什么位置出现或者终结,CTC提供了一种统计方法,只需要给整体进行标注,并不需要对具体的字母进行标注。
    文中使用了CTC forward algorithm(当然对应的,也有backward的方法),具体算法可以看相关论文,主要在于动态规划图的理解。
    在添加了CTC之后,给原先的类别添加一个{no gesture}的类别,这样子,CTC就能对连续的动作进行标注,其loss为
    这里写图片描述

实现

先说下最终test的效果,112x112x3的大小,在nvidia TitanX上面但clip 8帧的情况下,单次耗时30ms左右。可以说,还不错,但是conv感觉太深,可能没有必要。
具体流程如下

  • 16 epoch对3D-CNN进行fine tune
  • 100 epoch加上RNN,用CTC的loss来训练就可以

《Realtime Multi-Person 2D Human Pose Estimation using Part Affinity Fields》2016.6

code

目标

多人同时Pose Estimation, 如下图所示
这里写图片描述

框架

分两个部分,检测部分和匹配部分,如下图所示
pipeline
(b)关键点检测,(c)part affinity fields即四肢关系检测,(d)二分图匹配

检测部分

如下图所示,上下分为两个brach,分别用来检测关键点 Part Confidence Maps 以及 四肢关系Part Affinity Fields
two branch
分stage的思路和《Convolutional Pose Machines》一致(毕竟是一个团队)。其中的F来自于VGG-19的前十层finetuned的结果,对于stages t>=2, 每个branch的输入都是

F,St−1,Lt−1

的联合,即
这里写图片描述
类似于《Convolutional Pose Machines》,计算每层的loss为
这里写图片描述
其中的W(p)代表本该存在的单位是否在groud true中存在(有些关节或者四肢没有标注)。而对应的total loss为
total loss
注意Part Affinity Fields(PAF)是一些矢量区域,可以通过指定四肢粗细然后在训练数据中根据关节点来标注。

匹配部分

这里首先要明确 Part Confidence Maps和PAF是如何协同确定四肢和关节的预测的
这里写图片描述
如上图,对于图中的任意点P,在PAF的对应点的投影可以用来表示该点在四肢上的相关性。对于 Part Confidence Maps中任意的两个极值点A,B,可以通过插值A,B中的几个点p0, p1, p2, p3, p4…求这些点在PAF上的投影的积分来确定A,B两点作为同肢节的关节点的可能性,如下图
这里写图片描述

有了上面的两点同肢节判定的方法,我们就可以通过匹配每组能相连的点来决定连接与点的有效性。即通过右手腕的confidence map 和右手肘的confidence map的极值点之间的二分图匹配问题
这里写图片描述
这里写图片描述
其中
这里写图片描述
用来表示两个关节点是否相连。这个问题可以用Hungarian algorithm来解决,相对的总体的error,可以通过简单的相加来衡量
这里写图片描述

两个子问题:

  • non-maximum suppression非极大值抑制
    定义:处理一份数据,讲非极大值的部分设置为0,是不是非常直观^^
    实现:常见的高效算法可以参见 ICPR2006-《Efficient Non-Maximum Suppression》,核心是减少重复比较
    应用:检测算法中常见,本质是从众多的滑动窗口的sore中找到局部极值作为检测结果。参见很不错的人脸检测的NMS例子

  • Hungarian algorithm
    目标:解决二分图的最大匹配问题 or 任务分配问题,用在文中是解决不同关键点之间的同肢体匹配问题

《Convolutional Pose Machines》2016

code

目标

实现关键部位的检测,生成scoremap,如下图所示
这里写图片描述

框架

常规的思路类似FCN,但是由于网络层数变深会有不好训练的问题。文章的重点在于分stage来训练,每个stage的结果目标都是最终的score map,通过把原图的feature和上一个stage的输出一起传递到下个stage作为输入,来实现迭代。注意下图中的x’这个网络的权重在所有的stages t>=2中都是共享的,用来提取图像的feature
这里写图片描述

要点

  • 通过分阶段stage的方式,用来迭代并扩大receptive field,每个stage都可量化以及可视化
  • 由于总体网络层数教深,很容易出现gradient vanish的问题, 由于每个stage的输出都可以计算loss,如下,ground true未真实位置点的高斯分布的maxloss, 同时,total loss 为每层loss的和total loss。即文中所谓的Intermediate supervision,每层的gradient都有部份来自于当层的loss。End-to-end learning。
    TODO: 不懂如果用了上面的loss却不intermediate supervision的方法

《Model-based Deep Hand Pose Estimation》2016

code

model-based的方法可以有效的利用手的先验知识,如下图所示: ![这里写图片描述](https://img-blog.csdn.net/20170731213003364?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb2h1NTA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 注:上图中的拇指部分的关节标错了,下移一节应该才正确

主要流程

  1. 应用于深度图首先用检测算法截图,使手在图像中间并resize到128x128
  2. CNN网络用来学习关节26个角度值,这里将会计算一个loss
  3. 通过Hand Model layer将角度值变换成关节点的坐标,坐标也会计算一个loss

流程图如下: ![这里写图片描述](https://img-blog.csdn.net/20170731213621001?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb2h1NTA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

Loss

Loss分为两部分: 一个是最终的Joint Locations的一个Loss ![这里写图片描述](https://img-blog.csdn.net/20170731213832929?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb2h1NTA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) 另一个是在计算关节角度值之后根据生理学模型或者统计求得的每个角度的角度范围,然后用这个合理范围作一个penalty ![这里写图片描述](https://img-blog.csdn.net/20170731213954716?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb2h1NTA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast) Total loss就是上面两个loss的系数相加 ![这里写图片描述](https://img-blog.csdn.net/20170731214032484?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQveGlhb2h1NTA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

要点与改进点

  • 上面第一个loss是joint locations的一个loss,其实还可以直接对关节角度进行regression的loss的比较,效果在文中没有比较。从我的理解来看可能会稍微好一点。因为joint locations的loss虽然GT的location本身是独立的,但是prediect的数据却是有关节角度累计变换来的。而如果采用关节角度regression的loss的话,predict的角度值是互相独立的。
  • 对于Joint Locations的loss其实更大的依赖全局的变换(即手掌相对于图像原点的平移和旋转),以及手指的骨长等参数。全局变换在算法中不予考虑,全当随机误差应该会显著影响学习,手指的骨长这里是通过测试数据来统计并固定的,实际上的误差可能很大
  • 上面的问题中,全局变换可以通过一个joint locations的中心来归一化,手指的骨长则可能需要产品话的时候需要像录入指纹一样对骨长数据进行调整。

《Multimodal Gesture Recognition Using 3D Convolution and Convolutional LSTM》2017.3

这文章其实没有啥新意,不过有代码,而且引用了一些不错的文章。这篇文章是采用将动作序列采样到标准长度,更好的替代方法是采用ctc

框架

两个steam,分别处理RGB的图像和Depth图像
这里写图片描述
其中每个子stream的框架如下:
这里写图片描述

值得一提的子模块

convolutional LSTM

这里写图片描述
在常规的LSTM中,上面的 * 是矩阵乘法,而convolutional LSTM中,上面的X,H都是二维数据(类似图像),* 也变成了convolution操作

Spatial Pyramid Pooling

参看下面的文章《Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition》

《VideoLSTM Convolves, Attends and Flows for Action Recognition》2016.7

《Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition》2014.6

目标

图像金字塔方法,多尺度。解决两个问题

  • 弥补传统的分类网络中图像要求固定的缺点
  • 提供多尺度的信息(传统的cnn通过层数的增加确实能增加perceptive field,但是CNN的视野基本像放大镜一样中间的显著,边缘模糊,这个时候金字塔方法能够提供一个全局信息)

框架

非常直观,如下图
这里写图片描述
采用多个尺度的pooling(比如Max pooling),与传统的pooling不同的是,窗口大小不固定,而是依据输入来变化,比如输入是一个100x100x5的feature map,现在我们需要对其作左边蓝色的SPP,则直接将100划分成四段,对每个bin中的25x25作Max pooling, 得到的结果就是16x5的一个vector,这样每层出来的结果都是定长的。

train方法

如何利用现有框架的方法来训练是个问题

single-size training

对于传统的固定大小的输入,使用金字塔方法也能获得多尺度信息来提升准确性,这个时候可以简单的用传统的pooling的方法来拼接就可以(根据bin的数目来算出所需要的size和stride),如下图所示
这里写图片描述

multi-size training

要像训练得到一些变尺度的信息,比如一个数据集原先图片的尺寸都是224x224,可以通过resize所有数据到180x180,这样,我们用224x224可以训练一个网络,用180x180也训练一个网络,都采用上面single-size training的方法。而两个网络中的参数数目是相同的,我们share两个网络中的参数,这样tain出来的参数更加符合多尺度特征。
在test的时候,则不论尺寸大小,这个时候poolling的size和stride需要根据数据确定。

《Gesture Recognition with a Convolutional Long Short-Term Memory Recurrent Neural Network》2016

水文,简单的cnn+lstm。唯一的收获是可以使用图像差来做输入,即
这里写图片描述

《Real time gesture recognition using Continuous Time Recurrent Neural Networks》

思路很有意思,不直接recognize,而是去predict下一步来recognize

有意思的亮点

首先采用的是三轴加速度计的输出,这一点本身比较适合predict next。
核心思路就是,对于每个gesture,训练一个下面的预测器:
这里写图片描述
即根据t-1时刻的值来预测t时刻的x,y,z三个传感器输出。
学习好之后,对于recognize过程,输入是一个序列,可以将输入放到所有的gesture的predict当中,比较输出的predict error的大小,最小的即为预测值。

猜你喜欢

转载自blog.csdn.net/guo1988kui/article/details/82192357