added classification, results are bad...
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
display("functions")
|
||||
source("settings.m");
|
||||
|
||||
|
||||
function files = getDataFiles(clsName, trainsetPerClass)
|
||||
|
||||
setDataDir = "/home/toni/Documents/handygames/HandyGames/daten/";
|
||||
|
||||
global setDataDir;
|
||||
|
||||
dir = strcat(setDataDir, clsName, "/");
|
||||
lst = readdir(dir);
|
||||
@@ -36,13 +38,16 @@ function samples = getSamplesForClass(clsName, trainsetPerClass, start, percent)
|
||||
display(strcat("training data for '", clsName, "': ", num2str(length(samples)), " samples"));
|
||||
end
|
||||
|
||||
function data = getRawTrainData(trainsetPerClass)
|
||||
function data = getRawTrainData()
|
||||
|
||||
#global trainsetPerClass;
|
||||
|
||||
data = {};
|
||||
data{1}.samples = getSamplesForClass("forwardbend", trainsetPerClass, 10, 0.9);
|
||||
data{2}.samples = getSamplesForClass("kneebend", trainsetPerClass, 10, 0.9);
|
||||
data{3}.samples = getSamplesForClass("pushups", trainsetPerClass, 10, 0.9);
|
||||
data{4}.samples = getSamplesForClass("situps", trainsetPerClass, 10, 0.9);
|
||||
data{5}.samples = getSamplesForClass("jumpingjack", trainsetPerClass, 10, 0.9);
|
||||
data{1}.samples = getSamplesForClass("forwardbend", 9, 10, 0.95);
|
||||
data{2}.samples = getSamplesForClass("kneebend", 11, 10, 0.95);
|
||||
data{3}.samples = getSamplesForClass("pushups", 11, 10, 0.95);
|
||||
data{4}.samples = getSamplesForClass("situps", 8, 10, 0.95);
|
||||
data{5}.samples = getSamplesForClass("jumpingjack", 13, 10, 0.95);
|
||||
end
|
||||
|
||||
function plotData(data,outPath)
|
||||
@@ -75,17 +80,15 @@ function filteredData = filterData(data)
|
||||
end
|
||||
|
||||
function win = window(rawVec, posMS)
|
||||
|
||||
global setWindowSize;
|
||||
pos = posMS / 10;
|
||||
#check if out of bounce, if yes- fill with zeros
|
||||
#the last windows are sometimes filled with a lot of zeros... this could cause problems
|
||||
if length(rawVec) <= pos+100-1
|
||||
#win = rawVec(pos-100:length(rawVec),:);
|
||||
#fillOut = zeros((pos+100-1) - length(rawVec), 3);
|
||||
#length(fillOut)
|
||||
#win = [win; fillOut];
|
||||
|
||||
#only full windows are accepted.
|
||||
if length(rawVec) <= pos+(setWindowSize/2)-1
|
||||
win = [];
|
||||
else
|
||||
win = rawVec(pos-100:pos+100-1,:); #100*10 ms is half the window size. that is 2s for each window.
|
||||
win = rawVec(pos-(setWindowSize/2):pos+(setWindowSize/2)-1,:); #100*10 ms is half the window size.
|
||||
endif
|
||||
end
|
||||
|
||||
@@ -100,14 +103,24 @@ function out = getMagnitude(data)
|
||||
end
|
||||
|
||||
function windowedData = windowData(data)
|
||||
windowedData = {};
|
||||
|
||||
global setWindowSize;
|
||||
global setWindowSliding;
|
||||
windowedData = {};
|
||||
|
||||
for k = 1:numel(data)
|
||||
for j = 1:numel(data{k}.samples)
|
||||
|
||||
winsAccel = {};
|
||||
winsGyro = {};
|
||||
winsMagnet = {};
|
||||
#init
|
||||
winsAccelX = {};
|
||||
winsAccelY = {};
|
||||
winsAccelZ = {};
|
||||
winsGyroX = {};
|
||||
winsGyroY = {};
|
||||
winsGyroZ = {};
|
||||
winsMagnetX = {};
|
||||
winsMagnetY = {};
|
||||
winsMagnetZ = {};
|
||||
|
||||
winsAccelPCA = {};
|
||||
winsGyroPCA = {};
|
||||
@@ -118,12 +131,15 @@ windowedData = {};
|
||||
winsMagnetMG = {};
|
||||
|
||||
winEnd = length(data{k}.samples{j}.raw{1}) * 10; # *10ms
|
||||
winBuffer = ((setWindowSize/2)+1) * 10;
|
||||
|
||||
for i = 1010:200:winEnd-1010 #200ms steps for sliding/overlapping windows
|
||||
for i = winBuffer:setWindowSliding:winEnd-winBuffer #steps for sliding/overlapping windows
|
||||
|
||||
#accel
|
||||
winAccel = window(data{k}.samples{j}.raw{1}, i);
|
||||
winsAccel = [winsAccel winAccel];
|
||||
winsAccelX = [winsAccelX winAccel(:,1)];
|
||||
winsAccelY = [winsAccelY winAccel(:,2)];
|
||||
winsAccelZ = [winsAccelZ winAccel(:,3)];
|
||||
|
||||
[coeff1, score1] = princomp(winAccel);
|
||||
winsAccelPCA = [winsAccelPCA score1(:,1)]; #choose the first axis (eigvec with the biggest eigvalue)
|
||||
@@ -133,7 +149,9 @@ windowedData = {};
|
||||
|
||||
#gyro
|
||||
winGyro = window(data{k}.samples{j}.raw{2}, i);
|
||||
winsGyro = [winsGyro winGyro];
|
||||
winsGyroX = [winsGyroX winGyro(:,1)];
|
||||
winsGyroY = [winsGyroY winGyro(:,2)];
|
||||
winsGyroZ = [winsGyroZ winGyro(:,3)];
|
||||
|
||||
[coeff2, score2] = princomp(winGyro);
|
||||
winsGyroPCA = [winsGyroPCA score2(:,1)];
|
||||
@@ -143,7 +161,9 @@ windowedData = {};
|
||||
|
||||
#magnet
|
||||
winMagnet = window(data{k}.samples{j}.raw{3}, i);
|
||||
winsMagnet = [winsMagnet winMagnet];
|
||||
winsMagnetX = [winsMagnetX winMagnet(:,1)];
|
||||
winsMagnetY = [winsMagnetY winMagnet(:,2)];
|
||||
winsMagnetZ = [winsMagnetZ winMagnet(:,3)];
|
||||
|
||||
[coeff3, score3] = princomp(winMagnet);
|
||||
winsMagnetPCA = [winsMagnetPCA score3(:,1)];
|
||||
@@ -154,53 +174,68 @@ windowedData = {};
|
||||
end
|
||||
|
||||
#write back data
|
||||
windowedData{k}.samples{j}.raw{1}.wins = winsAccel;
|
||||
windowedData{k}.samples{j}.raw{2}.wins = winsGyro;
|
||||
windowedData{k}.samples{j}.raw{3}.wins = winsMagnet;
|
||||
windowedData{k}.samples{j}.raw{4}.wins = winsAccelPCA;
|
||||
windowedData{k}.samples{j}.raw{5}.wins = winsGyroPCA;
|
||||
windowedData{k}.samples{j}.raw{6}.wins = winsMagnetPCA;
|
||||
windowedData{k}.samples{j}.raw{7}.wins = winsAccelMG;
|
||||
windowedData{k}.samples{j}.raw{8}.wins = winsGyroMG;
|
||||
windowedData{k}.samples{j}.raw{9}.wins = winsMagnetMG;
|
||||
windowedData{k}.samples{j}.raw{1}.wins = winsAccelX; #X
|
||||
windowedData{k}.samples{j}.raw{2}.wins = winsAccelY; #Y
|
||||
windowedData{k}.samples{j}.raw{3}.wins = winsAccelZ; #Z
|
||||
windowedData{k}.samples{j}.raw{4}.wins = winsGyroX;
|
||||
windowedData{k}.samples{j}.raw{5}.wins = winsGyroY;
|
||||
windowedData{k}.samples{j}.raw{6}.wins = winsGyroZ;
|
||||
windowedData{k}.samples{j}.raw{7}.wins = winsMagnetX;
|
||||
windowedData{k}.samples{j}.raw{8}.wins = winsMagnetY;
|
||||
windowedData{k}.samples{j}.raw{9}.wins = winsMagnetZ;
|
||||
windowedData{k}.samples{j}.raw{10}.wins = winsAccelPCA;
|
||||
windowedData{k}.samples{j}.raw{11}.wins = winsGyroPCA;
|
||||
windowedData{k}.samples{j}.raw{12}.wins = winsMagnetPCA;
|
||||
windowedData{k}.samples{j}.raw{13}.wins = winsAccelMG;
|
||||
windowedData{k}.samples{j}.raw{14}.wins = winsGyroMG;
|
||||
windowedData{k}.samples{j}.raw{15}.wins = winsMagnetMG;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function features = featureCalculation(data)
|
||||
|
||||
features = [];
|
||||
global setAutocorrelationBinSize;
|
||||
global setPSDBinSize;
|
||||
features = [];
|
||||
|
||||
for k = 1:numel(data)
|
||||
for j = 1:numel(data{k}.samples)
|
||||
for i = 1:numel(data{k}.samples{j}.raw)
|
||||
for m = 1:numel(data{k}.samples{j}.raw{i}.wins)
|
||||
currentWindow = data{k}.samples{j}.raw{i}.wins{m};
|
||||
currentWindow = currentWindow(:,1);
|
||||
|
||||
#autocorrelation on window. split into 5 evenly spaced bins (frequencies are evenly spaced, not number of values ;) ) and calculate mean of bin.
|
||||
[autoCorr] = xcorr(currentWindow);
|
||||
[binNum, binCenter] = hist(autoCorr, 5); #define 5 bins for the data.
|
||||
[binNum, binCenter] = hist(autoCorr, setAutocorrelationBinSize); #define bins for the data.
|
||||
binSize = abs(binCenter(end-1) - binCenter(end));
|
||||
binEdges = linspace(binCenter(1)-(binSize/2), binCenter(end)+(binSize/2), 6);
|
||||
binEdges = linspace(binCenter(1)-(binSize/2), binCenter(end)+(binSize/2), setAutocorrelationBinSize+1);
|
||||
[binNumc, binIdx] = histc(autoCorr, binEdges);
|
||||
binMeans = getBinMean(autoCorr, binIdx, 5);
|
||||
binMeans = getBinMean(autoCorr, binIdx, setAutocorrelationBinSize);
|
||||
|
||||
#calculate the root-mean-square (RMS) of the signal
|
||||
rms = sqrt(mean(currentWindow.^2));
|
||||
|
||||
#power bands 0.5 to 25hz (useful if the windows are greater then 4s and window sizes to 256, 512..)
|
||||
[powerBand, w] = periodogram(currentWindow); #fills up fft with zeros
|
||||
powerEdges = logspace(log10(0.5), log10(25), 10 + 2); #logarithmic bin spaces for 10 bins
|
||||
powerEdges = logspace(log10(0.5), log10(25), setPSDBinSize + 2); #logarithmic bin spaces for 10 bins
|
||||
triFilter = getTriangularFunction(powerEdges, length(powerBand)*2 - 2);
|
||||
for l = 1:numel(triFilter)
|
||||
filteredBand = triFilter{l} .* powerBand;
|
||||
psd(l) = sum(filteredBand); #sum freq (no log and no dct)
|
||||
end
|
||||
|
||||
#statistical features
|
||||
windowMean = mean(currentWindow);
|
||||
windowSTD = std(currentWindow); #standard deviation
|
||||
windowVariance = var(currentWindow);
|
||||
windowKurtosis = kurtosis(currentWindow); #(ger. Wölbung)
|
||||
windowIQR = iqr(currentWindow); #interquartile range
|
||||
|
||||
#put everything together
|
||||
classLabel = k; #what class?
|
||||
features = [features; classLabel, binMeans, rms, psd];
|
||||
sampleLabel = j; #what sample?
|
||||
features = [features; sampleLabel, classLabel, binMeans, rms, psd, windowMean, windowSTD, windowVariance, windowKurtosis, windowIQR];
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -209,29 +244,34 @@ end
|
||||
|
||||
function value = getBinMean(data, idx, numBins)
|
||||
|
||||
#search for an idx == numBins+1. this index occurs if a value == lastEdge, thanks histc...
|
||||
isSix = find(idx == numBins+1);
|
||||
if isSix != 0
|
||||
idx(isSix) = numBins;
|
||||
endif
|
||||
|
||||
value = [];
|
||||
value = [];
|
||||
for i = 1:numBins
|
||||
flagBinMembers = (idx == i);
|
||||
binMembers = data(flagBinMembers);
|
||||
|
||||
# if length(binMembers) == 0
|
||||
# idx
|
||||
#data
|
||||
# input = 'balala'
|
||||
#endif
|
||||
|
||||
value(i) = mean(binMembers);
|
||||
if length(binMembers) == 0
|
||||
value(i) = 0;
|
||||
else
|
||||
value(i) = mean(binMembers);
|
||||
endif
|
||||
end
|
||||
end
|
||||
|
||||
#triangular functions. (edges of the triangles; num fft values -> nfft.)
|
||||
function triFilter = getTriangularFunction(edges, nfft)
|
||||
|
||||
global samplerateHZ;
|
||||
|
||||
#get idx of the edges within the samples. thanks to fft each sample represents a frequency.
|
||||
# idx * samplerate / nfft = hertz of that idx
|
||||
for i = 1:length(edges)
|
||||
edgesByIdx(i) = floor((nfft + 1) * edges(i)/100); #100hz is the samplerate
|
||||
edgesByIdx(i) = floor((nfft + 1) * edges(i)/samplerateHZ);
|
||||
end
|
||||
|
||||
#generate the triangle filters
|
||||
|
||||
Reference in New Issue
Block a user