查看: 5124|回复: 1

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

[复制链接]
  • TA的每日心情
    开心
    2017-7-3 15:02
  • 签到天数: 56 天

    [LV.5]常住居民I

    发表于 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,获取识别结果,显示在屏幕上。


  • TA的每日心情
    开心
    2021-1-4 08:50
  • 签到天数: 827 天

    [LV.10]以坛为家III

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

    本版积分规则

    热门推荐

    新设计的一款遥控播放音乐机器人
    新设计的一款遥控播放音乐
    近期设计的一款遥控播放音乐歌曲的机器人终于完工了,DF mini mp3模块是真的强大。sol
    ESP8266物联网创意点阵时钟,女朋友看了都想要!
    ESP8266物联网创意点阵时
    [md]本文作者:默 & 铁熊 前段时间我在网上看到了一款很有意思的点阵时钟,它可以
    按键中断无法触发
    按键中断无法触发
    如题,按键中断无法触发,设成电平变化触发中断程序,但是flag的状态一直不变 void
    【原创】全球最小口袋3D打印机mini one直播教程贴
    【原创】全球最小口袋3D打
    最近闲得蛋疼,没事搞个掌上3D打印机,先放效果图吧。 搞了半天,终于能正常打印,
    OLED心率示波仪
    OLED心率示波仪
    在ARDUINO UNO开发板上插上一片0.96寸OLED显示屏并上传已下简单的程序就能构成一个OLE
    Copyright   ©2015-2016  Arduino中文社区  Powered by©Discuz!   
    快速回复 返回顶部 返回列表