清除神经数据中的噪声 - MATLAB

信息处理 matlab 过滤器
2022-02-12 09:55:04

我正在使用 Matlab 处理神经生理学数据,我目前正在处理信号中的这种噪声:

噪音

特写

特写

编辑:

为了澄清,干净的信号应该是这样的:

在此处输入图像描述

编辑2:

干净的

干净的

噪音污染

噪音

这些光谱取自 10 秒的片段,因为整个块要大得多。两个光谱都来自包含第一和第三图中数据的段(有和没有数据的噪声位)。噪声事件在每个数据块内是稀疏的。

这在数据集中经常发生,因此,我在检测感兴趣的事件(即神经尖峰检测)时遇到了一些麻烦。当我试图检测信号中的小幅度尖峰时,尽可能多地保留原始信号至关重要。

关于如何更好地解决这个问题的任何建议?纠正信号中这些变化/尖峰的最佳方法是什么,尽可能多地保留信号?

任何建议/帮助将不胜感激!

干杯,米

2个回答

下面,一种去除 3 个指数脉冲的方法。

1.- 从提供的图表重建信号 + 干扰源

clear all;clc;close all

A=imread('001.jpg');
A1=A(:,:,1);
figure(1);imshow(A1)

A2=~imbinarize(A1);
figure(2);imshow(A2)
% 001

在此处输入图像描述

问题:bwmorph打破因果关系并分裂信号

A3=bwmorph(A2,'skel',Inf);
figure(3);imshow(A3);
% 002

在此处输入图像描述

[sz1 sz2]=size(A2)

for k=1:1:sz2
    L1=A2(:,k);
    n1=find(L1);

    A2(:,k)=zeros(1,sz1);
    if ~isempty(n1)
        A2(floor(mean(n1)),k)=1;
    end
end
figure(4);imshow(A2)
% 003

在此处输入图像描述

现在信号已正确映射。

由于问题发起者可以使用受污染的信号,因此应在此处插入原始数据:

s=0
for k=1:1:sz2
    L1=A2(:,k)
    s=[s find(L1)];
end
s(1)=[]

2.- 平均值在哪里?

不要只做 s=s-mean(s)

故意留下 y=0 轴刻度

在此处输入图像描述

% 004

mean_s=287

s=-(s-mean_s)

3.- 重建时间参考

t=linspace(0,10,sz2)
dt=mean(diff(t))

4.- 绘图信号+干扰

figure(5);plot(t,s);grid on
xlabel('t[seconds]');ylabel('s+i')  % signal+interferer

评论:

最初 5 秒内的 VLF 弯曲可能来自传导干扰;联系,在手机上应用心电图传感器?

基站或移动寻求答案,以一定的功率开始,然后随着数据包的交换基站移动终端告诉对方增加或减少功率,通常基站开始高于确保到达小区边缘所需的功率,然后降低电源直到 MS 说电平正常。

负尖峰表明可能有金属反射干扰信号。

您提供了一个参考信号,它应该是什么样的,但是没有时间参考,只有样本量,没有进一步的信息,不确定参考信号持续时间也是 10 秒,是吗?

[pks,locs]=findpeaks(s,'MinPeakHeight',50,'MinPeakDistance',50)
s_peaks=s(locs)

5.- 3 个指数衰减干扰脉冲何时开始?

t_peaks=t(locs)

6.- 时间测量的这 3 个脉冲之间的平均延迟是多少?

diff(t_peaks)

7.- 在数量样本中测量的这 3 个脉冲之间的平均延迟是多少?

diff(locs)

8.- 脉冲的实际幅度是多少?大约第一个样本

ds_peaks=s(locs)-s(locs-10)

9.- 每个干扰脉冲的样本量是多少?

nT1=floor(mean(diff(locs)))

10.- 3 个指数脉冲各自的衰减常数是多少?

a=-1./(dt*nT1)*log(1./ds_peaks)

11.- 直接在图表上测量的第一个干扰脉冲开始时间

t0=.688

12.- 第一个干扰脉冲的起始时刻的样本数是多少?

nt0=[1:1:floor(mean(intersect(find(t>t0-.01),find(t<t0+.01))))]

13.- 每个干扰脉冲的值:

e1=ds_peaks(1)*exp(-a(1)*dt*([1:1:nT1]+t0))
e2=ds_peaks(2)*exp(-a(2)*dt*([1:1:nT1]+t0))
e3=ds_peaks(3)*exp(-a(3)*dt*([1:1:nT1]+t0))
e_interf=[zeros(1,numel(nt0)) e1 e2 e3 zeros(1,sz2-3*nT1-numel(nt0))]
hold all
plot(t,e_interf)

在此处输入图像描述

s2=s-e_interf
figure(6);plot(t,s2);grid on
xlabel('t[seconds]');ylabel('s+i-3pulses')  % signal+interferrer

在此处输入图像描述

如果有兴趣,我可以展示如何使用findpeaks去除尖锐的负脉冲。

您可以通过使用高通滤波器来减少大的衰减偏差。您还可以使用低通滤波器减少强尖峰,从而组合形成带通滤波器。困难的部分是确定带通的低频和高频,并在一定程度上确定阻带衰减,同时判断什么是可接受的结果。

如果您添加了噪声破坏信号和无噪声信号的频谱,则可以提供更具体和更有帮助的建议。您的信号似乎可以改进,但需要更多细节来提出具体建议。

对编辑 2 的回应

有很多光谱重叠,因此改进程度将受到限制。我肯定会首先对 3 Hz 以上的所有内容进行高通滤波,以减少大的指数偏差。如果这产生了一些有希望的东西,你可以继续使用更硬的大幅尖峰。它们非常容易被检测到,因此您可以忽略它们或将这些间隔设为空白,但这可能不适合您的应用程序。

您也可以尝试在时域中使用软限制来减少大尖峰,然后对低于 49Hz 的结果进行低通滤波,或者首先尝试低通滤波器。