Audio data wavelet denoising-python

Most of the content is referred to from https://zhuanlan.zhihu.com/p/157540476.
The data type processed in the original text is a one-dimensional data type. Since wav files are also one-dimensional data, the same applies.

1. The first implementation method

1.1 Basic introduction

Number of wavelet layers: 5
Wavelet base: sym8
Threshold formula: insert image description here, cD1 is the detail coefficient decomposed in the first layer, N is the data length
Threshold function: a compromise between soft and hard thresholds

1.2 Code

# 读excel表格数据进行去噪,并使用自适应阈值计算和软阈值收缩处理
import librosa
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import math
import pywt

# 封装成函数
def sgn(num):
    if(num > 0.0):
        return 1.0
    elif(num == 0.0):
        return 0.0
    else:
        return -1.0

def wavelet_noising(new_df):
    data = new_df
    data = data.tolist()  # 将np.ndarray()转化为列表
    w = pywt.Wavelet('sym8')  # 选择sym8小波基
    [ca5, cd5, cd4, cd3, cd2, cd1] = pywt.wavedec(data, w, level=5)  # 5层小波分解
    length1 = len(cd1)
    length0 = len(data)

    Cd1 = np.array(cd1)
    abs_cd1 = np.abs(Cd1)
    median_cd1 = np.median(abs_cd1)

    sigma = (1.0/0.6745)*median_cd1
    lamda = sigma * math.sqrt(2.0*math.log(float(length0), math.e))  # 固定阈值计算
    usecoeffs = []
    usecoeffs.append(ca5)  # 向列表末尾添加对象

    # 软硬阈值折中的方法
    a = 0.5
    for k in range(length1):
        if (abs(cd1[k]) >= lamda):
            cd1[k] = sgn(cd1[k]) * (abs(cd1[k]) - a*lamda)
        else:
            cd1[k] = 0.0

    length2 = len(cd2)
    for k in range(length2):
        if (abs(cd2[k]) >= lamda):
            cd2[k] = sgn(cd2[k])*(abs(cd2[k])-a*lamda)
        else:
            cd2[k] = 0.0

    length3 = len(cd3)
    for k in range(length3):
        if (abs(cd3[k]) >= lamda):
            cd3[k] = sgn(cd3[k]) * (abs(cd3[k]) - a * lamda)
        else:
            cd3[k] = 0.0

    length4 = len(cd4)
    for k in range(length4):
        if (abs(cd4[k]) >= lamda):
            cd4[k] = sgn(cd4[k]) * (abs(cd4[k]) - a * lamda)
        else:
            cd4[k] = 0.0

    length5 = len(cd5)
    for k in range(length5):
        if (abs(cd5[k]) >= lamda):
            cd5[k] = sgn(cd5[k]) * (abs(cd5[k]) - a * lamda)
        else:
            cd5[k] = 0.0

    usecoeffs.append(cd5)
    usecoeffs.append(cd4)
    usecoeffs.append(cd3)
    usecoeffs.append(cd2)
    usecoeffs.append(cd1)
    recoeffs = pywt.waverec(usecoeffs, w)  # 信号重构
    return recoeffs

# 主函数
# path = "" #数据路径

# 提取数据
path = 'G:\实验数据集/5s/fold1/1_001-140.wav'
data, sr = librosa.load(path, sr = 16000)
'''data = pd.read_csv(path)
data = data.iloc[:, 0]  # 取第一列数据'''
plt.plot(data)
plt.show()
print(data)

data_denoising = wavelet_noising(data)  # 调用函数进行小波去噪
plt.plot(data_denoising)  # 显示去噪结果
plt.show()

1.3 Denoising effect

Audio waveform before denoising
insert image description here
Audio waveform after denoising
insert image description here
insert image description here

2 The second implementation method

insert image description here

#模块调用
import librosa
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import math
import pywt
from math import log

#sgn函数
def sgn(num):
    if(num > 0.0):
        return 1.0
    elif(num == 0.0):
        return 0.0
    else:
        return -1.0

