0

So I am trying to filter peaks from an FFT-processed signal in the given frequency domain. The processed signal is for example:

enter image description here

Using a simple mean filter algorithm, modifying from takanuva15's code, I managed to write a function to detect the peaks as follows:

public static int[] peakDetection(float[] data, float threshold) {

        // init stats instance
        SummaryStatistics stats = new SummaryStatistics();

        // the results (peaks, 1 or -1) of our algorithm
        int[] peaks = new int[data.length];

        // init average and standard deviation
        for (float datum : data) {
            stats.addValue(datum);
        }
        float avg = (float) stats.getMean(); // get average
        float std = (float) Math.sqrt(stats.getPopulationVariance()); // getStandardDeviation() uses sample variance
        stats.clear();

        // loop input
        for (int i = 0; i < data.length; i++) {

            if (Math.abs(data[i] - avg) > threshold * std) { // determine peaks

                if (data[i] > avg) {
                    peaks[i] = 1;
                } else {
                    peaks[i] = -1;
                }

            } else {
                // ensure this signal remains a zero
                peaks[i] = 0;
            }
        }

        return peaks;

    }

However the result seems not good enough with the given input threshold: 1:

enter image description here

As the noise peak from the first part of the frequency is detected, it seems I am missing something in the algorithm. How could I filter this problem?

Zukaru
  • 309
  • 2
  • 10
  • Best chance of getting a proper answer would probably be at https://dsp.stackexchange.com/ . My semi-educated guess is that you either first run the results through a high-pass filter, or maybe there is a way to make a low end threshold that is a % of the nearest peak rather than the same through the entire spectrum. – Phil Freihofner Nov 03 '21 at 23:08

0 Answers0