• 締切済み

matlabでのRRI検出

今研究で、睡眠時のストレスを検出するために、測定から得られた心拍データからRRIを読み取ることを考えています。 http://www.mental-plus.jp/heartcoherence.html このサイトにある、脈と脈の間隔がRRIとなっています。 自分の実験ではサンプリング間隔1msごとにデータを採取しています。 R-2000という機械を用いて、1msごとの心拍を電圧であらわしたものを エクセルに書き込んでいて、そのエクセルをマトラボで取り込んで マトラボで心拍のグラフの表示までは出来ています。 ここからRRIの検出を行いたいのですが、心拍の1つ1つの波形の山のピークを検出するにはどうすればよいのでしょうか?

みんなの回答

  • sgwjn
  • ベストアンサー率70% (47/67)
回答No.2

このような場合であれば、閾値か相関を使用するのが一般的だと思います。 閾値を使用する場合に最も単純なのは、ある閾値を決め、それ以上(または以下)のデータ群を取得し、連続するデータ群の最大振幅をピークとして取得する方法だと思います。 一定の値で上手く山が取れない場合は、移動平均などを閾値として使用すると良いでしょう。 ただし、この方法では連続したデータ群の中でのピーク位置がマチマチになってしまいます。 例えば、質問の添付画像の右上のように頂点が平坦な場合、ピーク位置が山ごとに前方・後方にバラつくと、正確なRR間隔を取得できません。 それが気になる場合は、テンプレートとなる波形を用意し、相関を使用すると比較的バラつきの少ない結果になると思います。

  • kirinoma
  • ベストアンサー率53% (288/542)
回答No.1

めちゃくちゃ単純にやるなら,データを先頭から読んでいって, 増加から減少に転じるところをピークとすれば良いのかな.いわゆる山登り法です. (山を効率的に見つけるアルゴリズムを研究しているのではなく, あくまで,手間を掛けないで山の位置を知りたいだけなのですよね?) 「実はピークには平らなところがあるのだ」とか, 「閾値pを手動で決めることが出来ない(状況・個人差でまちまち)」の場合はもっと ちゃんとやらないと駄目ですね. ・detectPRI.m function detectPRI(); % 山登り法でピーク位置を検出するよ! length = 100; % 心拍データの長さ(ms) p = 0.7; % 閾値(mv.任意.これより小さい値のピークがあっても無視する) beat_data = rand(1,length); % エクセルからデータを読み込んで配列に格納する関数.ダミー(rand関数を使ってます)です. peaks = zeros(1,length); % ピーク位置記憶用 x_lim = 1:length; % データのプロット用 for n = 2:length-1 if beat_data(n) > p && beat_data(n-1) < beat_data(n) && beat_data(n) > beat_data(n+1) peaks(n) = beat_data(n); end end plot(x_lim,beat_data,'g-',x_lim,peaks,'ro'); % 波形(緑線)と検出ピーク位置(赤丸)の表示 % End of file

pusuke1212
質問者

お礼

山として検出されたデータのx方向の成分を隣同士の成分の差をとることでピーク同士の距離を調べ、その値が一定値よりも低い場合を1つの塊とみなすことで、うまく作ることができました。 回答のほうありがとうございました。大変助かりました

pusuke1212
質問者

補足

御解答ありがとうございます。 kirinomaさんの通りにやってみたところ、山の検出をすることができました。ただ、山の先端は実際はノイズの影響か、先端を拡大してみるとギザギザと微小な山がいくつも出来ていて、1つの心拍の山に対して、複数の山として検出されてしまいました・・・・ これをどうにか1つの山として検出して、1つ1つの山の時間の間隔RRIを検出し、RRIの平均を出すのが目的としています。 先ほどのプログラムに少し改造を加えなければならないのですが、 peaks(t1)と、次に検出されるピークのpeaks(t2)として、t1とt2の間隔が一定より小さい場合はpeaks(t2)の値を格納しないなどとすればよいのでしょうか・・・・・ 無論自力でもがんばりますが、もしよろしければ先ほどのようにわかりやすいプログラム例をあげてもらえると助かります

専門家に質問してみよう