본문으로 바로가기

1차 필터는 생각보다 블로그에서 많이 다루었더라구요^^. 처음 1차 저역/고역 통과필터를 C로 구현하는 방법에 대한 이야기[바로가기]때 부터 MATLAB[바로가기]뿐만 아나라 Python에서도 어떻게 구현할 것인지 이야기[바로가기]했지요. 심지어 전 엑셀에서 저역통과필터를 구현하는 것도 이야기[바로가기]를 했던 적이 있습니다.^^. 오늘은 그 대상이 Python입니다만, 실제로는 디지털 필터를 어떻게 구현할 것인지를 한 번 정리하는 것을 목적으로 합니다. 일단 1차 저역통과필터를 대상으로 차단주파수를 결정했을 때, 어떻게 디지털 필터로 변환하며 또 어떻게 실제 코드로 구현할 것인지를 보는 것이 목적입니다.^^.

연속시간 영역에서의 1차 저역통과필터

앞 선 필터 관련 글들에서도 참 자주 나온 수식이지만, 위 수식은 1차 저역통과필터(LPF)의 s-domain 표현식입니다. 위 식의 bode 선도도 이야기[바로가기]한 적이 있습니다. 뭐 아무튼... 만약 차단 주파수(f_cut)를 결정했다면~ 차단 각주파수는...

이 됩니다.~

그러면 tau는 위 식으로 결정됩니다.^^ 이제 차단 주파수를 정하면 tau를 결정할 수 있겠죠^^ 만약 차단 주파수를 100Hz에서 결정했다면~

tau는 위 수식으로 결정이 됩니다.^^

그러면 애초 1차 LPF는 위와 같이 결정이 됩니다.

f_cut = 100
w_cut = 2*np.pi*f_cut
tau = 1/w_cut

num = np.array([1.])
den = np.array([tau, 1.])
w, h = sig.freqs(num, den, worN=np.logspace(0, 5, 1000))

plt.figure(figsize=(12,5))
plt.semilogx(toHz(w), 20 * np.log10(abs(h)))
plt.axvline(f_cut, color='k', lw=1)
plt.xlabel('Frequency (Hz)')
plt.ylabel('Amplitude response [dB]')
tmpTitle = 'Low Pass Filter, cutoff freq. at ' + str(f_cut) + 'Hz in continuous'
plt.title(tmpTitle)
plt.xlim(1, Fs/2)
plt.grid()
plt.show()

그러면 위 Python 코드처럼 실행해주면, 보드선도를 그려서 확인할 수 있습니다. 아~ freqs는 scipy.signal 모듈안에 있습니다.

그렇게 해서 위 그림처럼 100Hz가 차단 주파수로 설정된 1차 저역통과필터를 확인할 수 있습니다. 100Hz 지점에서 3dB 떨어지고, -20dB의 기울기로 하강하는 것이 보이네요^^ 이렇게 해서 차단 주파수가 결정되었을 때 tau를 계산하는 법을 보았습니다. 이제 이를 디지털 필터로 한 번 변환해 보도록 하겠습니다.^^

연속시간 영역에서의 1차 저역통과필터를 이산 시간 영역에서 구하기

이제 다시 위 식에서~

위와 같이 정리하고~

라플라스 역변환으로 위와 같이 표현가능합니다. 여기서 미분항을 차분으로 표현하면~

연속시간의 수식이 이산시간에서의 수식으로 편하게 변환됩니다.^^

그러면 이렇게 표현되지요. 여기서 C, MATLAB, Python등등 글 초반에 이야기한 예제들을 보여드렸었는데요^^ 이 상태에서 약간 정형화된 모습을 보기 위해 z-변환을 하도록 하겠습니다.^^

그러면 위 결과를 얻지요. 이 상태에서~ 아까 100Hz에서 구한 tau와 현재 샘플 주파수를 20kHz라고 가정한 후, 

num_z = np.array([Ts/(tau+Ts)])
den_z = np.array([1., -tau/(tau+Ts)])

wz, hz = sig.freqz(num_z, den_z, worN=10000)

