#预处理方式为使用动态MFCC并采用滑动窗口对2016心音挑战赛数据进行分割,使用过采样平衡数据
import os
import numpy as np
import librosa
from sklearn.preprocessing import MinMaxScaler
from scipy.signal import butter, filtfilt
from imblearn.over_sampling import KMeansSMOTE
from sklearn.cluster import KMeans
# 文件夹路径(更换成自己的)
input_folders = ['你自己的路径']
output_file = r'..\out_put\data.npy'
os.makedirs(os.path.dirname(output_file), exist_ok=True)
# 滑动窗口函数
def sliding_window(signal, window_size, step):
return [signal[i:i + window_size] for i in range(0, len(signal) - window_size + 1, step)]
# 巴特沃斯带通滤波器
def butter_bandpass(lowcut, highcut, fs, order=2):
nyquist = 0.5 * fs
low = lowcut / nyquist
high = highcut / nyquist
b, a = butter(order, [low, high], btype='band')
return b, a
def bandpass_filter(data, lowcut, highcut, fs, order=2):
b, a = butter_bandpass(lowcut, highcut, fs, order=order)
y = filtfilt(b, a, data)
return y
# 处理wav文件
def process_wav_file(file_path):
y, sr = librosa.load(file_path, sr=2000)
window_size = int(1.5 * sr) # 1.5秒
step_size = int(0.5 * sr) # 0.5秒的步长
windows = sliding_window(y, window_size, step_size)
processed_windows = []
for window in windows:
# 最小最大值归一化到[-1, 1]
scaler = MinMaxScaler(feature_range=(-1, 1))
window = scaler.fit_transform(window.reshape(-1, 1)).flatten()
# 二阶25-400Hz巴特沃斯带通滤波器
window = bandpass_filter(window, 25, 400, sr, order=2)
# 提取MFCC特征
mfcc = librosa.feature.mfcc(y=window, sr=sr, n_mfcc=13)
# 计算动态特征,使用较小的宽度参数
delta_mfcc = librosa.feature.delta(mfcc, width=3)
delta2_mfcc = librosa.feature.delta(mfcc, order=2, width=3)
# 合并静态和动态特征,因为我们使用了动态MFCC,比普通的MFCC多一个步骤
combined_mfcc = np.hstack((mfcc, delta_mfcc, delta2_mfcc))
processed_windows.append(combined_mfcc.flatten())
return processed_windows
# 聚合所有数据和标签
all_features = []
all_labels = []
for folder in input_folders:
label = 1 if 'abnormal' in folder else 0
for file_name in os.listdir(folder):
if file_name.endswith('.wav'):
file_path = os.path.join(folder, file_name)
features = process_wav_file(file_path)
all_features.extend(features)
all_labels.extend([label] * len(features))
# K-means SMOTE扩展训练集
features_array = np.array(all_features)
labels_array = np.array(all_labels)
# 调整KMeansSMOTE参数
kmeans_estimator = KMeans(n_clusters=10, random_state=42, n_init=10)
kmeans_smote = KMeansSMOTE(
sampling_strategy='auto',
k_neighbors=5,
random_state=42,
kmeans_estimator=kmeans_estimator,
cluster_balance_threshold=0.1
)
features_resampled, labels_resampled = kmeans_smote.fit_resample(features_array, labels_array)
# 保存为一个npy文件
data_resampled = {'features': features_resampled, 'labels': labels_resampled}
np.save(output_file, data_resampled)
print("数据处理完成并已保存为data.npy文件。")
# 加载并查看标签数量
data = np.load(output_file, allow_pickle=True).item()
features = data['features']
labels = data['labels']
# 统计每个标签的数量来观察过采样的标签平衡情况
unique, counts = np.unique(labels, return_counts=True)
label_distribution = dict(zip(unique, counts))
print("标签数量分布:", label_distribution)
提供一种医学信号处理中心音信号的预处理方式供参考,欢迎交流,一维信号并没有转换成二维图像而是转换成为了特征向量,大大的节省了计算资源消耗。