def wavelet_noising(new_df):
    data = new_df
    data = data.values.T.tolist()  # 将np.ndarray()转为列表
    w = pywt.Wavelet('dB10')#选择dB10小波基
    ca3, cd3, cd2, cd1 = pywt.wavedec(data, w, level=3)  # 3层小波分解
    ca3=ca3.squeeze(axis=0) #ndarray数组减维:(1,a)->(a,)
    cd3 = cd3.squeeze(axis=0)
    cd2 = cd2.squeeze(axis=0)
    cd1 = cd1.squeeze(axis=0)
    length1 = len(cd1)
    length0 = len(data[0])

    abs_cd1 = np.abs(np.array(cd1))
    median_cd1 = np.median(abs_cd1)

    sigma = (1.0 / 0.6745) * median_cd1
    lamda = sigma * math.sqrt(2.0 * math.log(float(length0 ), math.e))
    usecoeffs = []
    usecoeffs.append(ca3)

    #软阈值方法
    for k in range(length1):
        if (abs(cd1[k]) >= lamda/np.log2(2)):
            cd1[k] = sgn(cd1[k]) * (abs(cd1[k]) - lamda/np.log2(2))
        else:
            cd1[k] = 0.0

    length2 = len(cd2)
    for k in range(length2):
        if (abs(cd2[k]) >= lamda/np.log2(3)):
            cd2[k] = sgn(cd2[k]) * (abs(cd2[k]) - lamda/np.log2(3))
        else:
            cd2[k] = 0.0

    length3 = len(cd3)
    for k in range(length3):
        if (abs(cd3[k]) >= lamda/np.log2(4)):
            cd3[k] = sgn(cd3[k]) * (abs(cd3[k]) - lamda/np.log2(4))
        else:
            cd3[k] = 0.0

    usecoeffs.append(cd3)
    usecoeffs.append(cd2)
    usecoeffs.append(cd1)
    recoeffs = pywt.waverec(usecoeffs, w)#信号重构
    return recoeffs

path = 'G:\实验数据集/5s/fold1/1_001-140.wav'
data, sr = librosa.load(path, sr = 16000)
'''data = pd.read_csv(path)
data = data.iloc[:, 0]  # 取第一列数据'''
plt.plot(data)
plt.show()
print(data)

data_denoising = wavelet_noising(data)#调用小波阈值方法去噪
print(data_denoising)
plt.figure()
plt.plot(data_denoising)#显示去噪结果
plt.show()

Before denoising:
insert image description here
After denoising:
insert image description here
insert image description here

3. Simple principle of wavelet threshold denoising

When wavelet decomposition is performed on the signal, the coefficients are decomposed into approximate wavelet coefficients (low frequency components of the signal) and detail wavelet coefficients (high frequency components of the signal). The wavelet threshold denoising method
believes that the noise in the signal exists in the high frequency components, so , the threshold shrinkage process is performed on the detail wavelet coefficients, and then the wavelet coefficients are combined and reconstructed to obtain the denoised signal.

How to perform threshold shrinkage on the detail wavelet coefficients?

After the signal is decomposed by wavelet: For the wavelet coefficients of each layer, the value corresponding to the noise is small, because, when selecting an appropriate threshold, the wavelet coefficients whose absolute values ​​are smaller than the threshold are set to 0, and the semantics of the coefficients with larger absolute values ​​are retained or shrunk (threshold function), and then use the wavelet inverse transform to reconstruct, that is, the denoised signal is obtained.

Steps of wavelet threshold denoising signal

(1) Perform wavelet decomposition on the noisy signal. Choose the appropriate wavelet base and decomposition scale, and perform wavelet decomposition to obtain a set of wavelet coefficients.

(2) Perform threshold quantization processing on the high-frequency coefficients of each layer decomposed by wavelet to obtain the estimated value of wavelet coefficients.

(3) Perform inverse wavelet transform on the wavelet coefficients processed by threshold quantization to reconstruct the signal and obtain the denoising signal.

Guess you like

Origin blog.csdn.net/weixin_48983346/article/details/126914867