心音信号(PCG)预处理转换为特征向量不使用二维图像

#预处理方式为使用动态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)

 提供一种医学信号处理中心音信号的预处理方式供参考,欢迎交流,一维信号并没有转换成二维图像而是转换成为了特征向量,大大的节省了计算资源消耗。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值