在Python中使用OpenCV训练神经网络来检测手势!

王尧的技术 2018-12-18

点击上方关注,All in AI中国

在Python中使用OpenCV训练神经网络来检测手势!

手势→预测→行动

您可以在此处找到Github项目存储库中的代码,或在此处查看最终的演示文稿幻灯片。

(github传送门:

https://github.com/athena15/project_kojak

PPT传送门:

https://docs.google.com/presentation/d/1UY3uWE5sUjKRfV7u9DXqY0Cwk6sDNSalZoI2hbSD1o8/edit#slide=id.g49b784d7df_0_2488)

灵感

想象一下,你正在举办一个生日聚会,每个人都玩的很开心,音乐也嗨到了极限,我们经常在抖音上看到的大声呼唤天猫精灵、小米小爱等智能音响的场景,在这种时候就不起作用了,很可能它们根本听不到你的声音,基本上你也找不到遥控器,但如果这个时候你在谈话当中张开一只手,某个手势,你的智能家居设备就可以识别这种姿势,关闭音乐,然后调亮灯光打到生日寿星的脸上。那确实是有点浪漫,也有点酷的。

背景

很长时间我都对手势检测感到好奇。我记得当第一部微软Kinect问世的时候- 我只用一挥手就可以玩游戏并控制屏幕。慢慢地,谷歌主页和亚马逊Alexa等设备发布,似乎手势检测失去了语音的雷达的支持。不过,随着Facebook门户网站和亚马逊回声秀(Amazon Echo Show)等视频设备的推出,我想看看是否有可能构建一个能够实时识别我的手势的神经网络,并运行我的智能家居设备!

数据和我的早期模型

我对这个想法感到很兴奋,并迅速采取了行动,就像我被射出大炮一样。我开始在Kaggle.com上使用手势识别数据库,并探索数据。它由20,000个标记的手势组成,如下面所示。

在Python中使用OpenCV训练神经网络来检测手势!

奇怪的图像,但标签丰富

当我阅读图像时,我遇到的第一个问题是我的图像是黑白的。这意味着NumPy阵列只有一个通道而不是三个通道(即每个阵列的形状是(224,224,1))。因此,我无法将这些图像与VGG-16预训练模型一起使用,因为该模型需要RGB的3通道图像。这是通过在图像列表上使用np.stack解决的,X_data:

在Python中使用OpenCV训练神经网络来检测手势!

一旦我克服了这个障碍,我就开始建立一个模型,使用一个训练-测试分割,完全显示照片10个人中的2个。在重新运行基于VGG-16架构的模型后,我的模型获得了总体0.74的F1分数。这是非常好的,因为超过10个类的随机猜测平均只能得到10%的准确率。

但是,训练模型以识别来自同质数据集的图像是一回事。另一个方法是训练它以识别以前从未见过的图像是另一种。我尝试调整照片的光线,并使用深色背景- 模仿模特训练过的照片。

我也尝试过图像增强——翻转、倾斜、旋转等等。虽然这些图像比以前做得更好,但我仍然无法预测,而且在我看来是不可接受的——结果。我需要重新思考这个问题,并提出一种创造性的方法来使这个项目发挥作用。

要点:训练你的模型,让它尽可能接近真实世界中的图像

重新思考问题

我决定尝试新的东西。在我看来,训练数据的奇怪外观与我的模型在现实生活中可能看到的图像之间存在明显的脱节。我决定尝试构建自己的数据集。

我一直在使用OpenCV,一个开源计算机视觉库,我需要一个工程师一个解决方案,从屏幕上抓取一个图像,然后调整大小并将图像转换成我的模型可以理解的NumPy数组。我用来转换数据的方法如下:

在Python中使用OpenCV训练神经网络来检测手势!

简而言之,一旦您启动并运行相机,您可以抓取框架,对其进行转换,并从模型中获取预测:

在Python中使用OpenCV训练神经网络来检测手势!

在网络摄像头和我的模型之间的连接管道取得了巨大成功。我开始思考什么是理想的图像,输入到我的模型之中。一个明显的障碍是很难将感兴趣的区域(在我们的例子中,一只手)与背景区分开来。

提取手势

我采用的方法是任何熟悉Photoshop的人都熟悉的方法- 背景减法。从本质上讲,如果你在你的手进入场景中先拍了一张照片,你可以创建一个“蒙版”,除了你的手之外,它将删除新图像中的所有内容。

在Python中使用OpenCV训练神经网络来检测手势!

背景掩蔽和二进制图像阈值

一旦我从我的图像中减去背景,然后我使用二进制阈值使目标手势完全变白,背景完全变黑。我选择这种方法有两个原因:它使手的轮廓清晰明了,这使得模型更容易在不同肤色的用户之间进行推广。这创造了我最终训练模型的照片“轮廓”般的照片。

构建新数据集

现在我可以准确地检测到我的手中的图像,我决定尝试新的东西。我的旧模型没有很好地概括,我的最终目标是建立一个能够实时识别我的手势的模型- 所以我决定建立自己的数据集!

我选择专注于5个手势:

在Python中使用OpenCV训练神经网络来检测手势!

我策略性地选择了4个手势,这些手势也包含在Kaggle数据集中,所以我可以在以后对这些图像交叉验证我的模型。

从这里开始,我通过设置我的网络摄像头来构建数据集,并在OpenCV中创建一个点击绑定来捕获和保存具有唯一文件名的图像。我试图改变帧中手势的位置和大小,这样我的模型就会更完善。很快,我建立了一个每个包含550个轮廓图像的数据集。是的,你没看错,我拍摄了超过2700张图片。

训练新模型

然后我使用Keras和TensorFlow构建了一个卷积神经网络。我开始使用优秀的VGG-16预训练模型,并在顶部添加了4个密集层和一个drop层。

然后,我采取了不寻常的步骤,选择在我之前尝试过的原始Kaggle数据集上交叉验证我的模型。这是关键,如果我的新模型无法概括为之前没有训练过的其他人的手的图像,那么它并不比我原来的模型好多少。

为了做到这一点,我将相同的变换应用到我应用于训练数据的每个Kaggle图像——背景减法和二进制阈值处理。这给了他们一个类似我的模型熟悉的“外观”。

在Python中使用OpenCV训练神经网络来检测手势!

L,好吧,Palm转换后的Kaggle数据集手势

结果

该车型的性能超出了我的预期。它几乎可以对测试集中的每个手势进行正确分类,最终获得98%的F1分数,以及98%的精确度和准确度分数。这是个好消息!

正如任何经验丰富的研究人员所知道的那样,在实验室中表现良好而在现实生活中表现不佳的模型价值不大。在我的初始模型遇到同样的失败后,这个模型在实时手势上表现良好。

智能家居集成

在测试我的模型之前,我想补充一点,我一直都是一个智能家居爱好者,我的愿景一直是用我的手势控制我的Sonos(无线wifi音箱)和飞利浦Hue灯。为了方便地访问Philips Hue和Sonos API,我分别使用了phue和SoCo库。它们都非常简单易用,如下所示:

在Python中使用OpenCV训练神经网络来检测手势!

使用SoCo通过Web API控制Sonos可以说更容易:

在Python中使用OpenCV训练神经网络来检测手势!

然后,我为不同的手势创建了绑定,以便使用我的智能家居设备执行不同的操作:

在Python中使用OpenCV训练神经网络来检测手势!

当我最终实时测试我的模型时,我对结果非常满意。模型在绝大部分时间都准确地预测了我的手势,并且我能够使用这些手势来控制灯光和音乐。有关演示,请参阅:

在Python中使用OpenCV训练神经网络来检测手势!

来源:https://towardsdatascience.com/training-a-neural-network-to-detect-gestures-with-opencv-in-python-e09b0a12bdf1

相关推荐