Android_基于g-sensor的坐下动作的的识别

基于g-sensor的坐下的姿势识别。手机需要放在口袋里,手机拿在手上的暂时还不支持。

如果看不明白,可以先学习这篇文章

计步算法识别:http://blog.csdn.net/finnfu/article/details/45273183


算法流程:

1.五阶移动均值滤波

2.波谷峰值检测

3.根据波形特征判断是起立还是坐下


核心代码:

package com.research.sensor.finnfu.gesturedetector.detector;

import android.os.Environment;
import android.util.Log;

import com.research.sensor.finnfu.gesturedetector.MyApp;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;


/**
 * Created by finnfu on 2017/6/3.
 * 坐下
 */



public class SitDownDetector {
    /*
    * 五阶的均值滤波
    * 第一阶是NUM1个数的均值
    * 第二阶以第一阶的均值为输入,再进行NUM2个数的均值
    * 第三阶以第二阶的均值为输入,再进行NUM2个数的均值
    * 第四阶以第三阶的均值为输入,再进行NUM2个数的均值
    * 第五阶以第四阶的均值为输入,再进行NUM2个数的均值
    * */
    public static final int NUM1 = 8;//取平均值的个数
    public static final int NUM2 = 3;//取平均值的个数
    float[] values1 = new float[NUM1];//一阶滤波,NUM1个值
    float[] values2 = new float[NUM2];//二阶滤波,NUM2个值
    float[] values3 = new float[NUM2];//三阶滤波,NUM2个值
    float[] values4 = new float[NUM2];//四阶滤波,NUM2个值
    float[] values5 = new float[NUM2];//五阶滤波,NUM2个值
    int count1 = 0;
    int count2 = 0;
    int count3 = 0;
    int count4 = 0;
    int count5 = 0;

    ArrayList keyValuelist = new ArrayList();//存放连续的波峰波谷值
    public static final String KEY_NAME_VALUE = "value";
    public static final String KEY_NAME_TIMEMILLIS = "timemillis";
    public static final String KEY_NAME_TYPE = "type";//1代表波峰,-1代表波谷


    //检测波谷相关
    boolean isDirectionDecline = false;
    int continueDeclineCount = 0;
    int formerContinueDeclineCount = 0;
    boolean formerDeclineStatus = false;



    //检测波峰相关
    boolean isDirectionUp = false;
    int continueUpCount = 0;
    int formerContinueUpCount = 0;
    boolean formerUpStatus = false;


    float ValleyPeakThread;
    float ValleyThread;
    int TimeIntervalOfValleyAndPeak = 350;

    float mOldValue = 0;


    public SitDownDetector(){
        ValleyPeakThread  = MyApp.getSitValleyPeakThread();
        ValleyThread = MyApp.getSitValleyThread();
        Log.i("Thread",""+"ValleyPeakThread: "+ValleyPeakThread +" "+"ValleyThread: "+ValleyThread);
    }

    //测试函数
    public void testvalue(){
                try {
            String rootPath = Environment.getExternalStorageDirectory().getAbsolutePath();
            FileReader fileReader = new FileReader(rootPath+"/test.txt");
            BufferedReader bufferedReader = new BufferedReader(fileReader);
            String content = bufferedReader.readLine();
            while (content!=null){
                float v = Float.parseFloat(content);
                inputValue(v);
                content = bufferedReader.readLine();
            }
            fileReader.close();
            bufferedReader.close();
        }catch (IOException e){
            e.printStackTrace();
        }
    }


    public void inputValue(float v){
        //第一次 NUM1个点的均值滤波
        if(count1<NUM1){
            values1[count1] = v;
            if(count1 == NUM1-1){
                averageValue1();
            }
            count1++;
        }else{
            translate1(v);
            averageValue1();
        }
    }

