【语言信号增强算法研究-1】维纳滤波(Wiener Filter)

news2024/10/5 17:25:29

1 语音增强方法分类

2 维纳滤波的局限性

  • 对于非线性和非高斯噪声的处理效果不佳; 对于信号和噪声的统计特性要求比较高,需要准确地了解信号和噪声的分布规律(说明自适应很差); 在处理复杂信号时,需要进行多次计算和优化,计算量较大。

3 维纳滤波的原理

4 实现源码与程序

4-1 维纳滤波器wiener_filter函数的实现代码

%% ============================================================ %%
%%                      维纳滤波器函数实现
%% ============================================================ %%

%% ------------------------------------------------------------ %%
%% param 
%  noisy:含噪信号  
%  clean:纯净信号(无噪信号)  
%  noise:纯噪音信号 
%  para :(集总了滤波器各参数的)结构体

%% retval
%  H:滤波器系数
%  enhenc:增强后的(时域形式)信号

%% (集总了滤波器各参数的)结构体para成员介绍:
%  n_fft      : FFT
%  hop_length :
%  win_length :
%  alpha      :
%  beta       :
%% ------------------------------------------------------------ %%
function [H, enhenc] = wiener_filter(noisy, clean, noise, para) % 使用维纳滤波函数
    %% 从结构体获取到相关参数
    n_fft      = para.n_fft;
    hop_length = para.hop_length;
    win_length = para.win_length;
    alpha      = para.alpha;
    beta       = para.beta;

    %% 使用短时傅里叶变换(STFT)后取绝对值,并转换为相应的频谱表示
    S_noisy = abs(stft(noisy, n_fft, hop_length, win_length)); % 得到含噪信号频谱
    S_noise = abs(stft(noise, n_fft, hop_length, win_length)); % 得到纯噪音信号频谱
    S_clean = abs(stft(clean, n_fft, hop_length, win_length)); % 得到无噪信号频谱

    %% 计算(无噪/纯噪音)信号的频谱平方后的均值
    Pxx = mean(S_clean.^2, 1);
    Pnn = mean(S_noise.^2, 1);

    %% 根据维纳滤波器的公式计算滤波器系数H
    H = (Pxx ./ (Pxx + alpha * Pnn)) .^ beta;   

    %% 将噪声信号频谱与滤波器系数相乘,得到增强后的频谱S_enhec
    S_enhec = S_noisy .* H;                     

    %% 使用逆短时傅里叶变换(ISTFT)将增强后的频谱S_enhec转换回时域信号,得到增强后的信号enhenc。
    enhenc = istft(S_enhec, hop_length, win_length);
end

4-2 滤波效果仿真代码

援引CSDN上一篇blog的代码改写如下

因为维纳滤波器的参数求解过程中必须要用到参考信号

  • 仿真信号 S g n Sgn Sgn 为两个正弦信号的叠加: S g n = A ∗ s i n ( 2 π f 1 t ) + B ∗ s i n ( 2 π f 2 t ) Sgn=A*sin(2πf_1t)+B*sin(2πf_2t) Sgn=Asin(2πf1t)+Bsin(2πf2t)
close all;
clear;
clc;

%% 信号产生,对原始信号进行采样
A=10;
B=15;
f1=1000;
f2=2000;
fs=10^5;
t=0:999;                            % 采样点t = [0,999],长度1000
M = length(t);                      % 信号长度
Sgn = A*sin(2*pi*f1*t/fs) + B*sin(2*pi*f2*t/fs);

%% 给仿真信号加入高斯白噪声
SNR = 3;                            % 初始信噪比
Obs_Sgn = awgn(Sgn,SNR,'measured'); % 给仿真信号加入信噪比为-3dB的高斯白噪声
WGN = Obs_Sgn - Sgn;                % 观测信号Obs_Sgn = 仿真信号Sgn + 高斯白噪声WGN(误差信号,每次运行都不一样)

%% 第一种情况:(期望)感兴趣信号SOI为的原信号Sgn
SOI = Sgn; 

