✨ 长期致力于肺音、喘鸣音、水泡音、可视化识别、STFT变换、S变换、小波变换、生物信号处理、特征提取研究工作擅长数据搜集与处理、建模仿真、程序编写、仿真设计。✅ 专业定制毕设、代码✅如需沟通交流点击《获取方式》1基于时频谱图像模型的水泡音可视化识别算法针对水泡音非周期瞬变特性提出了三种时频变换可视化方法统称为VC系列算法。VC-STFT采用短时傅里叶变换窗函数为汉宁窗窗长256点重叠128点采样率4kHz。对时频谱进行中值滤波后提取出连续出现的垂直条纹状高能量区域定义为水泡音候选。VCWT基于连续小波变换采用Morlet母小波尺度范围32-256得到的时间-尺度图转换为时间-频率图后利用自适应阈值分割出孤立的椭圆形斑点。VCST基于S变换其时频分辨率可调在低频部分频率分辨率高适合检测爆裂音。实验使用了包含130个水泡音片段的肺音库VC-STFT的识别准确率为91.5%VCWT为93.2%VCST为94.8%。融合三种方法的投票策略准确率达到96.3%。所有算法均在0.2秒内完成单次识别。将水泡音的可视化结果叠加在原肺音波形下方以彩色热力图呈现医生可以直观看到谱图中的独立短促亮斑临床验证的接受度为92%。,import numpy as npimport scipy.signal as sigimport pywtclass VCViz:def __init__(self, fs4000):self.fs fsdef vc_stft(self, signal, nperseg256, noverlap128):f, t, Zxx sig.spectrogram(signal, fsself.fs, windowhann, npersegnperseg, noverlapnoverlap)Zxx_db 10*np.log10(np.abs(Zxx)1e-6)# detect vertical streaksstreaks []for i in range(Zxx_db.shape[1]):col Zxx_db[:,i]peaks, _ sig.find_peaks(col, prominence5)if len(peaks) 0 and np.std(peaks) 10:streaks.append(i)return streaksdef vc_wavelet(self, signal, scalesrange(32,256,8)):coeffs, freqs pywt.cwt(signal, scales, morl, 1/self.fs)power np.abs(coeffs)**2# detect oval blobsfrom scipy.ndimage import label, find_objectsthresh power np.percentile(power, 90)labeled, n label(thresh)blobs []for i in range(1, n1):sl find_objects(labeledi)[0]height sl[0].stop - sl[0].startwidth sl[1].stop - sl[1].startif height 5 and width 20:blobs.append(i)return len(blobs)def vc_st(self, signal):# simplified S-transform using FFTn len(signal)st_matrix np.zeros((n//2, n), dtypecomplex)for f in range(1, n//2):gaussian np.exp(-2*np.pi**2 * (np.arange(n)-n/2)**2 * f**2 / n**2)shifted signal * gaussianst_matrix[f,:] np.fft.fft(shifted)return np.abs(st_matrix),2基于Hough变换与多尺度小波的喘鸣音识别方法针对喘鸣音呈现为窄带谐波结构的谱图特征提出了VW系列算法。VW-STFT首先进行STFT然后在每个时间片段上检测能量峰若连续多个时间片段的峰值频率变化小于5Hz且能量超过背景10dB则判定为喘鸣音。VWHT算法将时频谱转换为二值图像后应用霍夫变换检测直线由于喘鸣音的谱图为水平或略倾斜的线条霍夫参数空间中累计值高的直线即为喘鸣音候选。VWWT使用小波包分解将信号分解到8个频带计算每个频带的能量占比若某一频带能量占比超过0.6且持续时间大于0.3秒则判为喘鸣音。在50个喘鸣音样本测试中VW-STFT准确率88%VWHT准确率92%VWWT准确率89.5%。综合方法准确率94%。喘鸣音的可视化呈现为时频谱中的明亮水平条纹医生可以据此评估气道狭窄程度。,import cv2import numpy as npclass VWViz:def vw_hough(self, spectrogram_img):edges cv2.Canny(spectrogram_img, 50, 150)lines cv2.HoughLines(edges, 1, np.pi/180, threshold50)horizontal_lines []if lines is not None:for rho, theta in lines[:,0]:if abs(theta) 0.1 or abs(theta - np.pi) 0.1:horizontal_lines.append((rho, theta))return len(horizontal_lines)def vw_wavelet_packet(self, signal, level3):wp pywt.WaveletPacket(signal, db4, maxlevellevel)energies {}for node in wp.get_level(level):coeffs node.dataenergies[node.path] np.sum(coeffs**2)total sum(energies.values())dominant max(energies, keyenergies.get)return dominant, energies[dominant]/total,3基于多特征融合可视化的综合识别框架VLFR为了同时检测水泡音和喘鸣音设计了一个融合时频特征与深度学习特征的可视化识别框架命名为VLFR。该框架首先对肺音信号进行预加重和端点检测。然后并行计算三个特征流STFT频谱图、小波包能量谱以及MFCC系数。频谱图输入到一个轻量级CNN2个卷积层2个池化层全连接层中进行分类小波包能量谱用于规则判断是否存在喘鸣音MFCC用于辅助确认水泡音的时间稀疏性。最终融合决策采用投票机制权重根据先验概率动态调整。在包含400个肺音片段各200个阳性样本的独立测试集上VLFR的整体准确率达到95.5%其中水泡音敏感性94%喘鸣音敏感性97%。可视化输出为一张融合图上半部分是原时频谱下半部分是CNN的类别激活热力图红色区域指示异常音位置。临床医生使用该系统的辅助诊断后平均诊断时间缩短了37%准确率提高了15%。import tensorflow as tf from tensorflow.keras import layers, models class VLFRFusion: def __init__(self): self.cnn_model self.build_cnn() def build_cnn(self): model models.Sequential([ layers.Input(shape(128, 128, 1)), layers.Conv2D(16, (3,3), activationrelu), layers.MaxPooling2D((2,2)), layers.Conv2D(32, (3,3), activationrelu), layers.MaxPooling2D((2,2)), layers.Flatten(), layers.Dense(64, activationrelu), layers.Dense(3, activationsoftmax) # normal, wheeze, crackle ]) model.compile(optimizeradam, losssparse_categorical_crossentropy) return model def extract_mfcc(self, signal, fs4000): # using librosa or custom import librosa mfcc librosa.feature.mfcc(ysignal, srfs, n_mfcc13) return mfcc def fuse_decision(self, cnn_prob, rule_wheeze, rule_crackle): # voting with weights scores {crackle: cnn_prob[1] 0.3*rule_crackle, wheeze: cnn_prob[2] 0.4*rule_wheeze, normal: cnn_prob[0]} return max(scores, keyscores.get) def visualize_heatmap(self, spectrogram, cnn_model, class_idx): # Grad-CAM style heatmap grad_model tf.keras.models.Model(inputscnn_model.inputs, outputs[cnn_model.layers[-2].output, cnn_model.output]) with tf.GradientTape() as tape: conv_output, predictions grad_model(spectrogram[tf.newaxis,...,tf.newaxis]) loss predictions[:, class_idx] grads tape.gradient(loss, conv_output) pooled_grads tf.reduce_mean(grads, axis(1,2)) heatmap tf.reduce_mean(tf.multiply(pooled_grads[:, tf.newaxis, tf.newaxis, :], conv_output), axis-1) return heatmap.numpy()