Analysis of PyEMD algorithm

Algorithm background

Empirical Mode Decomposition (EMD for short) is a new adaptive signal time-frequency processing method creatively proposed by NE Huang and others at NASA in 1998, especially suitable for non- Analytical processing of linear non-stationary signals.

Algorithmic process analysis

  • Screening
    1. Find the extreme point极大值 and obtain the total sum  of the signal sequence through the Find Peaks algorithm极小值
    2. Fitting the envelope curve  through the 极大值sum 极小值group of the signal sequence, and 三次样条插值法obtaining two smooth peak/trough fitting curves, that is, the sum of the signal 上包络线and下包络线
    3. The mean envelope  averages the two extreme curves to obtain平均包络线
    4. Subtract the  mean envelope from the original signal of the intermediate signal to get中间信号
    5. Judging Intrinsic Modulus Function (IMF)  IMF needs to meet two conditions: 1) In the entire data segment, the number of extreme points and the number of zero-crossing points must be equal or the difference cannot exceed one at most. 2) At any time, the average value of the upper envelope formed by the local maximum point and the lower envelope formed by the local minimum point is zero, that is, the upper and lower envelopes are locally symmetrical with respect to the time axis .
  • The first intermediate signal that meets the IMF condition obtained by IMF 1  is the first eigenmode function component of the original signal IMF 1 (the new data after subtracting the envelope average from the original data, if there are negative local maxima and positive The local minimum value of , indicating that this is not yet an eigenmode function, and needs to continue to be "screened".)
  • After using the above method to obtain the first IMF, subtract IMF1 from the original signal as a new original signal, and then through the above screening analysis, IMF2 can be obtained, and so on, to complete the EMD decomposition.

1. Find extreme points

from scipy.signal import argrelextrema

# 通过Scipy的argrelextrema函数获取信号序列的极值点
data = np.random.random(100)
max_peaks = argrelextrema(data, np.greater)
min_peaks = argrelextrema(data, np.less)

# 绘制极值点图像
plt.figure(figsize = (18,6))
plt.plot(data)
plt.scatter(max_peaks, data[max_peaks], c='r', label='Max Peaks')
plt.scatter(min_peaks, data[min_peaks], c='b', label='Max Peaks')
plt.legend()
plt.xlabel('time (s)')
plt.ylabel('Amplitude')
plt.title("Find Peaks")

 

2. Fitting the envelope function

This step is the core step of EMD, and it is also the prerequisite for decomposing the intrinsic mode functions IMFs.

from scipy.signal import argrelextrema

data = np.random.random(100)-0.5
index = list(range(len(data)))

# 获取极值点
max_peaks = list(argrelextrema(data, np.greater)[0])
min_peaks = list(argrelextrema(data, np.less)[0])

# 将极值点拟合为曲线
ipo3_max = spi.splrep(max_peaks, data[max_peaks],k=3) #样本点导入,生成参数
iy3_max = spi.splev(index, ipo3_max) #根据观测点和样条参数,生成插值

ipo3_min = spi.splrep(min_peaks, data[min_peaks],k=3) #样本点导入,生成参数
iy3_min = spi.splev(index, ipo3_min) #根据观测点和样条参数,生成插值

# 计算平均包络线
iy3_mean = (iy3_max+iy3_min)/2

# 绘制图像
plt.figure(figsize = (18,6))
plt.plot(data, label='Original')
plt.plot(iy3_max, label='Maximun Peaks')
plt.plot(iy3_min, label='Minimun Peaks')
plt.plot(iy3_mean, label='Mean')
plt.legend()
plt.xlabel('time (s)')
plt.ylabel('microvolts (uV)')
plt.title("Cubic Spline Interpolation")

 

 The new signal is obtained by subtracting the average envelope from the original signal. If there are negative local maxima and positive local minima in the new signal, it means that this is not an intrinsic mode function, and it is necessary to continue " filter".

Get Intrinsic Mode Function (IMF)

def sifting(data):
    index = list(range(len(data)))

    max_peaks = list(argrelextrema(data, np.greater)[0])
    min_peaks = list(argrelextrema(data, np.less)[0])

    ipo3_max = spi.splrep(max_peaks, data[max_peaks],k=3) #样本点导入,生成参数
    iy3_max = spi.splev(index, ipo3_max) #根据观测点和样条参数,生成插值

    ipo3_min = spi.splrep(min_peaks, data[min_peaks],k=3) #样本点导入,生成参数
    iy3_min = spi.splev(index, ipo3_min) #根据观测点和样条参数,生成插值

    iy3_mean = (iy3_max+iy3_min)/2
    return data-iy3_mean


def hasPeaks(data):
    max_peaks = list(argrelextrema(data, np.greater)[0])
    min_peaks = list(argrelextrema(data, np.less)[0])
    
    if len(max_peaks)>3 and len(min_peaks)>3:
        return True
    else:
        return False


# 判断IMFs
def isIMFs(data):
    max_peaks = list(argrelextrema(data, np.greater)[0])
    min_peaks = list(argrelextrema(data, np.less)[0])
    
    if min(data[max_peaks]) < 0 or max(data[min_peaks])>0:
        return False
    else:
        return True

    
def getIMFs(data):
    while(not isIMFs(data)):
        data = sifting(data)
    return data


# EMD函数
def EMD(data):
    IMFs = []
    while hasPeaks(data):
        data_imf = getIMFs(data)
        data = data-data_imf
        IMFs.append(data_imf)
    return IMFs


# 绘制对比图
data = np.random.random(1000)-0.5
IMFs = EMD(data)
n = len(IMFs)+1

# 原始信号
plt.figure(figsize = (18,15))
plt.subplot(n, 1, 1)
plt.plot(data, label='Origin')
plt.title("Origin ")

# 若干条IMFs曲线
for i in range(0,len(IMFs)):
    plt.subplot(n, 1, i+2)
    plt.plot(IMFs[i])
    plt.ylabel('Amplitude')
    plt.title("IMFs "+str(i+1))

plt.legend()
plt.xlabel('time (s)')
plt.ylabel('Amplitude')

 

So far, the basic process of  empirical mode decomposition (EMD) has been completed .

Guess you like

Origin blog.csdn.net/chehec2010/article/details/131104665