2018年10月26日 更新

筋肉の電気信号・筋電位の識別 Part 2

前回は筋電位の計測し,どういった信号なのかを確認しました. 今回は計測結果を元にchainerを用いてニューラルネットワークで手の姿勢を識別しました.

5,157 view お気に入り 0

はじめに

前回の計測では筋電位センサでじゃんけんの時の筋電位を計測しました.
今回は計測した筋電位から手の姿勢を推定できるか,chainerを使って検証してみます.

筋電図の特徴量

こちらの論文では8つの手動作姿勢の識別にどの特徴量を用いるのが良いか検証しています.
https://www.jstage.jst.go.jp/article/kikaic/79/808/79_4746/_pdf
検証している特徴量は以下の通りです.
 1.生データ
 2.積分筋電位(IEMG)
 3.最大成分周波数(FFT Peek)
 4.パワースペクトル
 5.立ち上がり筋電位
 6.ウェーブレット係数
SVMを用いて識別をしていますが,IEMGを特徴量として用いた時が最も高い識別率を示しています.
この記事ではパワースペクトルを特徴量として識別してみます.

データセットの作成

計測条件と計測箇所は前回と同様です.
FFTの条件
・サンプリング数 256
・オーバーラップ数 64
・窓関数 ハミング窓
3つのセンサのパワースペクトルから成るベクトルと姿勢ラベルを1セットとすると合計で225セット.
データセットの作成のコーディングに手間を取ったのでプログラムを載せておきます.
    # データセット 学習データ(パワースペクトル)*センサ数+ラベル(姿勢)
    emg_dataset = np.empty((SAMPLING_N // 2 + 1) * SENSOR_NUM + 1)

    for posture in range(POSTURE_NUM):
        pyplot.figure()
        data_csv = pd.read_csv("emg" + str(posture) + ".csv", header=None)
        # 時刻ごとのFFT
        index = 0
        while index + SAMPLING_N < data_csv.shape[0]:
            amp_array = np.empty(0)
            # センサごとのFFT
            for i in range(SENSOR_NUM):
                emg = data_csv[i].values[index: index + SAMPLING_N]
                # フィルター処理
                emg = signal.detrend(emg)
                emg = np.convolve(emg, np.ones(10) / 10.0, mode='same')
                # 窓関数
                window = np.hamming(SAMPLING_N)
                f = np.fft.fft(emg * window)
                amp = np.abs(f)
                amp = amp[0: SAMPLING_N // 2 + 1]
                amp_array = np.append(amp_array, amp)
            # ラベルとして姿勢を登録
            label = posture
            amp_array = np.append(amp_array, label)
            emg_dataset = np.vstack((emg_dataset, amp_array))
            index += SAMPLING_N // 4

    emg_dataset = np.delete(emg_dataset, 0, 0)
    # 配列並び替え
    np.random.shuffle(emg_dataset)

    train_data = emg_dataset[:, 0: emg_dataset.shape[1] - 1].astype(dtype=np.float32)
    label_data = emg_dataset[:, emg_dataset.shape[1] - 1: emg_dataset.shape[1]].T.astype(dtype=np.int32)
    label_data = label_data[0]

    # 学習データの教師データとテスト用データに分ける
    threshold = np.int32(emg_dataset.shape[0] * 9 / 10)
    train = tuple_dataset.TupleDataset(train_data[0:threshold], label_data[0:threshold])
    test = tuple_dataset.TupleDataset(train_data[threshold:], label_data[threshold:])
一次元ベクトルのデータセット.py
訓練データとラベルは別に扱いますが,データをランダムに扱うために
まずは学習データの最後にラベルを追加して,シャッフルし,その後分離しています.

ニューラルネットワークの作成

使用したニューラルネットワークは以下の通り.
入力層 129x3次元
中間層 512
出力層 3次元
重み決定法 確率的勾配法
学習回数 200

結果!

NNの損失

NNの損失

学習するに連れて学習データ,テストデータ共に誤差が小さくなっていることが確認できます.
ちなみに識別率は100%を達成しました.

まとめ

16 件

関連する記事 こんな記事も人気です♪

電気刺激装置で筋トレ

電気刺激装置で筋トレ

画像脈拍計測を予定していましたが,上手く計測できていないのでコンテンツを変更しました. この記事では筋肉に電気で刺激しています.
栢菅 宏規 | 1,764 view
画像で脈拍計測 Part1

画像で脈拍計測 Part1

PCのWebカメラを用いた脈拍計測の準備として,顔画像のRGBの取得までを行いました
栢菅 宏規 | 4,032 view
脈拍でストレスを検出する

脈拍でストレスを検出する

前回計測した脈拍を利用して,自分のストレス状態を検出してみました.簡単なアルゴリズムで実装でき,脈拍以外に心電図なのでも同様な検出系を作ることができます
栢菅 宏規 | 14,410 view
お手軽な脈拍計測

お手軽な脈拍計測

指から自分の心拍数を計測してみました. Androidで計測するつもりでしたが,不具合があったためセンサを製作しました.
栢菅 宏規 | 4,163 view
筋肉の電気信号・筋電位の計測

筋肉の電気信号・筋電位の計測

じゃんけんの姿勢を筋電位で計測して,識別できるか検証します
栢菅 宏規 | 6,314 view

この記事のキーワード

この記事のキュレーター

栢菅 宏規 栢菅 宏規