2

我有一个波形,其中包含从射频收发器获得的相移信息。它不是规则的波形,而是如下图所示的不均匀波形。我已经使用油漆说明了信封,我该如何在 MATLAB 中做到这一点? 在此处输入图像描述

我还附上了waveform.csv。在我的 MATLAB 代码中,我已经使用了平均滤波器来平滑原始信号。

波形 csv 文件

信封.m

clc; clear all; close all;

%% Extract data from .csv
file = '150825_px6_human_rotcw_0to60cm_Ch1.csv';
data = csvread(file, 0, 3);

%% Shift time
shift = data(1,1);
for i = 1:length(data)
    t(i) = data(i,1) - shift;
end

%% Low pass filter
filterlen = 500;
y = myfilter(data(:,2), filterlen);

%% Plot
figure;
plot(data(:,1), data(:,2));
title('Raw signal');

figure;
plot(t(1:end-filterlen+1), y);
title('After low pass filter');

myfilter.m(简单平均滤波器)

function y = myfilter(x,a) 
    for i = 1:(length(x)-(a-1))
        y(i) = sum(x(i:(i+a-1)))/a;
    end
    y = y';
end
4

2 回答 2

4

一个简单的包络检波器可以很容易地按照二极管检波器的想法来实现,使用:

envelope = data(1,2);
for  i = 2:length(data)
    if (abs(data(i,2)) > envelope)
        envelope = abs(data(i,2));
    else
        envelope  = envelope * decayfactor;
        data(i,2) = envelope;
    end
end

应该选择具有比不均匀信号变化长得多的decayfactor衰减时间常数,但小于预期信号包络带宽的倒数。您可能需要进行一些实验,但诸如decayfactor=exp(-fmax/fs)fmax您的包络带宽在哪里,以及fs采样频率在哪里)应该是一个很好的起始值。

这通常会跟随一个低通滤波器(例如myfilter您提供的)。

作为基于提供的数据的示例执行,使用decayfactor=exp(-5/5000)具有 300 个样本窗口的平均滤波器产生以下图(原始数据为蓝色,包络为红色):

包络图

于 2015-08-26T13:42:38.163 回答
0

阅读下面的代码。这应该会根据需要得到信封。它的简单代码任何人都可以编写类似的类而不是使用这个实现(它的 GPL 代码),我发布了这个代码以供参考/解释。

/*
*      _______                       _____   _____ _____  
*     |__   __|                     |  __ \ / ____|  __ \ 
*        | | __ _ _ __ ___  ___  ___| |  | | (___ | |__) |
*        | |/ _` | '__/ __|/ _ \/ __| |  | |\___ \|  ___/ 
*        | | (_| | |  \__ \ (_) \__ \ |__| |____) | |     
*        |_|\__,_|_|  |___/\___/|___/_____/|_____/|_|     
*                                                         
* -------------------------------------------------------------
*
* TarsosDSP is developed by Joren Six at IPEM, University Ghent
*  
* -------------------------------------------------------------
*
*  Info: http://0110.be/tag/TarsosDSP
*  Github: https://github.com/JorenSix/TarsosDSP
*  Releases: http://0110.be/releases/TarsosDSP/
*  
*  TarsosDSP includes modified source code by various authors,
*  for credits and info, see README.
* 
*/


package be.tarsos.dsp;

/**
 * An envelope follower follows the envelope of a signal. Sometimes the name
 * envelope detector is used. From wikipedia:
 *  <blockquote> An envelope detector
 * is an electronic circuit that takes a high-frequency signal as input and
 * provides an output which is the envelope of the original signal. The
 * capacitor in the circuit stores up charge on the rising edge, and releases it
 * slowly through the resistor when the signal falls. The diode in series
 * rectifies the incoming signal, allowing current flow only when the positive
 * input terminal is at a higher potential than the negative input terminal.
 * </blockquote>
 * 
 * The resulting envelope is stored in the buffer in the processed AudioEvent. The class can be used thusly:
 * 
 * <pre>
 * EnvelopeFollower follower = new EnvelopeFollower(44100);
 *      
 * AudioDispatcher dispatcher = AudioDispatcher.fromFloatArray(sine, 44100, 1024, 0);
 *  
 *  
 *  dispatcher.addAudioProcessor(follower);
 *  dispatcher.addAudioProcessor(new AudioProcessor() {
 *  
 *      public boolean process(AudioEvent audioEvent) {
 *          //envelope
 *          float buffer[] = audioEvent.getFloatBuffer();
 *          for(int i = 0 ; i < buffer.length ; i++){
 *              System.out.println(buffer[i]);
 *          }
 *          return true;
 *      }
 *          
 *      public void processingFinished() {
 *      }
 *  });
 *  dispatcher.run();
 *  </pre>
 *  
 * 
 * @author Joren Six
 * 
 */
public class EnvelopeFollower implements AudioProcessor {

    /**
     * Defines how fast the envelope raises, defined in seconds.
     */
    private static final double DEFAULT_ATTACK_TIME =  0.0002;//in seconds
    /**
     * Defines how fast the envelope goes down, defined in seconds.
     */
    private static final double DEFAULT_RELEASE_TIME =  0.0004;//in seconds

    float gainAttack ;
    float gainRelease;
    float envelopeOut = 0.0f;

    /**
     * Create a new envelope follower, with a certain sample rate.
     * @param sampleRate The sample rate of the audio signal.
     */
    public EnvelopeFollower(double sampleRate){
        this(sampleRate,DEFAULT_ATTACK_TIME,DEFAULT_RELEASE_TIME);
    }

    /**
     * Create a new envelope follower, with a certain sample rate.
     * @param sampleRate The sample rate of the audio signal.
     * @param attackTime Defines how fast the envelope raises, defined in seconds.
     * @param releaseTime Defines how fast the envelope goes down, defined in seconds.
     */
    public EnvelopeFollower(double sampleRate, double attackTime,double releaseTime){
        gainAttack = (float) Math.exp(-1.0/(sampleRate*attackTime));
        gainRelease = (float) Math.exp(-1.0/(sampleRate*releaseTime));
    }

    @Override
    public boolean process(AudioEvent audioEvent) {
        float[] buffer = audioEvent.getFloatBuffer();
        calculateEnvelope(buffer);
        return true;
    }

    public void calculateEnvelope(float[] buffer){
        for(int i = 0 ; i < buffer.length ; i++){
            float envelopeIn = Math.abs(buffer[i]);
            if(envelopeOut < envelopeIn){
                envelopeOut = envelopeIn + gainAttack * (envelopeOut - envelopeIn);
            } else {
                envelopeOut = envelopeIn + gainRelease * (envelopeOut - envelopeIn);
            }
            buffer[i] = envelopeOut;
        }
    }

    @Override
    public void processingFinished() {

    }
}
于 2018-12-23T08:56:35.167 回答