質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

4486閲覧

心電のノイズの除去方法

N.R

総合スコア2

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

プログラミング言語

プログラミング言語はパソコン上で実行することができるソースコードを記述する為に扱う言語の総称です。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/11/11 07:29

編集2020/11/12 09:09

Bitalinoで心電を計測する際に、以下の写真のようにピーク間に規則性のあるノイズが必ず入ってきてしまいます。
以下の写真のようなノイズの大きさであれば、閾値を調整すればよいのですが、このノイズが大きく入ってきた際には心拍数が狂ってきてしまいます。
イメージ説明
イメージ説明
そこで質問なのですが、pythonでこのような規則性のあるノイズを除去する方法を教えていただきたいです。
よろしくお願い致します。

python

1import pandas as pd 2import numpy as np 3import matplotlib.pyplot as plt 4from scipy import signal 5#from matplotlib import pyplot as plt 6 7#データの読み込み 8f = pd.read_csv("file:///C:/Users/81806/.spyder-py3/test-wave11.csv", encoding="utf-8") 9 10N = len(f) 11 12f_x = (f["time"]) 13f_y = (f["ECG"]) 14 15 16f_x2 = [] 17f_y2 = [] 18#グラフ描画 19for i in range(4000,25000): 20 f_x2.append(f_x[i] - 4) 21 f_y2.append(f_y[i]) 22 23plt.plot(f_x2,f_y2) 24plt.show() 25 26 27 28N = len(f) 29fss = 1024 #サンプリング周波数 30dt = 1/fss 31fn = 1/(2*dt) #ナイキスト周波数 32#2Hzのハイパス 33 #'''''''''''ハイパス''''''''''''''''''''''''''''''''''''''''''' 34 35#パラメータ設定 36fp = 1 #通過域端周波数[Hz] 37fs = 20 #阻止域端周波数[Hz] 38gpass = 1 #通過域最大損失量[dB] 39gstop = 40 #阻止域最小減衰量[dB] 40 41#正規化 42Wp = fp/fn 43Ws = fs/fn 44 45#バターワースフィルタ 46n, Wn = signal.buttord(Wp, Ws, gpass, gstop) 47b1, a1 = signal.butter(n, Wn, "high") 48y3 = signal.filtfilt(b1, a1, f_y2) 49n3 = len(y3) 50 51#グラフ描画 52plt.plot(f_x2,y3,"r") 53plt.show() 54 55 56#''''''''''ローパス''''''''''''''''''''''''''''''''''''''''''' 57 58 59#パラメータ設定 60fp = 30 #通過域端周波数[Hz] 61fs = 100 #阻止域端周波数[Hz] 62gpass = 1 #通過域最大損失量[dB] 63gstop = 40 #阻止域最小減衰量[dB] 64 65#正規化 66 67Wp = fp/fn 68Ws = fs/fn 69 70#バターワースフィルタ 71N, Wn = signal.buttord(Wp, Ws, gpass, gstop) 72b1, a1 = signal.butter(N, Wn, "low") 73y = signal.filtfilt(b1, a1, y3) 74N_P = len(y) 75 76#ピーク検出 77fp_x = [] 78fp_y = [] 79fpp_x = [] 80fpp_y = [] 81 82#ピーク検出(心拍) 83for i in range(1,N_P): 84 if (y[i] > 100): 85 if ((y[i] - y[i-1]) > 0 and (y[i+1] - y[i]) < 0): 86 fp_x.append(f_x2[i]) 87 fp_y.append(y[i]) 88 89 90 91 92print('--->>----') 93plt.plot(f_x2,y,"g") 94plt.scatter(fp_x,fp_y) 95plt.show() 96print('--->>----') 97 98#ピークの数を数える 99NPH = len(fp_y) 100NPH2 = len(fpp_y) 101print('心拍センサ上ピークの数',NPH) 102 103f = 0 104h = 0 105a = [] 106z = [] 107beat = [] 108time = [] 109 110while h < len(fp_x)-1: 111 a = fp_x[h + 1] - fp_x[h] 112 z = 60 / a 113 f = f + a 114 beat.append(z) 115 time.append(f) 116 h = h + 1 117#plt.plot(time,beat) 118#plt.scatter(time,beat) 119#plt.show() 120print('心拍') 121print(beat) 122 123plt.plot(f_x2,y,"r") 124#plt.ylim(0,200) 125#plt.xlim(0,20) 126plt.scatter(fp_x,fp_y) 127plt.plot(time,beat) 128plt.ylim(-400,400) 129plt.show()

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ozwk

2020/11/11 08:11 編集

「Bitalino ECG」で検索したところまあまあきれいな心電図が取れるように見えますので 後処理でどうこうするのを考えるよりまず測定に問題がないかを検討してください
N.R

