Извлечение высокочастотного компонента из сигнала с использованием PyWT в Python - PullRequest
0 голосов
/ 22 января 2019

Я хочу извлечь высокочастотную составляющую из сигнала, состоящего из разных частотных составляющих, используя пакет pywt в python. Как мне сделать это правильно?

Чтобы извлечь высокочастотные компоненты из сигнала, я попытался использовать функциональность pywt.dwt для дискретного вейвлет-преобразования. Мой код и объяснения того, что он делает, можно найти здесь: https://github.com/EstebanHess/WaveletTransform_with_pywt/blob/master/Extract_High_Freqs.ipynb

Поскольку я не знал, как напрямую восстанавливать высокочастотные компоненты сигнала, я реконструировал их косвенно: я выделил более низкие частоты и вычел их из исходного сигнала, чтобы получить более высокие частоты. Однако восстановленные низкочастотные компоненты длиннее исходного сигнала и должны быть нарезаны, чтобы иметь одинаковую длину, прежде чем они могут быть вычтены из исходного сигнала. Правильный срез может быть получен методом проб и ошибок или визуальным осмотром в случае простого иллюстративного примера, как в моей записной книжке. Но как мне узнать, как выбрать правильную часть восстановленной низкочастотной составляющей в случае реальных данных? Или можно напрямую восстановить высокочастотную составляющую? Если да, то как?

#### Import python packages:  
import math
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import pylab
import pywt

#### Create a signal by adding the two above signals: constant low frequency plus a mixed signal (constant in the first part and high frequency in the second part):

zero_streak = np.zeros(100)
zero_high = np.concatenate((zero_streak,signals_highfreq['200_points'][100:]))
len(zero_high)

sine_wave_low = signals_lowfreq['200_points']
sine_wave_high = signals_highfreq['200_points']

pylab.subplot(2,2,1)
pylab.plot(sine_wave_low)
pylab.subplot(2,2,2)
pylab.plot(zero_high)
fig.show()

signal_mixed_half = signals_lowfreq['200_points'] + zero_high

plt.plot(signal_mixed_half)


## Task: Decompose the mixed signal (signal_mixed_half) in order to reconstract the original low frequency signal (sine_wave_low):


#### Decomposing the signal using discrete wavelet transform:
def dwt_steps(a, w, mode, num_steps):
    ca = []
    cd = []
    for i in range(num_steps + 1):
        (a, d) = pywt.dwt(a, w, mode)
        ca.append(a)
        cd.append(d)
    return ca, cd

w = 'sym14'
mode = pywt.Modes.smooth
ca, cd = dwt_steps(signal_mixed_half, w, mode, 10)


#### Reonstructing the signal from the estimates:
rec_a = []
rec_d = []

for i, coeff in enumerate(ca):
    coeff_list = [coeff, None] + [None] * i
    rec_a.append(pywt.waverec(coeff_list, w))

for i, coeff in enumerate(cd):
    coeff_list = [None, coeff] + [None] * i
    rec_d.append(pywt.waverec(coeff_list, w))


#### Select the correct slice from the low frequency component:
low_freq_rec = rec_a[2][:200]
## This is the critical step: How do I know the indices for correct slicing?


#### Subtract the low frequency component from the original signal:
high_freq_rec = signal_mixed_half - low_freq_rec


#### The two signal components reconstructed by wavelet transform look quite similar to the two original signal components that were used to create the mixed signal: 

pylab.subplot(2,2,1)
pylab.plot(low_freq_rec)
pylab.subplot(2,2,2)
pylab.plot(high_freq_rec)
fig.show()

pylab.subplot(2,2,1)
pylab.plot(sine_wave_low)
pylab.subplot(2,2,2)
pylab.plot(zero_high)
fig.show()

Был бы признателен пример кода, показывающего, как извлечь высокочастотный компонент из сигнала без проб и ошибок или визуального осмотра данных (чтобы он работал с большими и сложными данными).

...