    //一阶滤波的均值
    public void averageValue1(){
        float v = 0;
        for(int i = 0;i < NUM1;i++){
            v += values1[i];
        }
        v = v/NUM1;

        if(count2<NUM2){
            values2[count2] = v;
            if(count2 == NUM2-1){
                averageValue2();
            }
            count2++;
        }else{
            translate2(v);
            averageValue2();
        }
    }
    //二阶滤波的均值
    public void averageValue2(){
        float v = 0;
        for(int i = 0;i < NUM2;i++){
            v += values2[i];
        }
        v = v/NUM2;

        if(count3<NUM2){
            values3[count3] = v;
            if(count3 == NUM2-1){
                averageValue3();
            }
            count3++;
        }else{
            translate3(v);
            averageValue3();
        }
    }

    //三阶滤波的均值
    public void averageValue3(){
        float v = 0;
        for(int i = 0;i < NUM2;i++){
            v += values3[i];
        }
        v = v/NUM2;

        if(count4<NUM2){
            values4[count4] = v;
            if(count4 == NUM2-1){
                averageValue4();
            }
            count4++;
        }else{
            translate4(v);
            averageValue4();
        }
    }

    //四阶滤波的均值
    public void averageValue4(){
        float v = 0;
        for(int i = 0;i < NUM2;i++){
            v += values4[i];
        }
        v = v/NUM2;

        if(count5<NUM2){
            values5[count5] = v;
            if(count5 == NUM2-1){
                averageValue5();
            }
            count5++;
        }else{
            translate5(v);
            averageValue5();
        }
    }

    //五阶滤波的均值
    public void averageValue5(){
        float v = 0;
        for(int i = 0;i < NUM2;i++){
           v += values5[i];
        }
        v = v/NUM2;

        strategy(v);
    }


    public void strategy(float v){
        Log.i("fushiqing",""+v);
        if(keyValuelist.size() == 0){//监测第一个波谷点
            if(mOldValue == 0){
                mOldValue = v;
            }else{
                if(detectFirstValley(v,mOldValue)){
                    resetValleyRelativeParam();
                }
                mOldValue = v;
            }
        }else if(keyValuelist.size() == 1){//监测第二个波峰点
            HashMap hashMap = (HashMap) keyValuelist.get(0);
            if((int)hashMap.get(KEY_NAME_TYPE)  == -1){
                if(detectNormalPeak(v,mOldValue)){
                    resetPeakRelativeParam();
                }
                mOldValue = v;
            }
        }else if(keyValuelist.size() == 2){
            judgeMaybeSitDown();
            keyValuelist.clear();
            resetPeakRelativeParam();
            resetValleyRelativeParam();
            mOldValue = v;
        }
    }



    public boolean judgeMaybeSitDown(){
        boolean result;
        HashMap hashMap1 = (HashMap) keyValuelist.get(0);
        HashMap hashMap2 = (HashMap) keyValuelist.get(1);
        int type1 = (int)(int)hashMap1.get(KEY_NAME_TYPE);
        int type2 = (int)hashMap2.get(KEY_NAME_TYPE);
        if(type1 == -1 && type2 == 1){
            long millis1 = (long)hashMap1.get(KEY_NAME_TIMEMILLIS);
            float v1 = (float)hashMap1.get(KEY_NAME_VALUE);
            float v2 = (float)hashMap2.get(KEY_NAME_VALUE);
            float diffValue = v2 - v1;
            long millis2 = (long)hashMap2.get(KEY_NAME_TIMEMILLIS);
            if(millis2 - millis1 >= 320 && diffValue >= ValleyPeakThread && diffValue <= ValleyPeakThread+1){
                Log.i("result","judgeMaybeSitDown");
                result = true;
            }else{
                Log.i("result","judge sit down failed "+(millis2 - millis1)+" "+diffValue);
                result = false;
            }
        }else{
            Log.i("result","type wrong");
            result = false;
        }
        return result;
    }

