信号处理(Java)

Zac*_*ham 4 java algorithm signals

我有一个传感器,我正在阅读,目前代码是Java,但我不认为这个问题是语言特定的,更多的方法相关.

传感器产生具有高脉冲和低脉冲的信号,大致类似于心跳.然而,"高"脉冲并不总是相同的水平,也不是"低".我感兴趣的是相对差异.然而,仅凭这一点还不够,因为在单个"会话"中,高值和低值也可能会发生变化(想想弯曲的中点)

我已经包含了我希望能够处理的4种"信号"类型的图像.左上角是"理想的"我相当肯定我已经可以处理它,其他三个可悲的是更常见,不太容易处理.

我目前的方法是寻找数据的平均值,并查看该点的交叉次数,这将告诉我有多少高低脉冲.

我想知道是否有一种简单的方法来检测高低脉冲,而不使用平均方法.

在此输入图像描述

Ric*_*gle 9

当你说你想要提取波的频率时,我想到的第一件事是傅立叶变换; 这将信号从时域转换到频域.鉴于以下样本波:

在此输入图像描述

这是我添加噪音和趋势的正弦方式.基础正弦波的频率为1.5Hz

你得到这个傅里叶变换

在此输入图像描述

在这里你可以看到0hz的大响应,这是线性趋势,在这种情况下我们可以忽略它.之后,您可以在1.5Hz处看到响应中的一个峰值,即输入信号的频率.换一种说法; 一旦你进行了傅立叶变换,你的结果就是具有最大值的数据点(删除极低频率结果后)

Java代码

Apachi commons有一个快速傅立叶变换类,我用它来创建这个变换.它将波的采样数据作为输入并输出一个复数,复数的模数(实部平方的平方根加上虚部平方)等于该频率的能量.i输出数组中的每个条目都指向频率at i*samplingFrequency/noOfSamples.

但是,下面的Java代码会为您处理这些问题.快速傅立叶变换的唯一问题是输入条目的数量必须是2的幂.

import org.apache.commons.math3.complex.Complex;
import org.apache.commons.math3.transform.DftNormalization;
import org.apache.commons.math3.transform.FastFourierTransformer;
import org.apache.commons.math3.transform.TransformType;

public class FourierTest {

    public static void main(String[] args) {

        double samplingFrequency=10; //hz, You will know this from your data and need to set it here



        double[] frequencyDomain = new double[input.length];

        FastFourierTransformer transformer = new FastFourierTransformer(DftNormalization.STANDARD);
        try {           
            Complex[] complex = transformer.transform(input, TransformType.FORWARD);

            for (int i = 0; i < complex.length; i++) {               
                double real = (complex[i].getReal());
                double imaginary = (complex[i].getImaginary());

                frequencyDomain[i] = Math.sqrt((real * real) + (imaginary * imaginary));
            }

        } catch (IllegalArgumentException e) {
            System.out.println(e);
        }

        //only to frequencyDomain.length/2 since second half is mirror image or first half
        for(int i=0;i<frequencyDomain.length/2;i++){
            double frequency=samplingFrequency*i/frequencyDomain.length;
            System.out.println("Frequency: " + frequency + "\t\tEnergyComponent: " + frequencyDomain[i]);
        }
    }

    static double[]  input = new double[]{
            0.017077407 , //sample at 0 seconds
            1.611895528 , //sample at 0.1 seconds
            2.063967663 , //sample at 0.2 seconds
            1.598492541 , //etc
            0.184678933 ,
            0.02654732  ,
            0.165869218 ,
            1.026139745 ,
            1.914179294 ,
            2.523684208 ,
            1.71795312  ,
            0.932131202 ,
            1.097366772 ,
            1.107912105 ,
            2.843777623 ,
            2.503608192 ,
            2.540595787 ,
            2.048111122 ,
            1.515498608 ,
            1.828077941 ,
            2.400006658 ,
            3.562953532 ,
            3.34333491  ,
            2.620231348 ,
            2.769874641 ,
            2.423059324 ,
            2.11147835  ,
            3.473525478 ,
            4.504105599 ,
            4.325642774 ,
            3.963498242 ,
            2.842688545 ,
            2.573038184 ,
            3.434226007 ,
            4.924115479 ,
            4.876122332 ,
            4.553580015 ,
            3.92554604  ,
            3.804585546 ,
            3.476610932 ,
            4.535171252 ,
            5.398007229 ,
            5.729933758 ,
            5.573444511 ,
            4.487695977 ,
            4.133046459 ,
            4.796637209 ,
            5.091399617 ,
            6.420441446 ,
            6.473462022 ,
            5.663322311 ,
            4.866446009 ,
            4.840966187 ,
            5.329697081 ,
            6.746910181 ,
            6.580067494 ,
            7.140083322 ,
            6.243532245 ,
            4.960520462 ,
            5.100901901 ,
            6.794495306 ,
            6.959324497 ,
            7.194674358 ,
            7.035874424 

        };
}
Run Code Online (Sandbox Code Playgroud)