How to implement low pass filter using java

前端 未结 7 1838
野趣味
野趣味 2020-11-29 23:53

I am trying to implement a low pass filter in Java. My requirement is very simple,I have to eliminate signals beyond a particular frequency (Single dimension). Looks like Bu

相关标签:
7条回答
  • 2020-11-30 00:28

    Here is a lowpass filter that uses a fourier transform in the apache math library.

        public double[] fourierLowPassFilter(double[] data, double lowPass, double frequency){
        //data: input data, must be spaced equally in time.
        //lowPass: The cutoff frequency at which 
        //frequency: The frequency of the input data.
    
        //The apache Fft (Fast Fourier Transform) accepts arrays that are powers of 2.
        int minPowerOf2 = 1;
        while(minPowerOf2 < data.length)
            minPowerOf2 = 2 * minPowerOf2;
    
        //pad with zeros
        double[] padded = new double[minPowerOf2];
        for(int i = 0; i < data.length; i++)
            padded[i] = data[i];
    
    
        FastFourierTransformer transformer = new FastFourierTransformer(DftNormalization.STANDARD);
        Complex[] fourierTransform = transformer.transform(padded, TransformType.FORWARD);
    
        //build the frequency domain array
        double[] frequencyDomain = new double[fourierTransform.length];
        for(int i = 0; i < frequencyDomain.length; i++)
            frequencyDomain[i] = frequency * i / (double)fourierTransform.length;
    
        //build the classifier array, 2s are kept and 0s do not pass the filter
        double[] keepPoints = new double[frequencyDomain.length];
        keepPoints[0] = 1; 
        for(int i = 1; i < frequencyDomain.length; i++){
            if(frequencyDomain[i] < lowPass)
                keepPoints[i] = 2;
            else
                keepPoints[i] = 0;
        }
    
        //filter the fft
        for(int i = 0; i < fourierTransform.length; i++)
            fourierTransform[i] = fourierTransform[i].multiply((double)keepPoints[i]);
    
        //invert back to time domain
        Complex[] reverseFourier = transformer.transform(fourierTransform, TransformType.INVERSE);
    
        //get the real part of the reverse 
        double[] result = new double[data.length];
        for(int i = 0; i< result.length; i++){
            result[i] = reverseFourier[i].getReal();
        }
    
        return result;
    }
    
    0 讨论(0)
  • 2020-11-30 00:28

    I have designed a simple butterworth function recently (http://baumdevblog.blogspot.com/2010/11/butterworth-lowpass-filter-coefficients.html). They are easy to code in Java and should be fast enough if you ask me (you'd just have to change filter(double* samples, int count) to filter(double[] samples, int count), I guess).

    The problem with JNI is that it costs platform independence, may confuse the hotspot compiler and the JNI method calls within your code may still slow things down. So I would recommend trying Java and see if it is fast enough.

    In some cases it might be beneficial to use a fast fourier transform first and apply the filtering in the frequency domain but I doubt that this is faster than about 6 multiplies and a few additions per sample for a simple lowpass filter.

    0 讨论(0)
  • 2020-11-30 00:30

    Like Mark Peters said in his comment: A filter which needs to filter a lot should be written in C or C++. But you can still make use of Java. Just take a look at Java Native Interface (JNI). Because of C/C++ compiles to native machine code, it will run a lot faster than running your bytecode in the Java Virtual Machine (JVM), which is in fact a virtual processor that translates the bytecode to the local machine its native code (depending on CPU instruction set like x86, x64, ARM, ....)

    0 讨论(0)
  • 2020-11-30 00:37

    I have a page describing a very simple, very low-CPU low-pass filter that is also able to be framerate-independent. I use it for smoothing out user input and also for graphing frame rates often.

    http://phrogz.net/js/framerate-independent-low-pass-filter.html

    In short, in your update loop:

    // If you have a fixed frame rate
    smoothedValue += (newValue - smoothedValue) / smoothing
    
    // If you have a varying frame rate
    smoothedValue += timeSinceLastUpdate * (newValue - smoothedValue) / smoothing
    

    A smoothing value of 1 causes no smoothing to occur, while higher values increasingly smooth out the result.

    The page has a couple of functions written in JavaScript, but the formula is language agnostic.

    0 讨论(0)
  • 2020-11-30 00:38

    I understand this is an old question, but I'd like to add something that does not seem to have been mentioned before.

    The first thing you should realize is that:

    1. There are several different types of (digital) filters.
    2. There are several different ways to design filters.
    3. There are several different implementations of filters.

    When you need to use a filter in your application, you'll have to choose a certain type of filter, choose a specific design method for that kind of filter, apply that method to find the filter coefficients that satisfy your constraints and, finally, copy those coefficients to your filter implementation.

    Choosing the type of filter and applying the design method is something you do once, using an appropriate software, such as Matlab or Octave or Scilab. This may involve a bit of experimentation and observation of the obtained characteristics of the filter, such as the frequency response (both amplitude and phase) and/or the impulse response, to see if they match your specifications. Once you settle on the solution, you will have a set of constant coefficients. These numbers, or some linear combination of these numbers, is all you need to copy to your program (Java or otherwise) as a table of constants.

    Then, in your program, you just need a function that applies some filter implementation that uses these coefficients to do linear combinations of the input stream samples (and possibly previous output samples) to produce the new output sample in each time instant.

    I assume you will probably be interested in Linear Time-Invariant filters, either with finite impulse response (FIR) or infinite impulse response (IIR). The design methods differ between these two subclasses. Butterworth, Chebyshev, elliptic filters are merely the result of different techniques (or optimizations) for designing IIR filters. These can achieve very good frequency responses with a small order, meaning you need few coefficients and therefore a small number of multiplications/additions per sample in the implementation. But if you really want a linear-phase response, say, then you'll need FIR filters. These have different design techniques and generally require higher orders for similar frequency characteristics. There are efficient implementations using Fast Fourier Transforms, but I doubt you would need such a thing.

    The possible different filter implementations differ mainly in numerical stability. You probably won't notice the difference unless you're using very low precision arithmetic and/or quite exotic coefficients. I believe the Matlab/Octave filter function uses the "Direct-form II" implementation, which is quite simple. You'll find a description on DSP books or the web, I'm sure.

    João Manuel Rodrigues

    0 讨论(0)
  • 2020-11-30 00:45

    Filter design is an art of tradeoffs, and to do it well you need to take some details into account.

    What is the maximum frequency which must be passed "without much" attentuation, and what is the maximum value of "without much" ?

    What is the minimum frequency which must be attenuated "a lot" and what is the minimum value of "a lot" ?

    How much ripple (ie variation in attenuation) is acceptable within the frequencies the filter is supposed to pass?

    You have a wide range of choices, which will cost you a variety of amounts of computation. A program like matlab or scilab can help you compare the tradeoffs. You'll want to become familiar with concepts like expressing frequencies as a decimal fraction of a sample rate, and interchanging between linear and log (dB) measurements of attenuation.

    For example, a "perfect" low pass filter is rectangular in the frequency domain. Expressed in the time domain as an impulse response, that would be a sinc function (sin x/x) with the tails reaching to both positive and negative infinity. Obviously you can't calculate that, so the question becomes if you approximate the sinc function to a finite duration which you can calculate, how much does that degrade your filter?

    Alternately, if you want a finite impulse response filter that is very cheap to calculate, you can use a "box car" or rectangular filter where all the coefficients are 1. (This can be made even cheaper if you implement it as a CIC filter exploiting binary overflow to do 'circular' accumulators, since you'll be taking the derivative later anyway). But a filter that is rectangular in time looks like a sinc function in frequency - it has a sin x/x rolloff in the passband (often raised to some power since you would typically have a multi stage version), and some "bounce back" in the stop band. Still in some cases it's useful, either by itself or when followed up by another type of filter.

    0 讨论(0)
提交回复
热议问题