Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
信号处理(Java语言)_Java_Algorithm_Signals - Fatal编程技术网

信号处理(Java语言)

信号处理(Java语言),java,algorithm,signals,Java,Algorithm,Signals,我有一个传感器,我正在阅读,目前的代码是Java,但我不认为这个问题是语言特定的,更多的方法相关 传感器产生的信号有高脉冲和低脉冲,大致类似于心跳。然而,“高”脉冲并不总是相同的电平,“低”脉冲也不总是相同的电平。我感兴趣的是相对差异。但是,仅此一点还不够,因为在单个“会话”中,高值和低值也可能发生变化(想想弯曲的中点) 我包括了一张我希望能够处理的4种“类型”信号的图片。左上角是“理想的”,我相当肯定我已经可以处理了,其他三个更常见,更不容易处理 我目前的方法是寻找数据的平均值,看看有多少次穿

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

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

我包括了一张我希望能够处理的4种“类型”信号的图片。左上角是“理想的”,我相当肯定我已经可以处理了,其他三个更常见,更不容易处理

我目前的方法是寻找数据的平均值,看看有多少次穿过该点,这将告诉我有多少个高脉冲和低脉冲

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


找到改变方向的点。用微积分的术语来说,这是二阶导数

基本上你是在寻找一个点,
sign(f(x)-f(x-1))
sign(f(x+1)-f(x))


根据您的数据采集,有几种方法可以做到这一点。如果您添加了一些关于您的具体问题的更多信息,我将编辑答案以提供更多帮助。

看起来,您只需要高频率即可。当你说你想提取波的频率时,我首先想到的是傅里叶变换;这将信号从时域转换为频域。给定以下采样波:

这是一种正弦方式,我添加了噪音和趋势。基本正弦波的频率为1.5Hz

你可以得到这个傅里叶变换

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

Java代码 Apachi commons有一个快速傅立叶变换类,我用它来创建这个变换。它将波形的采样数据作为输入,并输出一个复数,复数的模数(实部平方的平方根加上虚部平方)为。输出数组中的每个条目
i
都引用
i*采样频率/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 

        };
}
import org.apache.commons.math3.complex.complex;
导入org.apache.commons.math3.transform.dft规范化;
导入org.apache.commons.math3.transform.FastFourierTransformer;
导入org.apache.commons.math3.transform.TransformType;
公开等级考试{
公共静态void main(字符串[]args){
double samplingFrequency=10;//hz,您将从数据中知道这一点,需要在此处进行设置
double[]frequencyDomain=新的double[input.length];
FastFourier变压器=新的FastFourier变压器(DFT.STANDARD);
试试{
复数[]复数=transformer.transform(输入,TransformType.FORWARD);
对于(inti=0;i对于(int i=0;i,根据我对问题的理解,这里需要的是峰值相对于相邻波谷的高度。我创建了一个库,可以使用我称之为尖峰检测的方法处理此类情况。该库被称为尖峰检测,并提供一个称为尖峰检测的实用程序

可以找到峰值检测的演示,可以做的是识别相对于相邻波谷的峰值高度,然后使用特定值进行过滤


橙色交叉代表检测到的峰值。

我认为您需要某种类型的平均方法,但不一定要对整个信号进行平均。您可能可以使用boxcar滤波器。因此,您是否希望立即获得峰值和波谷之间的平均差(反之亦然)或者你想知道波的频率?这是我需要的波的频率。如果信号不对称,这仍然有效吗?即,向上的坡度比向下的坡度更陡,或者反之亦然?是的,你所做的只是找到拐点。请注意,此方法假设你沿着曲线获得数据点,而不是高点、低点、高点模式。仅仅改变方向是不够的(由于信号上的噪音)我最终寻找了一个实质性的方向变化,结果证明这是相对准确的。看来我需要知道波的频率来使用它。是的,但你可以从一个低截止频率开始,然后增加它,直到只有非常高的频率通过。这很有趣,我现在没有时间去做我的回答可以深入到任何深度,但我看到的一些东西可能会引起问题:如果波的频率小于1,会发生什么?有可能区分真实结果和“非常低频的结果”吗?@ZackNewsham傅里叶的优点是