Commit 408bce06 authored by pandersson's avatar pandersson

Updates code structure and README

parent bcafdf29
# WASP AS 1 Assigment: Activity Recognition,
# by Frida Heskebeck, Matthias Mayr, Momina Rizwan and Pontus Andersson
Our activity recognition is based on thresholds.
The approach is to use the mean of the x,y and z accelerometer data.
Over a time interval of two seconds, we look at the difference of the max and min values of the mean.
If the differences is lower than a set threshold, the person is predicted to be standing still.
If the difference is greater than the still treshold but smaller than a set running threshold, the person is predicted to be walking.
Otherwise, the person is predicted to be running.
This repository contains three scripts used to perform activity recognition and data visualization.
The data is stored in the `data` directory. To include your own data, add a subfolder to `data` named Data_YourData.
We assume the scripts are called from the as1-activity-recognition folder.
* `data_visualization.py` allows you to visualize data. Usage: `python data_visualization.py Name DataType`,
where `Name` is the name of the person whose data you wish to show, and `DataType` is either `ACC` or `GYR` for accelerometer and
gyro data, respectively. Red bars are used to separate the data files.
* `get_data.py` is a helper function for `activity_recognition.py`. It collects the data used in the latter script.
* `activity_recognition.py` allows you to do activity recognition. Usage: `python activity_recognition.py Name PresentationMode`,
where `Name` is as in `data_visualization.py` and `PresentationMode` is either `Text` or `ConfusionMatrix`, with
`Text` yielding console output of each prediction and corresponding ground truth, and `ConfusionMatrix` yielding a confusion matrix.
For both options, we print the accuracy in the console.
\ No newline at end of file
No preview for this file type
......@@ -9,40 +9,74 @@ Created on Wed Mar 25 07:38:10 2020
import numpy as np
import sys
from get_data import get_data
import matplotlib.pyplot as plt
#%%
def main():
person = sys.argv[1] # Which person's data?
presentation = sys.argv[2] # What presentation option? (Text or ConfusionMatrix)
freq = 100 # Assume data was collected at 100 Hz
still = 2
walk = 20
# Get mean of accelerometer x,y,z data
acc, ground_truth = get_data(sys.argv[1], 'ACC')
acc, ground_truth = get_data(person, 'ACC')
confMat = np.zeros((3,3))
# Check minimum and maximum value over time interval. Determine activity during time interval based on difference between these
time_interval = 2 # s
correct_guesses = 0
total_guesses = 0
number_correct_guesses = 0
number_total_guesses = 0
for i in np.arange(0, len(acc)//freq - time_interval, time_interval):
acc_one_sec = acc[i * freq:(i + time_interval) * freq]
xMin = min(acc_one_sec)
xMax = max(acc_one_sec)
classes = ['Still','Walking','Running']
true_idx = classes.index(ground_truth[int((2 * i + time_interval) * freq / 2.0)])
gt = ground_truth[int((2 * i + time_interval) * freq / 2.0)]
if xMax - xMin < still: # Some limit for still
print("At time: {}-{}, the person is - Still ({}, Diff: {:0.2f})".format(i, i + time_interval, gt, xMax - xMin))
correct_guesses += int(gt == 'Still')
elif xMax - xMin < walk: # Some limit for walk
print("At time: {}-{}, the person is - Walking ({}, Diff: {:0.2f})".format(i, i + time_interval, gt, xMax - xMin))
correct_guesses += int(gt == 'Walking')
if xMax - xMin < still:
if presentation == 'Text': print("At time: {}-{}, the person is - Still ({}, Diff: {:0.2f})".format(i, i + time_interval, ground_truth[int((2 * i + time_interval) * freq / 2.0)], xMax - xMin))
pred_idx = 0
elif xMax - xMin < walk:
if presentation == 'Text': print("At time: {}-{}, the person is - Walking ({}, Diff: {:0.2f})".format(i, i + time_interval, ground_truth[int((2 * i + time_interval) * freq / 2.0)], xMax - xMin))
pred_idx = 1
else:
print("At time: {}-{}, the person is - Running ({}, Diff: {:0.2f})".format(i, i + time_interval, gt, xMax - xMin))
correct_guesses += int(gt == 'Running')
total_guesses += 1
print("#Correct guesses: {}, #Total guesses: {}, Correct%: {:.2f}".format(correct_guesses, total_guesses, correct_guesses / float(total_guesses) * 100))
if presentation == 'Text': print("At time: {}-{}, the person is - Running ({}, Diff: {:0.2f})".format(i, i + time_interval, ground_truth[int((2 * i + time_interval) * freq / 2.0)], xMax - xMin))
pred_idx = 2
number_correct_guesses += int(true_idx == pred_idx)
number_total_guesses += 1
confMat[true_idx,pred_idx] += 1
print("#Correct guesses: {}, #Total guesses: {}, Correct%: {:.2f}".format(number_correct_guesses, number_total_guesses, number_correct_guesses / float(number_total_guesses) * 100))
if presentation == 'ConfusionMatrix':
fig, ax = plt.subplots()
im = ax.imshow(confMat,cmap='rainbow')
# We want to show all ticks...
#ax.set_xticks(np.arange(len(classes)))
#ax.set_yticks(np.arange(len(classes)))
# ... and label them with the respective list entries
classes_tick = [' ','Still',' ','Walking',' ','Running',' ']
ax.set_xticklabels(classes_tick)
ax.set_yticklabels(classes_tick)
# Rotate the tick labels and set their alignment.
plt.setp(ax.get_xticklabels(), rotation=45, ha="right",
rotation_mode="anchor")
# Loop over data dimensions and create text annotations.
for i in range(len(classes)):
for j in range(len(classes)):
text = ax.text(j, i, confMat[i, j],
ha="center", va="center", color="k")
ax.set_title("Confusion matrix {}, \nrows - true activity, cols - predicted activity".format(person))
#fig.tight_layout()
fig.colorbar(im)
plt.show()
if __name__ == "__main__":
main()
\ No newline at end of file
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Mar 25 07:38:10 2020
@author: frida
"""
import numpy as np
import sys
from get_data import get_data
import matplotlib.pyplot as plt
#%%
def main(person):
freq = 100 # Assume data was collected at 100 Hz
still = 2
walk = 20
# Get mean of accelerometer x,y,z data
acc, ground_truth = get_data(person, 'ACC')
confMat = np.zeros((3,3))
# Check minimum and maximum value over time interval. Determine activity during time interval based on difference between these
time_interval = 2 # s
for i in np.arange(0, len(acc)//freq - time_interval, time_interval):
acc_one_sec = acc[i * freq:(i + time_interval) * freq]
xMin = min(acc_one_sec)
xMax = max(acc_one_sec)
classes = ['Still','Walking','Running']
true_idx = classes.index(ground_truth[int((2 * i + time_interval) * freq / 2.0)])
if xMax - xMin < still: # Some limit for still
print("At time: {}-{}, the person is - Still ({}, Diff: {:0.2f})".format(i, i + time_interval, ground_truth[int((2 * i + time_interval) * freq / 2.0)], xMax - xMin))
pred_idx = 0
elif xMax - xMin < walk: # Some limit for walk
print("At time: {}-{}, the person is - Walking ({}, Diff: {:0.2f})".format(i, i + time_interval, ground_truth[int((2 * i + time_interval) * freq / 2.0)], xMax - xMin))
pred_idx = 1
else:
print("At time: {}-{}, the person is - Running ({}, Diff: {:0.2f})".format(i, i + time_interval, ground_truth[int((2 * i + time_interval) * freq / 2.0)], xMax - xMin))
pred_idx = 2
confMat[true_idx,pred_idx] += 1
fig, ax = plt.subplots()
im = ax.imshow(confMat,cmap='rainbow')
# We want to show all ticks...
#ax.set_xticks(np.arange(len(classes)))
#ax.set_yticks(np.arange(len(classes)))
# ... and label them with the respective list entries
classes_tick = [' ','Still',' ','Walking',' ','Running',' ']
ax.set_xticklabels(classes_tick)
ax.set_yticklabels(classes_tick)
# Rotate the tick labels and set their alignment.
plt.setp(ax.get_xticklabels(), rotation=45, ha="right",
rotation_mode="anchor")
# Loop over data dimensions and create text annotations.
for i in range(len(classes)):
for j in range(len(classes)):
text = ax.text(j, i, confMat[i, j],
ha="center", va="center", color="k")
ax.set_title("Confusion matrix {}, \nrows - true activity, cols - predicted activity".format(person))
#fig.tight_layout()
fig.colorbar(im)
plt.show()
if __name__ == "__main__":
main()
\ No newline at end of file
......@@ -9,9 +9,8 @@ import numpy as np
def main():
person = sys.argv[1] # Frida, Matthias or Momina
data_type = sys.argv[2] # ACC or GYR
verbose = True if len(sys.argv) > 3 else False
data_path = '../Data_' + person + '/'
data_path = 'data/Data_' + person + '/'
data_paths = (glob.glob(data_path + '/*.txt'))
data_x = []
......@@ -34,12 +33,7 @@ def main():
data_z.append(float(l[4][:-1])) # don't include newline
nbr_measurements += 1
if verbose:
print("Mean value x: {:0.3f}".format(statistics.mean(data_x)))
print("Mean value y: {:0.3f}".format(statistics.mean(data_y)))
print("Mean value z: {:0.3f}".format(statistics.mean(data_z)))
all_nbr_measurements.append(nbr_measurements)
print("Mean of means for file {:s}: {:0.3f}".format(path, (statistics.mean(data_x) + statistics.mean(data_y) + statistics.mean(data_z)) / 3))
# Plot x, y, z, and the mean of those, together with delimeters for the different files
cumulative_all_nbr_measurements = np.cumsum(all_nbr_measurements)
......
......@@ -9,7 +9,7 @@ import numpy as np
def get_data(person, data_type):
freq = 100
data_path = '../Data_' + person + '/'
data_path = 'data/Data_' + person + '/'
data_paths = (glob.glob(data_path + '/*.txt'))
data_x = []
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment