MATLAB环境下一种音频降噪优化方法—基于时频正则化重叠群收缩

语音增强是语音信号处理领域中的一个重大分支,这一分支已经得到国内外学者的广泛研究。当今时代,随着近六十年来的不断发展,己经产生了许多有效的语音增强算法。根据语音增强过程中是否利用语音和噪声的先验信息,语音增强算法一般被归类为两类, 一类是无先验信息的语音增强算法,另外一类则是具有先验信息的语音增强算法。在第一类无先验信息语音增强算法中,比较常用的语音增强算法有谱减算法、基于统计模型的算法、基于信号子空间的算法、维纳滤波算法之类。这些算法对于平稳噪声具有很好的增强效果,但是对于特征很快变化的非平稳噪声,降噪性能经常无法满足需求。与上面的无先验信息语音增强算法相比,有先验信息语音增强算法能够弥补上述的缺点,能够有效的处理于非平稳噪声,达到合适的效果。有先验信息语音增强算法主要有隐马尔科夫模型语音增强算法以及码数驱动的语音增强算法。有先验信息语音增强算法能够通过线下提取语音和噪声的先验信息,然后利用HMM或者码数分别对获取的语音和噪声先验信息进行建模,结合线上语音和噪声的先验HMM 或者码数估计的语音谱和噪声谱,并构建维纳滤波器增强声音中的语音部分。由于利用到了语音和噪声的先验信息,这类算法能够很好地追踪线上语音和噪声特征的变化,实现对非平稳噪声很好的降噪效果。语音增强的主要目包含两个方面:1. 降低含噪语音中的噪音;2 尽量保留甚至增强原语音的质量。

提出一种基于时频正则化重叠群收缩的音频降噪优化方法,该方法使用可分解凸优化问题的预定结构知识对语音信号进行降噪,利用语音谱图观察聚类特性,使用混合范数惩罚项迭代地获得稀疏干净的语音信号。并在重叠群收缩算法基础上,在代价函数中引入时频权值。

