ref #6 peak detection implementiert, noch ohne prominence faktor von matlab. läuft aber gut
This commit is contained in:
@@ -3,6 +3,7 @@ import java.io.BufferedReader;
|
|||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileReader;
|
import java.io.FileReader;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.stream.IntStream;
|
import java.util.stream.IntStream;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -15,6 +16,9 @@ public class Main {
|
|||||||
File[] listOfFiles = folder.listFiles();
|
File[] listOfFiles = folder.listFiles();
|
||||||
Utils.ShowPNG windowRaw = new Utils.ShowPNG();
|
Utils.ShowPNG windowRaw = new Utils.ShowPNG();
|
||||||
Utils.ShowPNG windowAuto = new Utils.ShowPNG();
|
Utils.ShowPNG windowAuto = new Utils.ShowPNG();
|
||||||
|
Utils.ShowPNG windowPeaksX = new Utils.ShowPNG();
|
||||||
|
Utils.ShowPNG windowPeaksY = new Utils.ShowPNG();
|
||||||
|
Utils.ShowPNG windowPeaksZ = new Utils.ShowPNG();
|
||||||
|
|
||||||
// iterate trough files in measurements folder
|
// iterate trough files in measurements folder
|
||||||
for (File file : listOfFiles) {
|
for (File file : listOfFiles) {
|
||||||
@@ -78,10 +82,50 @@ public class Main {
|
|||||||
windowAuto.set(plotCorr.draw());
|
windowAuto.set(plotCorr.draw());
|
||||||
|
|
||||||
//find peaks
|
//find peaks
|
||||||
|
LinkedList<Integer> peaksX = Utils.findPeaks(xAutoCorr, 50, 0.1f, 0, false);
|
||||||
|
|
||||||
|
double[] dPeaksXX = IntStream.range(0, peaksX.size()).mapToDouble(i -> (peaksX.get(i) - 1024)).toArray();//peaks.stream().mapToDouble(i->i).toArray();
|
||||||
|
double[] dPeaksXY = IntStream.range(0, peaksX.size()).mapToDouble(i -> (dXAuto[peaksX.get(i)])).toArray();
|
||||||
|
Plot plotPeaksX = Plot.plot(Plot.plotOpts().
|
||||||
|
title("Peak Detection on X").
|
||||||
|
legend(Plot.LegendFormat.BOTTOM)).
|
||||||
|
series("x", Plot.data().xy(rangeAuto, dXAuto), Plot.seriesOpts().color(Color.RED)).
|
||||||
|
series("Peaks", Plot.data().xy(dPeaksXX, dPeaksXY), Plot.seriesOpts().color(Color.CYAN).
|
||||||
|
marker(Plot.Marker.DIAMOND).line(Plot.Line.NONE));
|
||||||
|
|
||||||
|
windowPeaksX.set(plotPeaksX.draw());
|
||||||
|
|
||||||
|
LinkedList<Integer> peaksY = Utils.findPeaks(yAutoCorr, 50, 0.1f, 0, false);
|
||||||
|
|
||||||
|
double[] dPeaksYX = IntStream.range(0, peaksY.size()).mapToDouble(i -> (peaksY.get(i) - 1024)).toArray();//peaks.stream().mapToDouble(i->i).toArray();
|
||||||
|
double[] dPeaksYY = IntStream.range(0, peaksY.size()).mapToDouble(i -> (dYAuto[peaksY.get(i)])).toArray();
|
||||||
|
Plot plotPeaksY = Plot.plot(Plot.plotOpts().
|
||||||
|
title("Peak Detection on Y").
|
||||||
|
legend(Plot.LegendFormat.BOTTOM)).
|
||||||
|
series("x", Plot.data().xy(rangeAuto, dYAuto), Plot.seriesOpts().color(Color.RED)).
|
||||||
|
series("Peaks", Plot.data().xy(dPeaksYX, dPeaksYY), Plot.seriesOpts().color(Color.CYAN).
|
||||||
|
marker(Plot.Marker.DIAMOND).line(Plot.Line.NONE));
|
||||||
|
|
||||||
|
windowPeaksY.set(plotPeaksY.draw());
|
||||||
|
|
||||||
|
LinkedList<Integer> peaksZ = Utils.findPeaks(zAutoCorr, 50, 0.1f, 0, false);
|
||||||
|
|
||||||
|
double[] dPeaksZX = IntStream.range(0, peaksZ.size()).mapToDouble(i -> (peaksZ.get(i) - 1024)).toArray();//peaks.stream().mapToDouble(i->i).toArray();
|
||||||
|
double[] dPeaksZY = IntStream.range(0, peaksZ.size()).mapToDouble(i -> (dZAuto[peaksZ.get(i)])).toArray();
|
||||||
|
Plot plotPeaksZ = Plot.plot(Plot.plotOpts().
|
||||||
|
title("Peak Detection on Z").
|
||||||
|
legend(Plot.LegendFormat.BOTTOM)).
|
||||||
|
series("x", Plot.data().xy(rangeAuto, dZAuto), Plot.seriesOpts().color(Color.RED)).
|
||||||
|
series("Peaks", Plot.data().xy(dPeaksZX, dPeaksZY), Plot.seriesOpts().color(Color.CYAN).
|
||||||
|
marker(Plot.Marker.DIAMOND).line(Plot.Line.NONE));
|
||||||
|
|
||||||
|
windowPeaksZ.set(plotPeaksZ.draw());
|
||||||
|
|
||||||
//fill hols improve peaks
|
//fill hols improve peaks
|
||||||
|
|
||||||
//estimate bpm between detected peaks
|
//estimate bpm between detected peaks
|
||||||
|
|
||||||
|
int dummyForBreakpoint = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import java.awt.*;
|
|||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
|
||||||
public class Utils {
|
public class Utils {
|
||||||
@@ -97,7 +98,6 @@ public class Utils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static float sqr(float x) {
|
public static float sqr(float x) {
|
||||||
return x * x;
|
return x * x;
|
||||||
}
|
}
|
||||||
@@ -180,8 +180,70 @@ public class Utils {
|
|||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: findPeaks
|
//TODO: findPeaks method identical to Matlab... with PeakProminence
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simple method for finding local maxima in an array
|
||||||
|
* @param data input
|
||||||
|
* @param width minimum distance between peaks
|
||||||
|
* @param threshold minimum value of peaks
|
||||||
|
* @param decayRate how quickly previous peaks are forgotten
|
||||||
|
* @param isRelative minimum value of peaks is relative to local average
|
||||||
|
* @return array of peaks
|
||||||
|
*/
|
||||||
|
public static LinkedList<Integer> findPeaks(float[] data, int width, float threshold, float decayRate, boolean isRelative) {
|
||||||
|
LinkedList<Integer> peaks = new LinkedList<>();
|
||||||
|
int maxp = 0;
|
||||||
|
int mid = 0;
|
||||||
|
int end = data.length;
|
||||||
|
float av = data[0];
|
||||||
|
while (mid < end) {
|
||||||
|
av = decayRate * av + (1 - decayRate) * data[mid];
|
||||||
|
if (av < data[mid])
|
||||||
|
av = data[mid];
|
||||||
|
int i = mid - width;
|
||||||
|
if (i < 0)
|
||||||
|
i = 0;
|
||||||
|
int stop = mid + width + 1;
|
||||||
|
if (stop > data.length)
|
||||||
|
stop = data.length;
|
||||||
|
maxp = i;
|
||||||
|
for (i++; i < stop; i++)
|
||||||
|
if (data[i] > data[maxp])
|
||||||
|
maxp = i;
|
||||||
|
if (maxp == mid) {
|
||||||
|
if (overThreshold(data, maxp, width, threshold, isRelative, av)){
|
||||||
|
peaks.add(new Integer(maxp));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mid++;
|
||||||
|
}
|
||||||
|
return peaks;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean overThreshold(float[] data, int index, int width,
|
||||||
|
float threshold, boolean isRelative,
|
||||||
|
float av) {
|
||||||
|
int pre = 3;
|
||||||
|
int post = 1;
|
||||||
|
|
||||||
|
if (data[index] < av)
|
||||||
|
return false;
|
||||||
|
if (isRelative) {
|
||||||
|
int iStart = index - pre * width;
|
||||||
|
if (iStart < 0)
|
||||||
|
iStart = 0;
|
||||||
|
int iStop = index + post * width;
|
||||||
|
if (iStop > data.length)
|
||||||
|
iStop = data.length;
|
||||||
|
float sum = 0;
|
||||||
|
int count = iStop - iStart;
|
||||||
|
while (iStart < iStop)
|
||||||
|
sum += data[iStart++];
|
||||||
|
return (data[index] > sum / count + threshold);
|
||||||
|
} else
|
||||||
|
return (data[index] > threshold);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
|
|||||||
Reference in New Issue
Block a user