    /*
    * 用于检测第一个波谷值,如果检测到符合要求的波谷值,则进行后续的检测
    * 1.持续下降或持平大于等于4个点
    * 2.波谷值小于8.2和7之间
    * */
    public boolean detectFirstValley(float newValue,float oldValue){
        boolean result = false;
        formerDeclineStatus = isDirectionDecline;
        if(newValue < oldValue){
            isDirectionDecline = true;
            continueDeclineCount++;
        }else{
            formerContinueDeclineCount = continueDeclineCount;
            continueDeclineCount = 0;
            isDirectionDecline = false;
        }
        Log.i("process","formerContinueDeclineCount:"+formerContinueDeclineCount +" " +"oldValue:"+oldValue);
        if(!isDirectionDecline && formerDeclineStatus
                && formerContinueDeclineCount >= 6 && oldValue<= ValleyThread+1.2 && oldValue>=ValleyThread){
            long timeMillis = System.currentTimeMillis();
            float valleyValue = oldValue;
            HashMap hashMap = new HashMap();
            hashMap.put(KEY_NAME_TIMEMILLIS,timeMillis);
            hashMap.put(KEY_NAME_VALUE,valleyValue);
            hashMap.put(KEY_NAME_TYPE,-1);
            keyValuelist.add(hashMap);
            Log.i("result","valleyValue"+valleyValue);
            result = true;
        }
        return result;
    }

    /*
    * 用于检测普通的符合要求的波峰
    * */
    public Boolean detectNormalPeak(float newValue,float oldValue){
        Boolean result = false;
        formerUpStatus = isDirectionUp;
        if(newValue > oldValue){
            isDirectionUp = true;
            continueUpCount++;
        }else{
            isDirectionUp =false;
            formerContinueUpCount = continueUpCount;
            continueUpCount = 0;
        }
        if(!isDirectionUp  && formerUpStatus){
            long timeMillis = System.currentTimeMillis();
            float peakValue = oldValue;
            HashMap hashMap = new HashMap();
            hashMap.put(KEY_NAME_TIMEMILLIS,timeMillis);
            hashMap.put(KEY_NAME_VALUE,peakValue);
            hashMap.put(KEY_NAME_TYPE,1);
            keyValuelist.add(hashMap);
            result = true;
        }
        return result;
    }

    public boolean detectNormalValley(float newValue,float oldValue){
        boolean result = false;
        formerDeclineStatus = isDirectionDecline;
        if(newValue < oldValue){
            isDirectionDecline = true;
            continueDeclineCount++;
        }else{
            formerContinueDeclineCount = continueDeclineCount;
            continueDeclineCount = 0;
            isDirectionDecline = false;
        }
        if(!isDirectionDecline && formerDeclineStatus){
            long timeMillis = System.currentTimeMillis();
            float valleyValue = oldValue;
            HashMap hashMap = new HashMap();
            hashMap.put(KEY_NAME_TIMEMILLIS,timeMillis);
            hashMap.put(KEY_NAME_VALUE,valleyValue);
            hashMap.put(KEY_NAME_TYPE,-1);
            keyValuelist.add(hashMap);
            result = true;
        }
        return result;
    }


    //一阶滤波的平移
    public void translate1(float v){
        for(int i=1;i<NUM1;i++){
            values1[i-1] = values1[i];
        }
        values1[NUM1-1] = v;
    }

    //二阶滤波的平移
    public void translate2(float v){
        for(int i=1;i<NUM2;i++){
            values2[i-1] = values2[i];
        }
        values2[NUM2-1] = v;
    }

    //三阶滤波的平移
    public void translate3(float v){
        for(int i=1;i<NUM2;i++){
            values3[i-1] = values3[i];
        }
        values3[NUM2-1] = v;
    }

    //四阶滤波的平移
    public void translate4(float v){
        for(int i=1;i<NUM2;i++){
            values4[i-1] = values4[i];
        }
        values4[NUM2-1] = v;
    }

    //五阶滤波的平移
    public void translate5(float v){
        for(int i=1;i<NUM2;i++){
            values5[i-1] = values5[i];
        }
        values5[NUM2-1] = v;
    }

    //初始化波谷监测的相关值
    public void resetValleyRelativeParam(){
        isDirectionDecline = false;
        continueDeclineCount = 0;
        formerContinueDeclineCount = 0;
        formerDeclineStatus = false;
    }

    //初始化波峰监测的相关值
    public void resetPeakRelativeParam(){
        isDirectionUp = false;
        continueUpCount = 0;
        formerContinueUpCount = 0;
        formerUpStatus = false;
    }

}





  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值