%% 维纳滤波
N = floor(length(Obs_Sgn)*0.1);     % 滤波器的阶数,向下取整
Rxx=xcorr(Obs_Sgn, N-1, 'biased');  % 自相关函数1*(2N-1)维度,返回一个延迟范围在[-N,N]的互相关函数序列

%% 变成矩阵(N*N维度)
for i=1:N
    for j=1:N
        mRxx(i,j)=Rxx(N-i+j); % N*N维度
    end
end

%% 产生维纳滤波中x方向上观测信号与期望信号d的互相关矩阵
Rxd=xcorr(Obs_Sgn, SOI, N-1, 'biased');        % 互相关函数1*(2N-1)维度

%% 变成矩阵1*N维度
for i=1:N
    mRxd(i)=Rxd(N-1+i); % 1*N维度
end

h = inv(mRxx)*mRxd';                % 由wiener-Hopf方程得到滤波器最优解, h是N*1维度

%% 检验wiener滤波效果
y   = conv(Obs_Sgn, h);             % 滤波后的输出,长度为M+N-1,要截取前M个。
y   = y(1:M);                       % yy = filter(h,1,x);  % 用卷积或者直接用filter都可以
Py  = sum(power(y,2))/M;            % 滤波后信号y的功率
ERR = SOI - y;                      % 输出减去期望等于滤波误差
Pn  = sum(power(ERR,2))/M;          % 滤波后噪声功率
Delta_P = Py-Pn                     % 功率增量
SNR_Filtered = 10*log10(Delta_P/Pn) % 滤波后信噪比(单位db) 
imv = 10*log10(Delta_P/Pn/power(10,SNR/10)) % 滤波后较滤波前信噪比提高了imv dB。

figure(1), subplot(311);
plot(t,Sgn);
title('Signal原信号');

subplot(312);
plot(t,WGN);
title('WGN高斯白噪声');

subplot(313)
plot(t,Obs_Sgn)
title('观测波形')

在这里插入图片描述

%% 期望和滤波后的信号对比
figure(2), subplot(211);
plot(t, SOI, 'r:', t, y, 'b-','LineWidth',1);
legend('期望信号','滤波后结果'); 
title('期望信号与滤波结果对比');
xlabel('观测点数'), ylabel('信号幅度');
axis([0 1000 -50 50]);

subplot(212), plot(t, ERR);
title('输出误差');
xlabel('观测点数'), ylabel('误差幅度');
axis([0 1000 -50 50]);


%% 滤波前后对比
figure(3), subplot(211);
plot(t, Obs_Sgn);
title('维纳滤波前');
xlabel('观测点数'), ylabel('信号幅度');
axis([0 1000 -50 50])

subplot(212), plot(t, y);
title('维纳滤波后');
xlabel('观测点数'), ylabel('误差幅度');
axis([0 1000 -50 50]);

在这里插入图片描述


%% 情况二:(期望)感兴趣信号SOI为的加性高斯白噪声WGN
SOI = WGN;

...
%% 期望信号与滤波结果对比
figure(2)
plot(t, SOI, 'r:', t, y, 'b-','LineWidth',1);
legend('期望信号','滤波后结果'); 
title('期望信号与滤波结果对比');
xlabel('观测点数'), ylabel('信号幅度');
axis([0 1000 -50 50])


%% Signal原始信号与噪声抵消后结果对比
figure(3)
plot(t, Sgn, 'r:', t, Obs_Sgn - y, 'b-','LineWidth',1);
legend('Signal原始信号','噪声抵消后结果');
title('Signal原始信号与噪声抵消后结果对比');
xlabel('观测点数'), ylabel('信号幅度');
axis([0 1000 -50 50])

在这里插入图片描述


%% 情况三:(期望)感兴趣信号SOI为的观测信号
%% 观测信号与滤波结果对比
figure(2), subplot(211);
plot(t, Obs_Sgn, 'r:', t, y, 'b-','LineWidth',1);
legend('观测信号','滤波后结果'); 
title('观测信号与滤波结果对比');
xlabel('观测点数'), ylabel('信号幅度');
axis([0 1000 -50 50])