plt.figure(figsize=(12,5))
plt.semilogx(toHz(wz*Fs), 20 * np.log10(abs(hz)), 'r', label='discrete time')
plt.semilogx(toHz(w), 20 * np.log10(abs(h)), 'b--', label='continuous time')
plt.axvline(f_cut, color='k', lw=1)
plt.axvline(Fs/2, color='k', lw=1)
plt.xlabel('Frequency (Hz)')
plt.ylabel('Amplitude response [dB]')
tmpTitle = 'Low Pass Filter, cutoff freq. at ' + str(f_cut) + 'Hz in discrete'
plt.title(tmpTitle)
plt.xlim(1, Fs/2)
plt.grid()
plt.legend()
plt.show()

위 코드를 실행하면 얻는 그림이

입니다. 샘플주파수의 절반(Nyquist Frequency)에 가까워질 수록 연속시간과는 차이가 나지만, 일단 나머지 부분에서는 비슷한 결과네요. 아 Python에서 연속시간의 주파수 응답을 얻기 위한 함수가 freqs이고, 이산시간에서는 freqz입니다 그런데.... freqs는 그냥 주파수를 domain으로 출력해서 plot할 때 그냥 사용하면 되는데, freqz느 normalize된 주파수를 내놓기 때문에 plot할 때, Fs(sample freqeuncy)를 곱해야 합니다. 뭐 아무튼 여기까지 해서 라플라스 표현으로 나타내는 1차 저역통과필터를 z-변환의 형태로 표현하도록 공식화 할 수 있네요. 

디지털 필터 구현하기

이제 실제 필터의 구현에 대해 이야기를 해보겠습니다. 필터의 형태에서 아마도~ 가장 많이 사용하는 형태가

2차의 Direct II Form

이런 Direct II Form일텐데요. 이 형태에 맞춰서 계수를 정리할 수 있습니다.

이렇게 말이죠^^ 위 그림의 2차 Direc II Form의 경우는 def로 만들어 두면 편할 겁니다.^^.

def direct2FormModel(data, a1, a2, b0, b1, b2):
    from numpy import zeros, arange
    
    result = zeros((len(data),))
    timeZone = zeros((len(data),))
    
    for n in arange(2, len(data)):
        sum0 = -a1*timeZone[n-1] - a2*timeZone[n-2]
        timeZone[n] = data[n] + sum0
        result[n] = b0*timeZone[n] + b1*timeZone[n-1] + b2*timeZone[n-2]
        
    return result
    
def differentialEqForm(data, a1, a2, b0, b1, b2):
    from numpy import zeros, arange
    
    result = zeros((len(data),))
    
    for n in arange(2, len(data)):
        result[n] = b0*data[n] + b1*data[n-1] + b2*data[n-2] - a1*result[n-1] - a2*result[n-2]
        
    return result
    
def filterSimpleLPF(data, tau, Ts):
    from numpy import zeros, arange
    
    result = zeros((len(data),))
    
    for n in arange(1, len(data)):
        result[n] = (tau*result[n-1] + Ts*data[n])/(tau + Ts)
        
    return result

