【CurieNano】基于加速度计和神经网络的手势识别-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 6385|回复: 1

【CurieNano】基于加速度计和神经网络的手势识别

[复制链接]
发表于 2017-7-13 18:14 | 显示全部楼层 |阅读模式
本帖最后由 甲基红橙黄绿蓝 于 2017-7-13 20:12 编辑

概述:       采集和处理加速度计的数据,使用 Curie 的硬件神经元进行训练和识别
       特点:
              1、自动捕捉手势:这个程序能分辨静止和运动状态,不需要用户使用按钮等方式告诉程序什么时候开始手势,什么时候结束手势。
              2、消除重力影响:如果你训练了一个手势:画圈,那么CurieNano的倾角将不会对识别造成影响。
              3、识别率因人而异,我测试时达到90%
              4、允许你存储训练结果到板载SPI flash,这样你就能在下次上电时直接用上次训练的结果进行识别。
              5、识别结果通过蓝牙和UART两种方式传输,你可以用 NRF connect ,或者我编写的UWP程序查看蓝牙发送的识别结果。



代码:
       话不多说,先贴代码:github.com/WangXuan95/CurieGesture
Gesture.jpg



思路概述:

一、预处理算法
      因为 Curie 自带神经网络,我要写的只有预处理算法。因为直接获得的加速度计数据是海量的,需要判断哪些是手势片段,哪些是静止片段。另外,还有消除重力偏差,归一化。因此,预处理算法我写了大概100行。

预处理算法包括:手势片段截取、消除重力偏差、时间轴规范化、幅度轴规范化、三轴数据拼接。

1、手势片段截取:
       为了实现自动手势片段截取,首先需要判断Curie是处于近似静止的状态,还是运动状态。我们规定了两个参数:WSIZE、THRESHODE。WSIZE次采样内三轴加速度的极差的和称为A。在数据结构层面,算法采用了一个WSIZE大小的循环数组,每采一次样就把采样数据放入循环数组,再计算循环数组内三轴数据的极差值只和作为A值。若A>THRESHODE,则进入运动状态,若A<=THRESHODE,则进入静止状态。手势片段必须是夹在两个静止状态间的运动状态。当一个手势片段被提取出来后,判断他的长度,若太长或太短都被丢弃,只有时间在30~200个采样周期之间的手势片段,才被认为是一个合法的手势。为了确定参数WSIZE和THRESHODE的值,我们先实现手势截取算法,再不断调整WSIZE和THRESHODE,当算法能正确截取用户的手势时,确定了WSIZE=30,THRESHODE=2000

2、消除重力偏差
       当芯片竖直向上时,获得的加速度数据是 (ax,ay,az) = (0,0,1g) 实际上,我们做手势是无法保证芯片完全向上,比如可能有一个30度的倾角。无论如何,重力会在3轴加速度数据上产生一个常数的偏差。为了消除重力产生的偏差,需要记录截取手势片段前平稳状态的加速度平均值(xAvg1, yAvg1, zAvg1)、以及截取手势片段后的平稳状态的加速度平均值(xAvg2, yAvg2, zAvg2)然后计算前后平均值:
xAvg = (xAvg1+xAvg2) / 2

yAvg = (yAvg1+yAvg2) / 2

zAvg = (zAvg1+zAvg2) / 2

      代表手势前后的静止状态的重力产生的加速度偏差。
      最后,将动态手势片段的三轴加速度片段一一减去以上的重力加速度偏差。


3、时间轴归一化
       因为每个手势时长不同,获得的数据的维数也不同。因此需要时间轴规范化。我们获得的手势片段的长度在30~200维之间,我们使用相邻数据求平均值的方式,把它压缩到30维。


4、幅度轴归一化
       由于每个手势的幅度和猛烈程度不同,因此需要幅度规范化。方法是:计算三轴数据的极差中最大的一个,该极差为delta,然后使用以下公式进行幅值规范化:
规范化数据 = 原始数据 × 128 / delta

       这样,所有的手势片段的最大最小值差距都为128
       幅值规范化有效地减小了手势的幅度带来的影响,比如,同样的画圈手势,缓慢地画一个圈和猛烈地画一个圈,得到的原始数据不同,但经过幅值规范化后,这个差距会减小。


5、三轴数据拼接
       经过以上步骤,我们得到了x,y,z三个方向的三个向量,每个各30维。因为神经网络只接受一维向量,我们将它拼接为一个90维的向量。



二、训练和识别
        将上一步获得的90维数据片段向量交付硬件神经网络进行训练和识别。每个手势训练30次左右,可以获得较好的识别结果。为了用户方便,建议训练的手势都是能回到原地的手势。




三、其他的一些工作
       1、 编写了一个专门用于训练的程序,使用串口传输提示信息,用户在提示下做手势,完成一组手势的训练。
       2、支持使用板载Flash(非易失性存储器)保存神经网络权重数据,训练的数据掉电不丢失。
       3、编写了一个专门用于识别的程序,它从Flash中读取曾经训练好的数据后,对手势进行识别,并用蓝牙把识别结果传出去。
       4、编写了一个Windows10上的UWP程序,调用蓝牙API,获取识别结果,显示在屏幕上。


发表于 2017-7-14 10:13 | 显示全部楼层
虽然看不懂 但是还是给楼猪点个赞
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 06:41 , Processed in 0.259906 second(s), 18 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表