消除噪音/尖峰

时间:2011-11-27 08:14:53

标签: matlab

我有一个具有相似正负值的测量数据,应该是这样的:

ReqData=[0 0 -2 -2 -2 -2 -2 -2 0 0 0 -2 -2 -2 -2 0 0 2 2 2 2 2 2 0 0 2 2 2 2 2 0 0 2 2 2 2 2 0 0 2 2 2 0 0]'

但是,数据中存在一些测量噪声 - 所以实际数据是这样的:

RealData=[0 0 -2 -2 -2 -2 -2 -2 0 0 0 -2 -2 -2 -2 0 0 2 2 2 2 -4 -1 0 0 2 2 2 2 -7 0 0 2 2 2 2 -1 0 0 2 2 2 0 0]'
  1. 如何从RealData中删除结束噪音并使用Matlab将其转换为ReqData
  2. 如何找到每组正面或负面数据的开始和停止索引并使用Matlab进行拆分?例如,ansPositive = [3,8, 12, 15]'ansNegative = [18, 23, 26, 30, 33, 37, 40, 42]'

3 个答案:

答案 0 :(得分:1)

当您向我邮寄另一个与您在此处发布的数据集完全不同的数据集时,我将解释另一种处理您数据的方法。

为完整起见,您可以在下图中找到数据集的详细信息:

New dataset

在左侧,您可以看到完整的数据集,右侧是详细信息。与之前的数据集相比,我们看到每个峰值都不是恒定的水平,我们也不需要像以前那样以最近邻的方式进行插值。

首先,我之前的答案在完整的数据集上非常缓慢(我的部分编码很糟糕),但它很可能会很糟糕,因为所有峰值可能都没有投射到正确的值(例如图像最多经常使用的值是4,4.1和0(其次是-4.05和其他))。这会导致我以前的算法失败。

为了避免这种情况,我们很容易选择两个阈值水平来构建预测器:大于正阈值的所有值都被视为常数正值,小于负阈值的所有阈值都被视为负常数,所有内容都在之间被认为是零。

通过选择合适的阈值,您可以获得相当强大的重建: Reconstructed signal

您可以看到绿色重建,而阈值显示为红色虚线。应该可以根据实际数据自动选择那些阈值;但是我把它留给你(看看我以前的代码,了解你如何解决这个问题)。

相应的源代码:

thresholdNeg = -3;
idxNeg   = RealData<thresholdNeg;
valueNeg = mean(RealData(idxNeg));

thresholdPos = 3;
idxPos   = RealData>thresholdPos;
valuePos = mean(RealData(idxPos));

reconData         = zeros(size(RealData));
reconData(idxPos) = valuePos;
reconData(idxNeg) = valueNeg;

n = numel(reconData);

plot(RealData,'b'); hold on;
plot(reconData,'-gx'); 
plot([1 n NaN n 1],[thresholdPos thresholdPos NaN thresholdNeg thresholdNeg], 'r--');

修改: 如果你想保留信号高低电平所含的任何信息(如果放大近似恒定的电平,你可以注意到另一个信号的存在),你可以使用逆阈值技术:保持信号到处但请将信号置于信号在阈值之间的0

答案 1 :(得分:0)

这取决于你的RealData有多嘈杂,这里有点令人困惑。例如,RealData(16)是负数,但ReqData(16)是正数,那么你想要的输出是什么?

我愿意:

 RealDataPos=double(RealData'>0);
 RealDataPosBeginning=find(conv(RealDataPos,[-1 1 0],'same')>0);
 RealDataPosEnd=find(conv(RealDataPos,[0 1 -1],'same')>0);

 RealDataNeg=double(RealData'<0);
 RealDataNegBeginning=find(conv(RealDataNeg,[-1 1 0],'same')>0);
 RealDataNegEnd=find(conv(RealDataNeg,[0 1 -1],'same')>0);

PS:注释你是否想要一些更复杂的东西来处理reaData中正序的en变为负的事实。

答案 2 :(得分:0)

您可以使用类似以下代码的内容来重建数据。

首先会确定最频繁发生的振幅。它假设3个最频繁的幅度是正确的幅度,你可以总是施加稍微不同的约束(例如,检查它们中的两个是否具有相同的绝对值并且总是包括)。

然后它找到信号具有不同幅度的采样点,并将其校正到信号的先前幅度。

clc; clear all; close all;

ReqData=[0 0 -2 -2 -2 -2 -2 -2 0 0 0 -2 -2 -2 -2 0 0 2 2 2 2 2 2 0 0 2 2 2 2 2 0 0 2 2 2 2 2 0 0 2 2 2 0 0]';
RealData=[0 0 -2 -2 -2 -2 -2 -2 0 0 0 -2 -2 -2 -2 0 0 2 2 2 2 -4 -1 0 0 2 2 2 2 -7 0 0 2 2 2 2 -1 0 0 2 2 2 0 0]';

ReconData = RealData;

amplitudes = unique(RealData);
histogram = hist(RealData,amplitudes);
[histogram, sorted] = sort(histogram);
amplitudes = amplitudes(sorted);

allowedValues = amplitudes(end-2:end);
%allowedValues = [-1 0 1] * 2;

spikes = find(arrayfun(@(x) (~ismember(x,allowedValues)),RealData));
for iSpike = 1:numel(spikes)
    jSpike = spikes(iSpike);
    ReconData(jSpike) = ReconData(jSpike-1);
end

plot(ReqData,'-or'); hold on;
plot(RealData,'b');
plot(ReconData,'-gx');