그게 위 함수인 direc2FormModel입니다. 블럭을 그대로 그냥 뭐 아무 생각없이 작성했다고 생각하시면 됩니다^^. 이왕하는 김에 이전 글에서 tau로 표현하던 간편한 형태를 또 filterSimpleLPF로 작성해 두었습니다. 또 direct2form이 아니라 바로 차분 방정식으로 표현하는 것도 나중을 위해 2차로 구현을 해 두었습니다.(differentialEqForm

이제 제가 맨날 하듯이~~~ 시험신호 하나 만들고 가죠^^

# Create Test Signal
Fs = 20*10**3               # 20kHz
Ts = 1/Fs                   # sample Time
endTime = 2
t = np.arange(0.0, endTime, Ts)

inputSig = 3.*np.sin(2.*np.pi*t)

sampleFreq = np.arange(10,500,50)

for freq in sampleFreq:
    inputSig = inputSig + 2*np.sin(2*np.pi*freq*t)
    
plt.figure(figsize=(12,5))
plt.plot(t, inputSig)
plt.xlabel('Time(s)')
plt.title('Test Signal in Continuous')
plt.grid(True)
plt.show()

draw_FFT_Graph(inputSig, Fs, title='inputSig', xlim=(0, 500))

2Hz의 주 주파수를 두고, 10부터 500까지 50간격으로 주파수를 만들어 더해둡니다. 아 그리고 FFT를 그리는 함수도 따로 두었는데요.

def draw_FFT_Graph(data, fs, **kwargs):
    from numpy.fft import fft
    import matplotlib.pyplot as plt
    
    graphStyle = kwargs.get('style', 0)
    xlim = kwargs.get('xlim', 0)
    ylim = kwargs.get('ylim', 0)
    title = kwargs.get('title', 'FFT result')
    
    n = len(data)
    k = np.arange(n)
    T = n/Fs
    freq = k/T 
    freq = freq[range(int(n/2))]
    FFT_data = fft(data)/n 
    FFT_data = FFT_data[range(int(n/2))]
    
    plt.figure(figsize=(12,5))
    if graphStyle == 0:
        plt.plot(freq, abs(FFT_data), 'r', linestyle=' ', marker='^') 
    else:
        plt.plot(freq,abs(FFT_data),'r')
    plt.xlabel('Freq (Hz)')
    plt.ylabel('|Y(freq)|')
    plt.vlines(freq, [0], abs(FFT_data))
    plt.title(title)
    plt.grid(True)
    plt.xlim(xlim)
    plt.ylim(ylim)
    plt.show()

입니다. 이제~ 시험신호는 

이렇습니다. 흠~~ 이쁘네요^^

주파수 응답은 또 위와 같습니다.^^. 원했던 주파수가 다 표현되어 있네요^^

filteredSig1 = filterSimpleLPF(inputSig, tau, Ts)
filteredSig2 = differentialEqForm(inputSig, a1, a2, b0, b1, b2)
filteredSig3 = direct2FormModel(inputSig, a1, a2, b0, b1, b2)

draw_FFT_Graph(filteredSig1, Fs, title='filterSimpleLPF', xlim=(0, 500))
draw_FFT_Graph(filteredSig2, Fs, title='differentialEqForm', xlim=(0, 500))
draw_FFT_Graph(filteredSig3, Fs, title='direct2FormModel', xlim=(0, 500))

이제 간편한 제가 자주 블로그에서 언급하던 방법(filterSimpleLPF)과 일반적으로 필터를 구현할 때 많이 사용하는 Direct II Form, 그리고 차분방정식으로 그대로 표현하는 differentialEqForm을 모두 적용한 후 FFT로 확인했더니....

모두 위와 같이 나왔습니다 큰 차이가 없다는 거겠죠^^

그 결과도 위와 같이 나타납니다. LPF가 잘 적용된 듯 보입니다.^^

각 방법별 에러를 확인했는데 아주 작거나 혹은 첫 샘플에서만 약간의 에러를 가지는 것으로 확인됩니다. 괜찮네요^^

오늘은

  • 차단 주파수를 결정했을 때, 연속시간 영역에서 1차 저역통과필터 결정하기
  • 연속시간 영영에서 결정된 1차 저역통과필터를 이산 시간영역에서 표현하기
  • 결정된 필터를 알려진 몇몇 방법으로 직접 구현해보기

를 보여드리고 싶었습니다.^^ 마지막으로 전체 Python 코드는 아래에 있습니다.^^

# -*- coding: utf-8 -*-

def toHz(value):
    from numpy import pi
    return value/2/pi
    
def direct2FormModel(data, a1, a2, b0, b1, b2):
    from numpy import zeros, arange
    
    result = zeros((len(data),))
    timeZone = zeros((len(data),))
    
    for n in arange(2, len(data)):
        sum0 = -a1*timeZone[n-1] - a2*timeZone[n-2]
        timeZone[n] = data[n] + sum0
        result[n] = b0*timeZone[n] + b1*timeZone[n-1] + b2*timeZone[n-2]
        
    return result
    
def differentialEqForm(data, a1, a2, b0, b1, b2):
    from numpy import zeros, arange
    
    result = zeros((len(data),))
    
    for n in arange(2, len(data)):
        result[n] = b0*data[n] + b1*data[n-1] + b2*data[n-2] - a1*result[n-1] - a2*result[n-2]
        
    return result
    
def filterSimpleLPF(data, tau, Ts):
    from numpy import zeros, arange
    
    result = zeros((len(data),))
    
    for n in arange(1, len(data)):
        result[n] = (tau*result[n-1] + Ts*data[n])/(tau + Ts)
        
    return result
    
def draw_FFT_Graph(data, fs, **kwargs):
    from numpy.fft import fft
    import matplotlib.pyplot as plt
    
    graphStyle = kwargs.get('style', 0)
    xlim = kwargs.get('xlim', 0)
    ylim = kwargs.get('ylim', 0)
    title = kwargs.get('title', 'FFT result')
    
    n = len(data)
    k = np.arange(n)
    T = n/Fs
    freq = k/T 
    freq = freq[range(int(n/2))]
    FFT_data = fft(data)/n 
    FFT_data = FFT_data[range(int(n/2))]
    
    plt.figure(figsize=(12,5))
    if graphStyle == 0:
        plt.plot(freq, abs(FFT_data), 'r', linestyle=' ', marker='^') 
    else:
        plt.plot(freq,abs(FFT_data),'r')
    plt.xlabel('Freq (Hz)')
    plt.ylabel('|Y(freq)|')
    plt.vlines(freq, [0], abs(FFT_data))
    plt.title(title)
    plt.grid(True)
    plt.xlim(xlim)
    plt.ylim(ylim)
    plt.show()

import numpy as np
import matplotlib.pyplot as plt
import scipy.signal as sig

# Create Test Signal
Fs = 20*10**3               # 20kHz
Ts = 1/Fs                   # sample Time
endTime = 2
t = np.arange(0.0, endTime, Ts)

inputSig = 3.*np.sin(2.*np.pi*t)

sampleFreq = np.arange(10,500,50)

for freq in sampleFreq:
    inputSig = inputSig + 2*np.sin(2*np.pi*freq*t)
    
plt.figure(figsize=(12,5))
plt.plot(t, inputSig)
plt.xlabel('Time(s)')
plt.title('Test Signal in Continuous')
plt.grid(True)
plt.show()

draw_FFT_Graph(inputSig, Fs, title='inputSig', xlim=(0, 500))

# Design 1st Order Low Pass Filter
f_cut = 100
w_cut = 2*np.pi*f_cut
tau = 1/w_cut

num = np.array([1.])
den = np.array([tau, 1.])
w, h = sig.freqs(num, den, worN=np.logspace(0, 5, 1000))

plt.figure(figsize=(12,5))
plt.semilogx(toHz(w), 20 * np.log10(abs(h)))
plt.axvline(f_cut, color='k', lw=1)
plt.xlabel('Frequency (Hz)')
plt.ylabel('Amplitude response [dB]')
tmpTitle = 'Low Pass Filter, cutoff freq. at ' + str(f_cut) + 'Hz in continuous'
plt.title(tmpTitle)
plt.xlim(1, Fs/2)
plt.grid()
plt.show()

# Design 1st Order Low Pass Filter Z-Transform
num_z = np.array([Ts/(tau+Ts)])
den_z = np.array([1., -tau/(tau+Ts)])

wz, hz = sig.freqz(num_z, den_z, worN=10000)

plt.figure(figsize=(12,5))
plt.semilogx(toHz(wz*Fs), 20 * np.log10(abs(hz)), 'r', label='discrete time')
plt.semilogx(toHz(w), 20 * np.log10(abs(h)), 'b--', label='continuous time')
plt.axvline(f_cut, color='k', lw=1)
plt.axvline(Fs/2, color='k', lw=1)
plt.xlabel('Frequency (Hz)')
plt.ylabel('Amplitude response [dB]')
tmpTitle = 'Low Pass Filter, cutoff freq. at ' + str(f_cut) + 'Hz in discrete'
plt.title(tmpTitle)
plt.xlim(1, Fs/2)
plt.grid()
plt.legend()
plt.show()

# Implementation Signal
a1 = den_z[1]
a2 = 0
b0 = num_z[0]
b1 = 0.
b2 = 0.

filteredSig1 = filterSimpleLPF(inputSig, tau, Ts)
filteredSig2 = differentialEqForm(inputSig, a1, a2, b0, b1, b2)
filteredSig3 = direct2FormModel(inputSig, a1, a2, b0, b1, b2)

draw_FFT_Graph(filteredSig1, Fs, title='filterSimpleLPF', xlim=(0, 500))
draw_FFT_Graph(filteredSig2, Fs, title='differentialEqForm', xlim=(0, 500))
draw_FFT_Graph(filteredSig3, Fs, title='direct2FormModel', xlim=(0, 500))

plt.figure(figsize=(12,5))
plt.plot(t, inputSig)
plt.plot(t, filteredSig1, 'r', label='SimpleLPF')
plt.plot(t, filteredSig2, 'c', label='DE')
plt.plot(t, filteredSig3, 'k', label='D2F')
plt.xlabel('Time(s)')
plt.title('Filtered Signal in Discrete')
plt.legend()
plt.grid(True)
plt.show()

# Err
err = filteredSig2 - filteredSig1
plt.figure(figsize=(12,5))
plt.plot(t, err)
plt.xlabel('Time(s)')
plt.title('Error between differentialEqForm and filterSimpleLPF')
plt.grid(True)
plt.show()

err = filteredSig2 - filteredSig3
plt.figure(figsize=(12,5))
plt.plot(t, err)
plt.xlabel('Time(s)')
plt.title('Error between differentialEqForm and direct2FormModel')
plt.grid(True)
plt.show()

err = filteredSig1 - filteredSig3
plt.figure(figsize=(12,5))
plt.plot(t, err)
plt.xlabel('Time(s)')
plt.title('Error between filterSimpleLPF and direct2FormModel')
plt.grid(True)
plt.show()


댓글을 달아 주세요

  1. BlogIcon 에이티포 2016.08.28 21:02 신고

    갑자기 두통이 나기 시작......;ㅋㅋㅋㅋㅋ

  2. 행복한 밤되세요

  3. 머리아포 2016.09.13 02:18 신고

    안녕하세요. 초면인데, 질문좀 드리겠습니다 ㅠ
    제가 지금 3축가속도 센서를 이용하여 속도를 구해보려고 하는데 갈 길이 막막합니다. 먼저, 속도변환하기에 앞서서, 우선 LP 필터 혹은 HP 필터를 써서 필터링을 해야한다는데, 쓰면 왜.... 노이즈가 제가 되는지 모르겠습니다.
    회로이론등을 통해서 얻은 지식으로는 노이즈가 제거 되는 것은 알겠는데요. 그것은 연속적인 그래프일 때 적용되는게 아닌가요? 저는 3축 가속도 센서에서 출력 하는 값들은 디지털값. 즉, 이산 적인 값이라서... 그래프로 찍어보면 노이즈가 가미된 연속 신호이겠지만, 이게 개별적으로 보면 점의 값인데 어떻게 필터가 적용이 될 수 있는것이죠? 애초에 점은 한순간의 값인데 어떻게.. 적용이 되는 걸까요..; ㅠㅠ 알려주시면 감사하겠습니다.

    • BlogIcon PinkWink 2016.09.13 13:54 신고

      샘플링 타임에 맞춰 이산시간 영역에서 필터를 설계한 것입니다.
      연속시간의 내용이 이산시간에 맞춰 적용된 것이 디지털 필터이구요...
      실제로 신호를 일정시간마다 맞춰 만들어서 필터를 적용해보시면 실제 확인할 수 있습니다.

  4. 머리아포 2016.09.15 07:07 신고

    안녕하세요. 한가위는 잘 보내셨나요?
    답변보고 3축 가속도 센서에 관하여 질문드립니다.

    달아주신 답변을 보고난 뒤, 혹시나 싶어 센서 제조사의 데이터시트에 스팩 및 응용방안을 보니..
    친절하지는 못했습니다. (현재 Analog사의 ADXL362를 쓰고 있습니다.)
    물론 검색을 2일에 걸쳐서 해보았지만 큰 성과는 없었습니다.
    아마, 제가 해당 단어를 모르니.. 올바른 검색이 안됐을 것이라 보고 있습니다.

    그럼, 본론입니다 ^^
    제가 궁금한 것은
    1)우선, 3축가속도 센서의 값을 유용한 값으로 쓸 수 있도록 하고 싶습니다.
    즉, 바로 3축가속도 센서의 값을 뽑아내면, 어디로 튈지 모르는 값이 사이사이에 끼어서 나옵니다. 이를 제거하여
    우선적으로 "응용할 수 있는 x,y,z축의 쓸모있는 값으로 정리하고 싶습니다."
    >> 속도를 뽑기위해 준비해야 될 과정이 무엇인지 궁금합니다. (이 과정에서 LP, HP필터니 zero Tolerence 등을 듣게 되었고 흘러흘러 'PinkWink님의 블로그'에 들어오게 되었습니다. 저는 이것을 어떻게 적용하라는 건지, 왜 필요 한지를 모르겠습니다. 이에 대한 설명을 해주신다면 정말 감사드리겠습니다.)

    2) 3축가속도 센서의 값이 정리가 된다면, 이제 속도를 뽑아내도록 하고 싶습니다.
    제가 단순하게 생각 해보았을 때는 3축 가속도 센서의 값이 이산값이므로 '구분구적법'에 의한 접근이 제일 편하다고 생각하는데 이것보다도 더 효과적인 방법이 있을것이라고 보고 있습니다.


    정말 오랫동안 혼자 생각해보고 연구해보았지만.. 벽에 부딪혀서 이렇게 질문을 드려보게 되네요.
    답변 하나하나 감사드립니다.


    • BlogIcon PinkWink 2016.09.17 08:46 신고

      1)우선, 3축가속도 센서의 값을 유용한 값으로 쓸 수 있도록 하고 싶습니다.
      즉, 바로 3축가속도 센서의 값을 뽑아내면, 어디로 튈지 모르는 값이 사이사이에 끼어서 나옵니다. 이를 제거하여
      우선적으로 "응용할 수 있는 x,y,z축의 쓸모있는 값으로 정리하고 싶습니다."
      >> 속도를 뽑기위해 준비해야 될 과정이 무엇인지 궁금합니다. (이 과정에서 LP, HP필터니 zero Tolerence 등을 듣게 되었고 흘러흘러 'PinkWink님의 블로그'에 들어오게 되었습니다. 저는 이것을 어떻게 적용하라는 건지, 왜 필요 한지를 모르겠습니다. 이에 대한 설명을 해주신다면 정말 감사드리겠습니다.)

      ====> 근본적으로 가속도 성분에서 속도를 추출하고 싶다면 당연히 '적분'이라는 과정이 필요합니다. 그러니 일단 적분한번 해 보시죠. 그러면 뭔가 내가 의도한 결과와는 좀 다를 겁니다. 여기서 참값으로 사용할 비교 데이터가 있어야합니다. 제자리에서 이정한 주파수로 흔든다든지, 혹은 엔코더등을 이용하여 참값이라고 믿을 수 있는 속도값을 가지고 있던지 말이죠. 그러면 사용할 목적과 환경에 맞게 노이즈 제거를 위한 LPF를 쓰거나, 저주파 영역을 제거할 HPF를 사용하는 것입니다.

      2) 3축가속도 센서의 값이 정리가 된다면, 이제 속도를 뽑아내도록 하고 싶습니다.
      제가 단순하게 생각 해보았을 때는 3축 가속도 센서의 값이 이산값이므로 '구분구적법'에 의한 접근이 제일 편하다고 생각하는데 이것보다도 더 효과적인 방법이 있을것이라고 보고 있습니다.

      ====> 없습니다. 적분(개념적으로든 실제로든)없이 가속도에서 무슨 수로 속도를 구하나요...? 단 칼만필터 등을 설계할 때 얼핏 보면 적분하지 않는 것처럼 보일 수 있으나 적분 과정이 들어가 있습니다.

  5. 쁘띠꼬숑 2016.09.27 10:41 신고

    LPF를 파이썬으로 구현해야 하는 생초짜입니다.
    저는 주파수 영역이 아니라 Time domain에서 주파수를 필터링하고 싶은데..
    위에서 언급하신 연속시간영역에서의 1차저역통과필터를 이산시간영역에서 구하기 내용을 적용하면 되는건지요?
    그리고 코드에 대한 설명을 해주시면 진심으로 감사하겠습니다.

  6. 쁘띠꼬숑 2016.10.05 14:24 신고

    질문이 있습니다.
    1. 제가 저역통과필터를 잘 알지 못하는데 만약, 차단주파수가 100Hz라고 하면, -100Hz < freq < 100Hz의 범위에 있는 주파수들을 담는다는 의미인가요?
    2. 위에서 이산시간영역에서의 저역통과필터를 보드선도로 그리셨는데..
    y축은 20*log10(G(freq))이고, x축은 주파수를 log로 표현한듯 한데..

    y축은 필터링된 주파수를 가지고 20log로 계산하고 x축은 raw_freq를 log로 표현한 것인지요?
    보드선도로 어떻게 나타낼 수 있는지 알고 싶어서요..

    • BlogIcon PinkWink 2016.10.09 10:24 신고

      보드선도에 대해서는 약간 다시 보셔야할듯 합니다.
      저역통과필터는 차단 주파수를 기준으로 낮은 영역을 통과시키고, 높은 영역은 차단하겠다는 뜻입니다.

  7. 2016.10.07 09:08

    비밀댓글입니다

  8. 2017.01.20 00:35

    비밀댓글입니다

    • BlogIcon PinkWink 2017.01.20 07:02 신고

      엑셀에서 1차 저역통과필터를 적요한 예제는
      http://pinkwink.kr/741
      에서 다룬적이 있습니다.
      엑셀 데이터를 읽어서 python에서 저역통과필터를 다루고 싶다면 엑셀 데이터를 읽는 법에 대해서는
      http://pinkwink.kr/959
      에서 또한 다루었답니다.^^

  9. 파이초보 2018.01.22 16:29 신고

    안녕하세요.
    최근에 블로그를 알게 되어서 파이썬 기초를 배우는데 큰 도움이 되고 있습니다.
    한가지 궁금한 사항이 있어서 이렇게 댓글을 남기게 되었습니다.
    위의 코드에서 예전에 포스팅 하셨던 출력된 그래프를 .scv 파일로 저장하는 것을 응용해서 코드를 짜고 있는데 **.to_scv('***.scv')
    라는 방식으로 적으면 출력된 그래프의 데이터가 엑셀 파일로 저장될 줄 알았는데 계속해서 오류가 생기는데 왜 그런지 알 수 있을까요?
    파이썬을 처음 공부하는지라 무식한 답변일 수도 있다고 생각이 듭니다. 항상 많은 도움 얻어갑니다. 감사합니다.

    • BlogIcon PinkWink 2018.01.22 21:47 신고

      csv??를 말씀하시는 거겠죠???
      음.. 현재 이 글에서 어느 부분을 csv로 저장하려 하셨나요???

    • 파이초보 2018.01.23 11:20 신고

      네, csv 입니다.
      <Filtered Signal in Discrete>
      그래프 에서 LPF 과정을 거친 후의 데이터를 엑셀파일 형태로 저장하는 것을 응용 중인데 이부분이 잘 모르겠네요.

      그리고 LPF후에 Power Spectral Density를 구하기 위해

      from scipy import signal
      freqs, times, spectrogram = signal.spectrogram(filteredSig1)

      freqs, psd = signal.welch(filteredSig1)

      plt.figure(figsize=(5, 4))
      plt.semilogx(freqs, psd)
      plt.title('PSD: power spectral density')
      plt.xlabel('Frequency')
      plt.ylabel('Power')
      plt.tight_layout()

      plt.show()

      를 추가하였습니다. 이부분까지는 문제가 없는데,
      PSD의 데이터도 저장을 하기 위해 앞서 말씀 드렸던 코드로 값을 저장하려 했더니 오류가 나서 질문 드렸습니다.
      친절한 답변주셔서 정말 감사합니다.

    • BlogIcon PinkWink 2018.01.23 14:15 신고

      코드를 돌려보진 않았지만 csv로 저장하기 전에 저장할 변수의 내용을 한 번 보시죠...
      아마 text가 아닐것 같은데요... 객체일듯합니다만... 그러면 저장이 안될것 같습니다.

    • 파이초보 2018.01.24 11:20 신고

      네! 답변 감사합니다.
      참고해서 공부해야겠네요.

    • BlogIcon PinkWink 2018.01.24 18:45 신고

      바빠서 많은 도움을 못 드렸네요.. ㅠㅠ

  10. 2018.02.06 20:38

    비밀댓글입니다

    • BlogIcon PinkWink 2018.02.07 11:09 신고

      20log10이라는 아이를 사용한 것은 bode선도를 그리는 정의에 따른 것입니다.
      http://pinkwink.kr/927
      에서 설명한 적이 있는데, 입력과 출력의 비율에 log10을 적용하고 20을 곱한 것이 bode선도의 정의라서 그랬습니다^^