% Reading in our audio files
[clean_signal, clean_speech_rate] = audioread("data/speech_files/sp01.wav");
[noise_signal, noise_signal_rate] = audioread("data/noise_files/keyboard_noise.wav");
noise_signal = noise_signal'; clean_signal = clean_signal';% Ensuring noise signal length matches clean signl length through reptition and cropping
noise_signal = noise_signal(mod(0:length(clean_signal)-1, numel(noise_signal)) + 1);
assert(length(clean_signal) == length(noise_signal));% Combining to create noisy signal
SNR = -10; % in dB
noisy_signal = clean_signal + (noise_signal / norm(noise_signal) * norm(clean_signal) / 10.0^(0.05*SNR));
% Uncomment the following line following line for using gaussian noise
%noisy_signal = awgn(clean_signal, SNR, "measured");% Setting this changes what we take the STFT of
yo = noisy_signal;% Some parameters for our test
noise_type = "impulsive"; % Noise types are impulsive, clean, stationary, used for weighting
lambda = 30; % Higher values when using both T & F weightings
Nit = 6;
K1 = 2;
K2 = 8;
window = sqrt(hann(256, 'periodic')); 
overlap_length = 128;
fft_length = 512;%% Preprocess Data
% Take STFT
% ensure to use both a cola compliant window and overlap length and k needs to
% be an int in this eq. k = (length(yo) - overlap_length) / (length(window) - overlap_length)
% otherwise we can pad signal to make k an integer and remove padded 0's
% from our output
if (~iscola(window, overlap_length))error("COLA noncompliant parameters, imperfect reconstruction");
end
k = (length(yo) - overlap_length) / (length(window) - overlap_length);
if (k ~= floor(k))warning("Padding signal to provide sample reconstruction post istft, results may be off for groups that stretch across to these padded zeros");padding = ceil(k) * overlap_length + overlap_length - length(noisy_signal);yo = [yo zeros(1, padding)];
elsepadding = 0;
end
tf = stft(yo, noise_signal_rate, 'Window', window, 'OverlapLength', overlap_length, 'FFTLength', fft_length);%% Creating our frequency weighting 
% For noise with varying energy across the bands
if noise_type == "clean" || noise_type == "impulsive" || noise_type == "stationary"[N, Fo, Ao, W] = firpmord([4000, 6000]/(noise_signal_rate/2), [1 0.8], [0.01, 0.01]);b = firpm(10, Fo, Ao, W);[filter_magnitudes, ~] = freqz(b, 1, size(tf, 1));filter_magnitudes = abs(filter_magnitudes);
elseif noise_type == "stationary"filter_magnitudes = ones(fft_length, 1);
end
frequency_weighting = repmat(filter_magnitudes, [1, size(tf, 2)]);%% Denoising Signal
% Running algorithm
[tf_denoised, cost, weights, energy_ratios] = tfs(tf, K1, K2, lambda, Nit, frequency_weighting);
denoised_signal = real(istft(tf_denoised, noise_signal_rate, 'Window', window, 'OverlapLength', overlap_length, 'FFTLength', fft_length)');% Undoing the padding if any was necessary
if (padding ~= 0)yo = yo(1:length(yo)-padding);denoised_signal = denoised_signal(1:length(denoised_signal)-padding);
end%% Plots, SNR Readout & Playing Denoised Signal
time = (1:length(denoised_signal))/noise_signal_rate;
figure(1)
clf;
subplot(3,3,1);
hold on;
plot(time, denoised_signal, 'Color', [1, 0, 0, 0.2]);
plot(time, clean_signal, 'Color', [0, 1, 0, 0.05]);
axis tight;
hold off;
title("Clean vs Denoised Signal");
legend("Denoised Signal", "Clean Signal");subplot(3,3,2);
plot(time, clean_signal - denoised_signal, 'Color', [1, 0, 0, 1]);
axis tight;
title("Delta of Clean vs Denoised");subplot(3,3,3);
hold on;
plot(time, denoised_signal, 'Color', [1, 0, 0, 0.2]);
plot(time, noisy_signal, 'Color', [0, 1, 0, 0.05]);
axis tight;
hold off;
title("Noisy vs Denoised Signal");
legend("Denoised Signal", "Noisy Signal");subplot(3,3,4);
plot(cost)
title("Cost Per Iteration");
legend("Cost");subplot(3, 3, 5);
mesh(mag2db(weights));
c = colorbar;
c.Label.String = "Power/Frequency db/Hz";
shading interp;
view(0, 90);
xlim([0 size(weights, 2)])
ylim([0 size(weights, 1)])
title ("Time & Frequency Attenutation Weighting");subplot(3, 3, 6);
spectrogram(clean_signal, window, overlap_length, fft_length, noise_signal_rate, 'yaxis');
title("Spectrogram of Clean Signal");subplot(3, 3, 7);
spectrogram(noisy_signal, window, overlap_length, fft_length, noise_signal_rate, 'yaxis');
title("Spectrogram of Noisy Signal");subplot(3, 3, 8);
spectrogram(denoised_signal, window, overlap_length, fft_length, noise_signal_rate, 'yaxis');
title("Spectrogram of Denoised Signal");subplot(3, 3, 9);
spectrogram(clean_signal - denoised_signal, window, overlap_length, fft_length, noise_signal_rate, 'yaxis');
title("Spectrogram of Delta Between Clean & Denoised Signal");if noise_type ~= "stationary"figure(2)freqz(b, 1, size(tf, 1));
endfigure(3)
subplot(2, 1, 1);
plot((1:fft_length).*(noise_signal_rate/2)/fft_length, smooth(filter_magnitudes));
xlabel("Frequency Hz");
ylabel("Weight");
title("Frequency Weights")subplot(2, 1, 2);
plot(energy_ratios);
axis tight;
xlabel("Time");
ylabel("Weight");
title("Time Weights")% Get the SNR and play the denoised signal
if (sum(clean_signal(:).^2) == 0) || (sum((clean_signal(:)-yo(:)).^2) == 0)preSNR = 0;
elsepreSNR = 10*log10(sum(clean_signal(:).^2) / (sum((clean_signal(:)-yo(:)).^2)));
endif (sum(clean_signal(:).^2) == 0) || (sum((clean_signal(:)-denoised_signal(:)).^2) == 0)postSNR = 0;
elsepostSNR = 10*log10(sum(clean_signal(:).^2) / (sum((clean_signal(:)-denoised_signal(:)).^2)));
end
fprintf("SNR Pre-Denoising: %.2f SNR Post-Denoising: %.2f dB\n", preSNR, postSNR);
sound(denoised_signal, noise_signal_rate);

工学博士,担任《Mechanical System and Signal Processing》审稿专家,担任《中国电机工程学报》优秀审稿专家,《控制与决策》,《系统工程与电子技术》,《电力系统保护与控制》,《宇航学报》等EI期刊审稿专家,担任《计算机科学》,《电子器件》 , 《现代制造过程》 ,《电源学报》,《船舶工程》 ,《轴承》 ,《工矿自动化》 ,《重庆理工大学学报》 ,《噪声与振动控制》 ,《机械传动》 ,《机械强度》 ,《机械科学与技术》 ,《机床与液压》,《声学技术》,《应用声学》,《石油机械》,《西安工业大学学报》等中文核心审稿专家。

擅长领域:现代信号处理,机器学习,深度学习,数字孪生,时间序列分析,设备缺陷检测、设备异常检测、设备智能故障诊断与健康管理PHM等。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/653767.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于springboot游戏分享网站源码和论文

网络的广泛应用给生活带来了十分的便利。所以把游戏分享管理与现在网络相结合,利用java技术建设游戏分享网站,实现游戏分享的信息化。则对于进一步提高游戏分享管理发展,丰富游戏分享管理经验能起到不少的促进作用。 游戏分享网站能够通过互…

快手社招一面算法原题

快手面试 最近收到一位读者的留言,是跟我吐槽「快手社招面试」的。 但是由于交谈内容太多东西需要脱敏,我打完马赛克之后,发现上下文都不连贯了。 遂罢。 但一转念,我想如果这真的是这个公司的普遍性问题,而非独立个例…

【极数系列】Flink环境搭建Linux版本 (03)

文章目录 引言01 Linux部署JDK11版本1.下载Linux版本的JDK112.创建目录3.上传并解压4.配置环境变量5.刷新环境变量6.检查jdk安装是否成功 02 Linux部署Flink1.18.0版本1.下载Flink1.18.0版本包2.上传压缩包到服务器3.修改flink-config.yaml配置4.启动服务5.浏览器访问6.停止服务…

verdaccio搭建npm私服

一、安装verdaccio 注:加上–unsafe-perm的原因是防止报grywarn权限的错 npm install -g verdaccio --unsafe-perm 二、启动verdaccio verdaccio 三、配置文件 找到config.yml一般情况下都在用户下的这个文件夹下面 注:首次启动后才会生成 C:\Users\h…

Idea上操作Git回退本地版本,怎么样保留已修改的文件,回退本地版本的四种方式代表什么?

Git的基本概念:Git是一个版本控制系统,用于管理代码的变更历史记录。核心概念包括仓库、分支、提交和合并。 1、可以帮助开发者合并开发的代码 2、如果出现冲突代码的合并,会提示后提交合并代码的开发者,让其解决冲突 3、代码文件版本管理 问题描述 当我们使用git提交代码…

深入了解低代码开发:多角度分类

引言 随着数字化时代的到来,应用程序的需求不断增长,企业和开发者们面临着更多的挑战,包括开发周期的压力、技术复杂性的增加以及对高效协作的需求。在这一背景下,低代码开发应运而生,成为解决这些挑战的一种强大工具…

算法基础课-数据结构

单链表 题目链接:826. 单链表 - AcWing题库 思路:AcWing 826. 单链表---图解 - AcWing 需要注意的点在于理解ne[idx] head,idx表示当前的点,意思是将当前的点链到头结点的后面,再将头结点链在当前idx的前面。 #inc…

JVM系列——垃圾收集器

对象存活判断 引用计数法 在对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加一;当引用失效时,计数器值就减一;任何时刻计数器为零的对象就是不可能再被使用的。 可达性分析算法 通过一系列称为“GC …

基于springboot+微信小程序+vue实现的校园二手商城项目源码

介绍 校园二手商城,架构:springboot微信小程序vue 软件架构 软件架构说明 系统截图 技术选型 技术版本说明Spring Boot2.1.6MVC核心框架Spring Security oauth22.1.5认证和授权框架MyBatis3.5.0ORM框架MyBatisPlus3.1.0基于mybatis,使用…

蓝桥杯备战——8.DS1302时钟芯片

1.分析原理图 由上图可以看到,芯片的时钟引脚SCK接到了P17,数据输出输入引脚IO接到P23,复位引脚RST接到P13。 2.查阅DS1302芯片手册 具体细节还需自行翻阅手册,我只截出重点部分 总结:数据在上升沿写出,下降沿读入,…

QGIS使用地理配准将3857坐标系转成上海城建坐标

控制点格式 如 mapX mapY sourceX sourceY enable dX dY residual -58653 70641 13452659.39 3746386.025 1 0 0 0 -58653 65641 13452693.09 3740477.283 1 0 0 0 ......保存为.points格式 图层预处理 图层投影为3857坐标系 地理配准 1. 打开图层-地理配准 工具 2. 导入…

基于FX构建大型Golang应用

Uber开源的FX可以帮助Go应用解耦依赖,实现更好的代码复用。原文: How to build large Golang applications using FX 构建复杂的Go应用程序可能会引入很多耦合 Golang是一种流行编程语言,功能强大,但人们还是会发现在处理依赖关系的同时组织大…

sql注入第一关

判断注入点的类型 通常 Sql 注入漏洞分为 2 种类型: 数字型字符型 数字型测试 在参数后面加上单引号,比如: http://xxx/abc.php?id1 如果页面返回错误,则存在 Sql 注入。 原因是无论字符型还是整型都会因为单引号个数不匹配而报错。 如果未报错&…

Go语言中的HTTP代理处理机制

在当今的互联网世界,HTTP代理是一种常见的网络通信方式,用于保护用户的隐私、突破网络限制或提高网络访问速度。在Go语言中,代理处理机制的实现可以为开发者提供强大的网络通信能力。本文将深入探讨Go语言中的HTTP代理处理机制。 首先&#…

每日一道面试题:Java中序列化与反序列化

写在开头 哈喽大家好,在高铁上码字的感觉是真不爽啊,小桌板又拥挤,旁边的小朋友也比较的吵闹,影响思绪,但这丝毫不影响咱学习的劲头!哈哈哈,在这喧哗的车厢中,思考着这样的一个问题…

PrimeFaces修改默认加载动画

Background 默认加载动画不够醒目&#xff0c;我们可以在网上下载个好看的gif图&#xff0c;然后修改默认设置&#xff0c;具体步骤如下参考官方地址&#xff1a;https://www.primefaces.org/showcase/ui/ajax/status.xhtml 实现效果如下 xhtml源码 <p:ajaxStatus onstar…

【人工智能】八数码问题的A*搜索算法实现

一、实验要求 熟悉和掌握启发式搜索的定义、估价函数和算法过程&#xff0c;并利用A*算法求解八数码问题&#xff0c;理解求解流程和搜索顺序 二、实验原理 定义h*(n)为状态n到目的状态的最优路径的代价&#xff0c;则当A搜索算法的启发函数h(n)小于等于h* (n)&#xff0c;即满…

使用毫米波雷达传感器的功能安全兼容系统设计指南2(TI文档)

2.3 步骤3&#xff1a;平台选择 平台选择是设计生命周期中最关键的步骤之一。一旦从第二步完成了一个成熟的系统框图&#xff0c;重要的任务就是根据性能需求选择系统模块/子系统。TI广泛的毫米波雷达传感器产品组合可以帮助实现许多性能要求&#xff0c;如远程或中程、角度分辨…

GoogLeNet模型详解

模型介绍 GoogLeNet是谷歌工程师设计的深度神经网络结构&#xff0c;于2014年在ImageNet比赛中取得了冠军。它的设计特点在于既有深度&#xff0c;又在横向上拥有“宽度”&#xff0c;并采用了一种名为Inception的核心子网络结构。这个网络名字中的“GoogLeNet”是对LeNet的致…

Layui + Echarts 5.0

Layui 怎么整合最新版本的 Echarts 5.0&#xff0c;Echarts 4 升级到 5后&#xff0c;有了很大改变&#xff0c;新的配置项4是无法兼容的&#xff0c;所以想要使用新的功能&#xff0c;都需要升级&#xff01; 新建一个echarts.js文件 layui.define(function (exports) {// 这…