Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/14.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
如何在matlab中使用allpassfilter去除声音中的噪声?_Matlab_Audio_Filter_Fft_Noise - Fatal编程技术网

如何在matlab中使用allpassfilter去除声音中的噪声?

如何在matlab中使用allpassfilter去除声音中的噪声?,matlab,audio,filter,fft,noise,Matlab,Audio,Filter,Fft,Noise,大家好,我有一个有噪音的声音。我想消除噪音。我怎样才能消除它 原声: 噪音: 首先我分析了信号 shiftedffty4=fftshift(ffty4); spectrumy41=abs(shiftedffty4); phaseffty41 = angle(shiftedffty4); N4=length(spectrumy41); t4=-Fs/2:Fs/N4:Fs/2-Fs/N4; spectrumy42=abs(fftshift(ffty4))/N4; phaseffty42=angle

大家好,我有一个有噪音的声音。我想消除噪音。我怎样才能消除它

原声:

噪音:

首先我分析了信号

shiftedffty4=fftshift(ffty4);
spectrumy41=abs(shiftedffty4);
phaseffty41 = angle(shiftedffty4);

N4=length(spectrumy41);
t4=-Fs/2:Fs/N4:Fs/2-Fs/N4;
spectrumy42=abs(fftshift(ffty4))/N4;
phaseffty42=angle(fftshift(ffty4));
然后对噪声进行fft,制作了一个具有相同频谱长度和乘积的全通滤波器,并进行逆fft,去除虚部,播放声音。声音仍然有噪音

allpassfilter=ones([N4,2]);
allpassfilter(spectrumy42>1e+06)=0;
filteredy4=allpassfilter.*ffty4;
filteredyeni4=ifft(filteredy4);
filteredyy4=real(filteredyeni4);
sound(filteredyy4,Fs);
但我无法去除噪声。问题是我不知道如何将allpassfilter中的噪声值(存在噪声的位置)设为零,如下所示:

allpassfilter(spectrumy42>1e+06)=0;

我怎么能做到!!!任何帮助都将不胜感激!!!!提前谢谢。

我下载了干净、嘈杂的音频文件。 首先,让我们分析一小部分音频

n=1024*8; % a small portion of data
w1=1e5;
w2=w1+n-1;

sig_noisy=data_n(w1:w2,1); % noisy audio
sig_clean=data_c(w1:w2,1); % clean audio

figure; hold all
plot(sig_noisy,'b')
plot(sig_clean,'r','LineWidth',2)
ylim([-1.5 1.5])
legend('Noisy','Clean')

如图所示,嘈杂的音频在某种程度上是饱和的 清除信号的截断版本。截断信号会引起谐波 频率更高。让我们看看功率谱 信号的密度

n=1024*1; % a smaller portion of data
w1=1e5;
w2=w1+n-1;

sig_noisy=data_n(w1:w2,1); % noisy 
sig_clean=data_c(w1:w2,1); % clean  

[psd_noisy, f] = pwelch(sig_noisy);
[psd_clean, ~] = pwelch(sig_clean);

figure; hold all
plot(f/pi,db(psd_noisy),'b')
plot(f/pi,db(psd_clean),'r')
xlabel('Normalized Freq.')
legend('Noisy','Clean')

你可以看到,嘈杂的音频在高频时有谐波和噪声。现在,如果你假设噪声的特性在音频的末尾没有改变,那么你可以设计一个滤波器来观察音频的这一小部分。既然已经有了噪声和干净的信号,为什么不使用反褶积方法呢

例如,如果将干净信号与嘈杂信号反褶积,则 获得系统的反向响应(h_inv),这也是可用于过滤噪声信号的滤波器系数

(sig_噪音=sig_清洁*h)

这里我使用维纳反褶积方法。还要注意的是,此函数并非仅用于图像,还可以使用Matlab中的1D信号反褶积方法

h_inv=deconvwnr(sig_clean,sig_noisy);

figure,plot(h_inv)
legend('h^-^1')

正如我所说,这是你需要的滤波器系数。例如,如果我使用h_inv过滤噪声信号:

sig_filtered=conv(sig_noisy,h_inv,'same');
[psd_filtered, ~] = pwelch(sig_filtered);

figure; hold all
plot(f/pi,db(psd_noisy),'b')
plot(f/pi,db(psd_clean),'r')
plot(f/pi,db(psd_filtered),'k')
xlabel('Normalized Freq.')
legend('Noisy','Clean','Filtered')

滤波后的信号频谱与干净的信号频谱非常接近。现在您已经有了滤波器系数,只需使用h_inv对整个嘈杂的音频进行滤波,然后收听结果

filtered_all=conv(data_n(:,1),h_inv,'same');
sound(filtered_all,48000)
您可以尝试其他反褶积方法并查看结果。您还可以在傅里叶域中对不需要的频谱进行归零,并对干净的信号进行逆傅里叶变换。但是,由于信号太长,您必须在滑动窗口中执行此操作。或者,您可以设计级联陷波滤波器来分别过滤每个谐波

我看到有四个斯特伦谐波。因此,为每个滤波器设计四个陷波滤波器,并设计一个低通滤波器来滤除高频噪声

% First notch
fc1=0.0001; bw1=0.05; N=4;
f = fdesign.notch('N,F0,BW',N,fc1,bw1); h = design(f);

% Second notch
fc2=0.21; bw2=0.2;
f = fdesign.notch('N,F0,BW',N,fc2,bw2); h2 = design(f);

% Third notch
fc3=0.41; bw3=0.2;
f = fdesign.notch('N,F0,BW',N,fc3,bw3); h3 = design(f);

% Fourth notch
fc4=0.58; bw4=0.2;
f = fdesign.notch('N,F0,BW',N,fc4,bw4); h4 = design(f);

% A Final lowpass filter
f = fdesign.lowpass('Fp,Fst,Ap,Ast',0.6,0.65,1,30);  h5 = design(f);

% Cascade the filters
hd = dfilt.cascade(h, h2, h3, h4, h5);

% See the filter characterisctic
ff=fvtool(hd,'Color','white');

% Now we can filter our 
sig_filtered2 = filter(hd,sig_noisy);
[psd_filtered2,f] = pwelch(sig_filtered2);

figure; hold all
plot(f/pi,db(psd_noisy),'b');
plot(f/pi,db(psd_clean),'r');
plot(f/pi,db(psd_filtered2),'k');
xlabel('Normalized Freq.')
legend('Noisy','Clean','Filtered')

现在,您可以过滤整个音频

filtered_all2 = filter(hd,data_n(:,1));
sound(filtered_all2,48000)

希望我能帮忙。

谢谢。是的,我有干净的声音和嘈杂的声音,但我将使用干净的声音进行检查,而不是清理嘈杂的声音。我们的建议是不使用任何matlab的内部滤波器。我们必须制作一个全通滤波器,使噪声部分为零,然后与噪声进行点积,以去除频域中的噪声。所以我只需要找到噪音的位置,这样我就可以做我问过的最后一个代码了。这是一个家庭作业,所以我需要用这种方式清理。然后你可以使用我建议的第二种方法(级联陷波滤波器)。如果你想用FFT,你可以用一小部分数据,因为信号本身太长了。
filtered_all2 = filter(hd,data_n(:,1));
sound(filtered_all2,48000)