subplot(212);
plot(t, ERR);
title('输出误差');
xlabel('观测点数'), ylabel('误差幅度');
axis([0 1000 -50 50]);


%% 滤波前后对比
figure(3), subplot(211);
plot(t, Obs_Sgn);
title('维纳滤波前');
xlabel('观测点数'), ylabel('信号幅度');
axis([0 1000 -50 50])

subplot(212), plot(t, y);
title('维纳滤波后');
xlabel('观测点数'), ylabel('误差幅度');
axis([0 1000 -50 50]);

在这里插入图片描述

4-3 仿真实验结论

  • (期望)感兴趣信号设置为原始信号 S g n Sgn Sgn时,效果最好

5 详细说明

  • 原始信号 S g n Sgn Sgn 经过噪声信道(加入白噪声 W G N WGN WGN),变成 含噪信号 O b s S g n ObsSgn ObsSgn O b s S g n = S g n + W G N ObsSgn=Sgn+WGN ObsSgn=Sgn+WGN)。
    O b s S g n ObsSgn ObsSgn 经过维纳滤波器(Wiener Filter)后得到 S g n F i l t e r e d SgnFiltered SgnFiltered,由于期望的感兴趣信号为 S O I SOI SOI ,则误差信号 E R R = S O I − S g n F i l t e r e d ERR=SOI-SgnFiltered ERR=SOISgnFiltered,滤波器系数为H
  • 按照均方误差最小原则,从 O b s S g n ObsSgn ObsSgn 信号中剥离得到 S g n Sgn Sgn,叫维纳滤波理论
  • 不能使用维纳滤波法对未知信号进行滤波!!!因为设计滤波器系数时需要使用到期望信号 S O I SOI SOI

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

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

相关文章

【Functional Affordances】如何确认可抓取的区域?(前传)

文章目录 1. 【Meta AI】Emerging Properties in Self-Supervised Vision Transformers2. 【Meta AI】DINOv2: Learning Robust Visual Features without Supervision3. 【NeurIPS 2023】Diffusion Hyperfeatures: Searching Through Time and Space for Semantic Corresponden…

ElasticSearch理论指导

引子 本文致力于ElasticSearch理论体系构建,从基本概念和术语讲起,具体阐述了倒排索引和TransLog,接着讲了ElasticSearch的增删改查的流程和原理,最后讲了讲集群的选举和脑裂问题。 前言 大碗宽面-Kafka一本道万事通&#xff0…

蓝桥杯真题:成绩统计

这题思路简单,但是输出结果的位置容易出错,题目要求四舍五入,所以要用Math.round()的方法

瑞吉外卖实战学习--10、完成新增菜品分类

完成新增菜品分类 前言1、前期准备定义实体类和实体对象 2、创建修改的接口 前言 1、前期准备 定义实体类和实体对象 package com.example.ruiji_demo.entity;import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.TableField; …

kubernetes-Pod基于污点、容忍度、亲和性的多种调度策略(二)

Pod调度策略 一.污点-Taint二.容忍度-Tolerations三.Pod常见状态和重启策略1.Pod常见状态2.Pod的重启策略2.1测试Always重启策略2.2测试Never重启策略2.3测试OnFailure重启策略(生产环境中常用) 一.污点-Taint 在 Kubernetes 中,污点&#x…

稻盛和夫|普通人如何才能取得非凡成就?

哈喽,你好啊,我是雷工! 稻盛和夫老先生曾经回答过这么一个问题: 资质平庸的普通人如何才能取得非凡的成就? 稻盛和夫认为:人生成就=能力努力态度。 也就是:做一个努力工作却不甘于只做眼前的事,而想要做更有挑战的事,这种人才能逃离平庸,取得非凡成就。 01 不甘平凡…

django+uniapp校园失物招领系统e5asg 微信小程序python

本失物招领小程序,使用的是比较成熟的python语言和比较完善的MySQL数据库,将网络失物招领小程序信息管理系统可以更安全、技术性更强的满足网站所有信息的管理。 失物招领小程序主要实现了管理员服务端模块、学生微信端模块二大部分。通过本失物招领小程…

