环境:matlab 2020a
目录
目录
一、 预处理
1.1、语音读取
1.2、标签导入
1.3、降噪
1.4、带通滤波
1.5、特征提取
1.5.1 方差选取12000点
1.5.2 采样12000点:
1.6 完整代码
二、traindata_testdata划分
语音读取主要采用audioread函数
调用格式::
[y,Fs] = audioread(filename)
[y,Fs] = audioread(filename,samples)
其返回值中,
y :输出的音频数字信号,默认是n行2列,其中2的意思是,这个音频信号是两个声道的,n的值等于该音频信号的时长乘采样频率Fs。
Fs:信号采样频率;
filename:文件路径即文件名,例:'DATA/单音分类/3/3/A1.wav'
根据原始数据将数据的标签输入至excel表格label.xlsx中(按行存储,例如第一个数据标签为1,则在第一行第一列存入1;第二个数据标签为2,则在第二行第一列存入2....),对于需要标注多个原始数据集的标签可以放在不同的Sheet中。
[label]=xlsread('label/label.xlsx',2); % 读取excel中第二个Sheet内容
其中:
xlsread()中第一个参数是label.xlse所在路径,第二个参数是需要读取的sheet表格中的数据;
返回值labe即为表格中存入的标签信息。
这里使用MAD法对加性噪声进行滤除。MAD法是定义了一个阈值,这个阈值叫做中位数绝对偏差MAD。如果超过了3倍的MAD,则认为该数据离群。通过滑动窗口依次滤除噪声是。
ft_3 = filloutliers(ft,'linear','movmedian',3);%MAD法
其中:
filloutliers()中
填充方法 | 说明 |
---|---|
数值标量 | 使用指定的标量值进行填充 |
'center' |
使用由 findmethod 决定的中心值进行填充 |
'clip' |
对于比 findmethod 决定的下阈值还小的元素,用下阈值填充。对于比 findmethod 决定的上阈值还大的元素,用上阈值填充。 |
'previous' |
使用上一个非离群值进行填充 |
'next' |
使用下一个非离群值进行填充 |
'nearest' |
使用最接近的非离群值进行填充 |
'linear' |
使用相邻的非离群值的线性插值进行填充 |
'spline' |
使用分段三次样条插值进行填充 |
'pchip' |
使用保形分段三次样条插值进行填充 |
'makima' |
修正 Akima 三次 Hermite 插值(仅限数值、duration 和 datetime 数据类型) |
方法 | 说明 |
---|---|
'median' |
离群值定义为与中位数相差超过三倍换算 MAD 的元素。换算 MAD 定义为 c*median(abs(A-median(A))) ,其中 c=-1/(sqrt(2)*erfcinv(3/2)) 。 |
'mean' |
离群值定义为与均值相差超过三倍标准差的元素。此方法比 'median' 快,但没有它可靠。 |
'quartiles' |
离群值定义为比上四分位数 (75%) 大 1.5 个四分位差以上或比下四分位数 (25%) 小 1.5 个四分位差以上的元素。当 A 中的数据不是正态分布时,此方法很有用。 |
'grubbs' |
使用 Grubbs 检验检测离群值,并基于假设检验每次迭代删除一个离群值。此方法假设 A 中的数据呈正态分布。 |
'gesd' |
使用广义极端 Student 化偏差检验检测离群值。此迭代方法与 'grubbs' 类似,但当有多个离群值互相遮盖时,此方法的执行效果更好。 |
根据信号的中心频率,选择带通滤波器。这里采用matlab 自带滤波器设计进行滤波器设计。
% BPF 带通滤波器
fp1=250; %通带下限频率
fp2=500; %通带上限频率
ft_bpf=filter(BPF(fp1,fp2,fs),f1_25);
通过中心频率选择带通滤波器的上下限频率。
滤波器实现:
function Hd = BPF(f1,f2,fs)
%GETFILTER 返回离散时间滤波器对象。
% MATLAB Code
% Generated by MATLAB(R) 9.8 and DSP System Toolbox 9.10.
% Generated on: 10-Aug-2021 14:33:50
if (f1<50)
Fstop1=0;
else
Fstop1=f1-50;
end
%Fstop1 = 200; % First Stopband Frequency
Fpass1 = f1; % First Passband Frequency
Fpass2 = f2; % Second Passband Frequency
Fstop2 = f2+50; % Second Stopband Frequency
Astop1 = 60; % First Stopband Attenuation (dB)
Apass = 1; % Passband Ripple (dB)
Astop2 = 60; % Second Stopband Attenuation (dB)
Fs = fs; % Sampling Frequency 采样频率%%
h = fdesign.bandpass('fst1,fp1,fp2,fst2,ast1,ap,ast2', Fstop1, Fpass1, ...
Fpass2, Fstop2, Astop1, Apass, Astop2, Fs);
Hd = design(h, 'equiripple', ...
'MinOrder', 'any');
注意:若选择的通带太小可能导致滤波器阶数过高,增大计算量,需根据情况进行选择
y_var=movvar(ft_bpf(6001:(len(k)-5999),:),[6000 5999]);
y_var1=sum(y_var,2);
[val,b0(k)]=max(y_var1); %min
data(k,:)=ft_bpf((b0(k)):(b0(k)+11999),:)';
通过修改max,min选择方差最大最小片段。
ft_s=zeros(1,12000);
ft_s = resample(f1_25, 12000, len(k));
data(k,:)=ft_s;
这里采用多相滤波器对时间序列进行重采样,得到的序列y的长度为原来的序列x的长度的p/q倍,
p和q都为正整数。此时,默认地采用使用FIR方法设计的抗混叠的低通滤波器。
%% Audio
Path = 'DATA/单音分类/3/3/';% 数据集路径
datdir = dir([Path '*.wav']);
data=zeros(209,12000);
for k =1:length(datdir)
[y,fs] = audioread([datdir(k).folder '/' datdir(k).name]);
t = (0:length(y)-1)/fs; % 音频时长
len(k)=length(y);
ft = y(:,1); % 选择声道
%%
%MAD法
ft_3 = filloutliers(ft,'linear','movmedian',3);%MAD法
f1_25 = filloutliers(ft_3,'linear','movmedian',101);
%%
% BPF 带通滤波器
% fp1=120; %通带下限频率
% fp2=260; %通带上限频率
% ft_bpf=filter(BPF(fp1,fp2,fs),f1_25);
%% 方差选取12000点
y_var=movvar(f1_25(6001:(len(k)-5999),:),[6000 5999]);
y_var1=sum(y_var,2); %min
[val,b0(k)]=max(y_var1);
data(k,:)=f1_25((b0(k)):(b0(k)+11999),:)';
%% 采样
% ft_s=zeros(1,12000);
% ft_s = resample(f1_25, 12000, len(k));
% % 采用多相滤波器对时间序列进行重采样,得到的序列y的长度为原来的序列x的长度的p/q倍,
% % p和q都为正整数。此时,默认地采用使用FIR方法设计的抗混叠的低通滤波器。
% data(k,:)=ft_s;
clearvars -except data label k datdir
end
[label]=xlsread('label/label.xlsx',2); % 读取excel中第二个Sheet内容
%%
% 数据集划分
data=data;
label=label;
% 测试数据占全部数据的比例
testRatio = 0.2;
% 训练集索引
trainIndices = crossvalind('HoldOut', size(data, 1), testRatio);
% 测试集索引
testIndices = ~trainIndices;
% 训练集和训练标签
trainData = data(trainIndices, :);
trainLabel = label(trainIndices, :);
% 测试集和测试标签
testData = data(testIndices, :);
testLabel = label(testIndices, :);
% clearvars -except trainData testData trainLabel testLabel % 清除无关变量
在运行完预处理代码后,可以得到数据data和标签label,然后再运行上述代码进行数据集划分。