解析エンジニアの自動化 blog

コツコツと自動化した方法を残す blog

Python で信号のノイズ除去 〜移動平均〜



こんにちは。
仕事の自動化にやりがいと達成感を感じるガッくんです。


この記事の目次



背景・目的


以前の記事で移動平均で波形データのスムージングが出来ることが分かりました。
Python で信号のノイズ除去 〜ローパスフィルター〜 - 解析エンジニアの自動化 blog

下のリンクのローパスフィルターと振幅処理でテストした波形データで試してみます。

Python で信号のノイズ除去 〜ローパスフィルター〜 - 解析エンジニアの自動化 blog

Python で信号のノイズ除去 〜振幅処理〜 - 解析エンジニアの自動化 blog



動作環境


Windows 7
・winpython 64bit 3.4.4



テスト用波形

テストに使用した波形データの仕様を以下に示す。

なお、テスト用波形データはリンクの記事の波形データ作成プログラムにノイズを与えられるように改造して作成しました。

Python で複雑な波形データを作る - 解析エンジニアの自動化 blog


正弦波数:1波
  サンプリング点数:1024点
  サンプリング周期:0.05秒
  正弦波式: A × sin( 2 × π × f × t )
 
正弦波式
 テスト用波形の正弦波の式を示す。
  0.869669428796 × sin( 2 × π × 0.0675797949804 × t )

Wave for Test



プログラム

ソースコード


###############################################################################
# 波形分析プログラム - Waveform analysis program -
###############################################################################
#==============================================================================
# ファイルインポート
#==============================================================================
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt
 
#==============================================================================
# 波形デジタルデータの csv 入力関数
#==============================================================================
def ReadWaveCsv():
   
    #ファイル読み込み ############################################################
    wave = np.loadtxt('C:\\Users\\UserName\\Desktop\\test-wave.csv', delimiter=',')
   
    # wave データの列スライス #####################################################
    time = wave[0:, 0] # time[sec]
    ampl = wave[0:, 1] # amplitude
   
    # グラフ表示 ################################################################
    plt.figure(figsize=(10, 8))
    plt.plot(time, ampl)
    plt.grid(True)
    plt.title('Input Wave')
    plt.xlabel('time[sec]')
    plt.ylabel('amplitude')
   
    # グラフ出力 ################################################################
    file_name = 'Input_Wave.jpg'
    plt.savefig(file_name)
   
    return time, ampl, file_name
 
#==============================================================================
# 移動平均する関数
#==============================================================================
def moving_average(x, y, term):
   
    # カーネル作成 ##############################################################
    kernel = np.ones(term)/float(term)
   
    # 移動平均 ################################################################
    y2 = np.convolve(y, kernel, mode='valid')
    x2 = np.convolve(x, kernel, mode='valid')
   
    # グラフの作成 ##############################################################
    plt.figure(figsize=(10, 8))
    plt.plot(x,  y,  'r--', label='original wave')
    plt.plot(x2, y2, 'k-',  label='moving average term = ' + str(term))
    plt.grid(True)
    plt.title('Moving Average')
    plt.xlabel('time[sec]')
    plt.ylabel('amplitude')
    plt.legend()
   
    # グラフの出力 ##############################################################
    file_name = 'smoothing(moving average term = ' + str(term) + ').jpg'
    plt.savefig(file_name)
   
    return x2, y2, file_name
 
#==============================================================================
# 実用例
#==============================================================================
# 波形の読込
time, ampl, input_wave_name = ReadWaveCsv()
 
# 移動平均
ret_time, ret_ampl, ma_name = moving_average(time, ampl, 20)
 
# グラフ表示
plt.figure(figsize=(10, 8))
plt.plot(time, ampl)
plt.plot(ret_time, ret_ampl)
plt.grid(True)
plt.title('Noise Cleared Wave and Original Wave')
plt.xlabel('time[sec]')
plt.ylabel('amplitude')
 
# グラフ出力
file_name = 'Noise_Cleared_Wave_and_Original_Wave.jpg'
plt.savefig(file_name)



結果

このプログラムから出力されるノイズ入り波形・移動平均波形・ノイズ除去波形とノイズ入り波形の重ね合わせをそれぞれ図1 〜 3 に示します。

図1 Input Wave


図2 Moving Average


図3 Noise Cleared Wave and Original Wave



コメント

単なる平均化なので、ノイズが小さくなってはいるもののノイズ除去波形自体がキレイではありません。

ローパスフィルターや振幅カットなどで処理した方が良さそうです。

移動平均は波形分析手法とはちょっと違う気がしました。



以上