2020/11/11 08:43

回答ありがとうございます。 電極を胸あたりに付けたときにはノイズも入らず綺麗に計測できるのですが、電極シートと手で計測するという形で計測しなければいけないので、この時にノイズが入ってきてしまうという現状です。
toast-uz

2020/11/11 09:18

周期性があるのであれば、ハイパスフィルタとローパスフィルタの組合せで対応可能かもですが、質問者様のコードで試されたように思いました。結果を教えてください。
ozwk

2020/11/11 10:32 編集

本命のパルスの間にパルスが1つあるという形なので、 心拍数を測るだけなら単純に両方のパルスを計数するように閾値を定めて計数を1/2すれば良さそうなもんですが。
thkana

2020/11/11 11:10

「ノイズ」と言っていますが、どれが信号成分でどれがノイズ成分なんですか? 大きな成分の信号はみな同期しているように見えるのですが。心拍に同期しているのなら、「ノイズ」と考えるのはちょっと違うのでは。 (ちょっと心臓を止めてみて、とは言えないですよね...ダミーボディみたいなものがあればノイズだけを捕まえられるのでしょうけれど)
toast-uz

2020/11/11 22:42

ノイズも心拍も、位相が違うだけで周期は一緒なので、パスフィルタやfftでは対処できないのかも・・・ 例えば,心拍数が2倍になって、例示されている心拍〜ノイズの時間差と重なってしまったら、どうするのでしょうか? そういったいろいろなケースを提示していただかないと、できるかどうか含めて、手法の判断がつかないです。
N.R

2020/11/12 09:14

皆様回答ありがとうございます. ECGセンサの計測結果を追加しました. 閾値は100にしています. 電極シートの上を軽く擦る動作が必要になってくるので、2~5秒の間などは波形が乱れている状態です. この乱れた波形をどうにかして消すことはできないのでしょうか? 無知な人間の質問で申し訳ありませんが、ご教授いただければ幸いです.
toast-uz

2020/11/12 10:46

追加されたグラフだと「ノイズに規則性がある」とは読み取れませんし、2~5秒の部分では、元の心拍がほとんど上書きされてしまっているように思います。そもそも、人間の技術者はこれから元の心拍を導き出せるのでしょうか?
thkana

2020/11/12 12:36

> 電極シートの上を軽く擦る つまり、電極の接触状態が変わっているときにもデータが欲しい、ということですか? 例えば走っている車の中でビーカーで水の量を測ろうとして、水面が揺れるのを「ノイズがあるから揺れの分を補正しよう」とか思いますか? やろうとしているのはそういうレベルのことに思えます。
N.R

2020/11/12 20:55

回答ありがとうございます。 自分がいかに無謀な考えをしていたかが、よくわかりました。 本当にありがとうございました。
toast-uz

2020/11/12 22:24

y_waiwai様の回答が正しかった、ということですね
thkana

2020/11/14 23:33

> y_waiwai様の回答が正しかった、ということですね 結果だけ見ればそう言えますね。
guest

回答2

0

そもそものはなしになりますが、元信号を超えるようなノイズは、後処理ではどーあがいても除去できません
考え方から見直したほうがよろしいかと思います

投稿2020/11/11 07:43

y_waiwai

総合スコア87784

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

似たようなことをしたことがあります。対策としてはいくつか。
0. フーリエ変換→ローパスフィルタ→逆フーリエ
そこそこの効果はありますが、今回のように心電波形とノイズが周波数にして10倍の差程度だと厳しいかもしれません。
もちろん落とせるには落とせますが、肝心の心電波形の高周波成分も落とされて波形の形が鈍ると思います。
0. 閾値設定してそれ以下の変動は消し込むという手もあります。心電波形が弱いとそれ自体が消えますが。
0. 完璧に周期的なノイズなら、その正負逆の信号を作ってあげて足し合わせて打ち消すことも可能です。
0. 逆に言うと周期的なノイズの場合は、原因追求してハード面で対応できる可能性が高いですし、それがベストです。

追記

勘違いしていました。緑線の画像でいうと、大きいほうがノイズですかね?(横軸は秒でいいんですよね?)
仮にそうだとすると、ノイズの方が周波数低い・信号大きいということですね。多分、呼吸時のノイズだと思うのですが、そうすると下記のような対策になるかもしれません。
・ 呼吸時(閾値超えている信号が出ている間とか、別のセンサで呼吸判定するとか)は信号を無視して使わない。ノイズが出ていない間のデータだけ計測に使う。
・センサを呼吸の影響の小さい部位につける。腕とか脚とか。

投稿2020/11/12 23:50

編集2020/11/13 00:15
jeanbiego

総合スコア3966

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問