Skip to content
This repository was archived by the owner on Jul 15, 2022. It is now read-only.

跌倒报警器-啦啦队 #41

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# 跌倒报警器 - 啦啦队

## 作品介绍
跌倒是全球老人意外伤害的头号杀手。数据显示,我国60岁以上的老人中,每年因跌倒造成伤害的达2500万人。跌倒后如果不及时急救,很容易有生命危险,那老人跌倒怎么办呢?本项目基于智能手机传感器获取加速度、角速度和偏向角的数据,并通过深度学习算法进行序列数据分类,识别出老人跌倒的情况。当出现意外情况,可以向预先设置的号码求救。也可以通过手机定位功能报告精确的位置方便急救人员快速到达现场。

## 作品截图
![摔倒](截图/摔倒.jpg)
![行走中](截图/行走中.jpg)
## 实现过程

### 收集数据
使用公开的mobifall数据集,共包含1442个片段,每个片段包含一段时间的传感器数据。传感器数据包括加速度传感器、方向传感器和角速度传感器。

### 训练深度学习模型
搭建LSTM模型用于时间序列数据,将传感器数据序列分类成正常行走和跌倒两种标签。

### 开发安卓应用程序
开发安卓应用程序获取传感器数据。将tflite模型部署到手机上并进行实时推理,当判断跌倒后发送http请求报警。

## 团队介绍
[朱融晨](mailto:[email protected])

## 使用到的 AWS 技术
使用 sagemaker 训练深度学习模型
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild
.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
apply plugin: 'com.android.application'

android {
compileSdkVersion 29
buildToolsVersion "29.0.0"

defaultConfig {
applicationId "com.example.falldetect"
minSdkVersion 21
targetSdkVersion 29
versionCode 1
versionName "1.0"

testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}

}

dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])

implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
// Build off of nightly TensorFlow Lite
implementation('org.tensorflow:tensorflow-lite:2.2.0') { changing = true }
implementation('org.tensorflow:tensorflow-lite-support:0.0.0-nightly') { changing = true }
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package com.example.falldetect;

import android.content.Context;

import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;

import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.*;

/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();

assertEquals("com.example.falldetect", appContext.getPackageName());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.falldetect">

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
package com.example.falldetect;

import androidx.appcompat.app.AppCompatActivity;

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.TextView;

import java.util.List;

public class MainActivity extends AppCompatActivity implements SensorEventListener {

private TextView accX;
private TextView accY;
private TextView accZ;
private TextView gyroX;
private TextView gyroY;
private TextView gyroZ;
private TextView orientX;
private TextView orientY;
private TextView orientZ;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 获得SensorManager对象
SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);

// 注册加速度传感器
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_FASTEST);

// 注册陀螺仪传感器
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE),
SensorManager.SENSOR_DELAY_FASTEST);

// 注册方向传感器
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
SensorManager.SENSOR_DELAY_FASTEST);

accX = findViewById(R.id.acc_x);
accY = findViewById(R.id.acc_y);
accZ = findViewById(R.id.acc_z);
gyroX = findViewById(R.id.gyro_x);
gyroY = findViewById(R.id.gyro_y);
gyroZ = findViewById(R.id.gyro_z);
orientX = findViewById(R.id.orient_x);
orientY = findViewById(R.id.orient_y);
orientZ = findViewById(R.id.orient_z);
}

@Override
public void onSensorChanged(SensorEvent event) {
// 通过getType方法获得当前传回数据的传感器类型
switch(event.sensor.getType()) {
case Sensor.TYPE_ACCELEROMETER: // 处理加速度传感器传回的数据
accX.setText(String.valueOf(event.values[0]));
accY.setText(String.valueOf(event.values[1]));
accZ.setText(String.valueOf(event.values[2]));
break;
case Sensor.TYPE_GYROSCOPE: // 处理陀螺仪传感器传回的数据
gyroX.setText(String.valueOf(event.values[0]));
gyroY.setText(String.valueOf(event.values[1]));
gyroZ.setText(String.valueOf(event.values[2]));
break;
case Sensor.TYPE_ORIENTATION: // 处理方向传感器传回的数据
orientX.setText(String.valueOf(event.values[0]));
orientY.setText(String.valueOf(event.values[1]));
orientZ.setText(String.valueOf(event.values[2]));
break;
}
}

@Override
public void onAccuracyChanged(Sensor sensor, int i) {

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.example.falldetect;

import android.app.Activity;

import org.tensorflow.lite.Interpreter;
import org.tensorflow.lite.support.common.FileUtil;

import java.io.IOException;
import java.nio.MappedByteBuffer;

public class Model {

private static Interpreter interpreter = null;

private static Model model = new Model();

private Model(){};

public static synchronized boolean inference(Activity activity, float[] input) {
if (interpreter == null) {
MappedByteBuffer model = null;
try {
model = FileUtil.loadMappedFile(activity, "model.tflite");
} catch (IOException e) {
e.printStackTrace();
}
interpreter = new Interpreter(model
, new Interpreter.Options().setNumThreads(4));
}
float[] singleInput = new float[30*9];
float[][] singleOutput = new float[1][2];
System.arraycopy(input, 30*9, singleInput, 0,
Math.min(input.length - 30*9, 30*9));
interpreter.run(singleInput, singleOutput);
return singleOutput[0][1] > 0.5;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="85.84757"
android:endY="92.4963"
android:startX="42.9492"
android:startY="49.59793"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
android:strokeColor="#00000000"
android:strokeWidth="1" />
</vector>
Loading