200个有趣的HTML前端游戏项目合集(持续更新中)

💂 个人网站:【 摸鱼游戏】【神级代码资源网站】【工具大全】🤟 一站式轻松构建小程序、Web网站、移动应用:👉注册地址🤟 基于Web端打造的:👉轻量化工具创作平台💅 想寻找共同学习交…

新生报到系统的设计与实现(论文+源码)_kaic

摘 要 互联网发展至今,无论是其理论还是技术都已经成熟,而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播,搭配信息管理工具可以很好地为人们提供服务。针对新生报到信息管理混乱,出错率高,信息安全性差…

11-2说说小滴课堂之前的被薅羊毛的事情+防范解决方案

11-2说说小滴课堂之前的被薅羊毛的事情防范解决方案

【LVGL-字库应用】

LVGL-中文字库应用 ■ LVGL-内部字库■ LVGL 内部字库的使用流程: ■ LVGL-自定义字库■ 方法一:C 语言数组(内部读取)-在线转换工具■ 方法二:C 语言数组(内部读取)-利用离线字体转换软件&…

【Java】API——Calendar日期类使用+题目演示

目录 Calendar日期类简单介绍 导入对应包: 获取 Calendar 对象: 设置日期和时间: 获取日期和时间的各个部分: 日期和时间的加减操作: 例题:世纪末的星期 题目描述 题目代码 Calendar日期类简单介绍…

FPGA之状态机学习

作为一名逻辑工程师,掌握和应用状态机设计是必不可少的。能够灵活的应用状态机是对逻辑工程师最基本的要求,状态机设计的好坏能够直接影响到设计系统的稳定性,所以学会状态机是非常的重要。 1.状态机的概念 状态机通过不同的状态迁移来完成特…

计算机网络—TCP协议详解:特性、应用(1)

🎬慕斯主页:修仙—别有洞天 ♈️今日夜电波:マリンブルーの庭園—ずっと真夜中でいいのに。 0:34━━━━━━️💟──────── 3:34 🔄 ◀️…

YOLOv8部署到C++上(综合版笔记)

这段时间由于项目的需要,需要将yolov8部署到C上以及跟相应的算法结合,花了我不少时间。 现阶段有考虑过使用onnx转Tensort,但是无法输出分类的结果,故放弃,有目标检测的小伙伴可以试试,接下来使用onnxrunt…

Qt打印系统库的日志 - QLoggingCategory

Qt的动态库通过源码可以可以看到含有大量的qCInfo 和 qCDebug 等大量的日志, 但是我们正常运行Qt程序,这些动态库或插件里面的日志是不会输出到我们的控制台里面的。 所以本章主要记录怎么输出这些日志出来。 一: 步骤 主要使用的是Qt的 函…

第十四届省赛大学B组(C/C++)岛屿个数

目录 题目链接:岛屿个数 解题思路: AC代码(BFSDFS): 题目链接:岛屿个数 小蓝得到了一副大小为 MN 的格子地图,可以将其视作一个只包含字符 0(代表海水)和 1&#xff0…

机器人控制系统阶跃响应

机械臂控制系统的阶跃响应是指当给机械臂控制系统施加一个阶跃输入(即输入量在短时间内从0跳变为某个定值)时,机械臂的输出(如位置、速度等)随时间的变化情况。通过观察和分析阶跃响应,可以了解机械臂控制系…

Verilog语法之assign语句学习

assign语法主要是对组合逻辑的变量进行赋值的,就是把一个变量赋值给另一个变量,被复制的变量必须是wire类型的参数。 从仿真结果可以看出,data_in变量的值赋值给了data_out,assign语法就是赋值没有任何延迟,data_in是什么值&#…

OpenHarmony相机和媒体库-如何在ArkTS中调用相机拍照和录像。

介绍 此Demo展示如何在ArkTS中调用相机拍照和录像,以及如何使用媒体库接口进行媒体文件的增、删、改、查操作。 本示例用到了权限管理能力ohos.abilityAccessCtrl 相机模块能力接口ohos.multimedia.camera 图片处理接口ohos.multimedia.image 音视频相关媒体业…