「AMG8833」は最高温度でノイズ発生

サーモグラフィー「AMG8833」で体温を検温している時、最高温度に大きなノイズがあることに気づきました。ノイズを除去して一定温度で検温できるように調整しましょう。

最高温度で大きなノイズ

AMG8833で非接触検温を試みています。

検温ではサーモグラフィー上の一番高い温度が人間の体温と仮定します。通常室温が36℃を超えることがないためです。

しかし、そのサーモグラフィー上の最高温度が安定しません。

状況を把握するため、壁に向かって検温し、最高温度をグラフ化して見ます。

120秒間、0.5秒間隔で計測しました。

ただの壁なので温度は一定のはずです。しかし17℃くらいをベースに、頻繁に6℃~8℃くらい温度が高くなるようです。

0℃の時もありますが、これは温度が全く取得できなかった場合で、別の問題です。

サーモグラフィー(色)で温度を確認すると、謎の高温のドットが時々現れています。

どうやらノイズがあるようです。

2番目に高い温度でノイズ低減

今度はAMG8833の64pxの中で2番めに高い温度を取得してみます。

最高温度に比べ、ノイズが小さくなるのが分かります。

この調査時の室温はだいたい20℃です。

10回中央値で温度安定

同じデータを使って、10回計測の中央値でグラフを作成します。

中央値を使えば、突発的な高温や、0℃といった異常値も除外できます。

120秒間、240回測り、最大温度が20.25℃。最小温度が19.5℃。±0.375℃の誤差です。

検温するには許せる誤差範囲でした。

サーモグラフィー「AMG8833」の温度揺らぎをグラフ化

サーモグラフィー「AMG8833」を使って検温できるシステムを作っています。計測すると温度の揺らぎがあり、センサーの特性を理解するため温度データをグラフ化することにしました。

サーモグラフィーの揺らぎを観察

「AMG8833」は、8×8の解像度で温度を取得できます。

ただし、温度の揺らぎが大きいので、キャリブレーションは必要です。

どれくらいの温度範囲で揺らぐか、試しに左上1pxの温度を取得してグラフ化して見ます。

120秒間、0.5秒間隔で計測してみました。

温度が一定の物体を計測しており、理論上はグラフの線が水平になります。

結果を見ると・・・ギザギザ。

まず、温度を取得できず0℃になっていることに気が付きます。

サーモグラフィー(色)で確認しても、上部で温度を取得できないことが、たまにあります。

この0℃については除外する必要があります。

温度の揺らぎは±1℃

240回の取得した温度データの分布を確認します。

15.5℃~17.5からの間、±1℃で、良い形で分布しています。

これなら温度を連続で取得した後、0℃を除外した平均値か、中央値を取得すればよさそうです。

固定の温度計測であれば可能

AMG8833と、計測する物体を動かさないという条件であれば、温度の揺らぎを調整して検温できます。

人間の位置を固定できれば、体温の検温としても使えそうです。

ラズパイ3でも動く顔認識「pico.js」

ラズパイ3のスペックでは、ブラウザのJavaScriptを使って顔認識をすることは難しいです。方法を探ったところ、超軽量の「pico.js」を使えば実現可能でした。

超軽量の顔認識「pico.js」

雑誌の柳井さんでテストしています。0.5秒間隔で顔認識しており、若干追従は遅れますが、ほぼリアルタイムで認識できています。

使っているのは200行のJavaScriptの顔検出ライブラリ「pico.js」です。

200行のコードの中には丁寧なコメントがあり、見やすい改行まであります。実際のコードはもっと短いです。

コードが分かりやすいので、自分の使っているプロダクトに合わせて、組み込んだり、カスタマイズできます。

そして軽量なため、スペックの低いラズパイ3で利用するには最適でした。

サーマルカメラ+顔認識で出来そうなこと

サーマルカメラ開発で顔認識を実装できると、カメラと顔の距離がだいたい分かります。

非接触温度センサーは物体との距離によって計測温度が変わるため、顔との距離が分かればキャリブレーションできます。

他にも、顔の部分だけ温度を取得したり、顔を認識していない間は処理をセーブして節電したりするなど、サーマルカメラをバージョンアップさせられそうです。

引き続き、サーマルカメラのキャリブレーションを行い、ひと段落したところでコードを掲載します。

ラズパイ3のブラウザでface-api.jsは無茶です

ラズパイ3(Model B+)でサーマルカメラを作っていました。カメラで顔を認識する機能を追加しようと思い、face-api.jsを組み込んでみます。しかし、ブラウザが重くなり、操作不能になりました。

ラズパイ3のブラウザでface-api.js顔認識

ラズパイを使って、ブラウザ側のJavaScript主体で開発する人は少ないと思います。しかし、もし同じようなことを試みている人がいれば伝えます。

ラズパイ3でface-api.jsを使うのは無茶です。

近くにあった雑誌に、柳井さんの顔があったので認識してみました。

雑誌なので体温は低いです。

カメラが起動してから1分くらい待てば顔認識できました。しかし、ブラウザがもう反応しなくなるくらい、処理が重くなってしまいます。

45px×30pxの小さな画像で試しても処理は重いため、解像度を低くして解決できる問題ではなさそうです。

ラズパイ3のスペックで、face-api.jsのブラウザ利用は無茶です。無理ではないですが、実用的ではありません。

サーバー側のNode.jsか、Pythonで顔認識は処理したほうが良いと思われます。

しかし、それでもフロント側でやるならば、もっと軽量のJavaScriptを使うと良いでしょう。

Fitbitの睡眠データを自動でスプレッドシートに記録

前回、FitbitのAPIで取得した活動データを、GAS(Google Apps Script)を用いてスプレッドシートに自動で書き込みました。今回は睡眠データの記録です。

GASのコード

スプレッドシートの用意までは、前々回の体重データの書き込みと同じです。

スプレッドシートのシート名は「睡眠」としておきます。

FitbitのAPIは、呼び出すデータや返ってくるデータの違いによって、プログラム調整が必要です。

睡眠データを記録するためのGASコードは下記です。

GASのトリガー設定で、getSleep()をタイマーで毎日実行することで、自動的に記録されます。

Fitbitアプリで睡眠データを同期した後でなければ、記録ができないので注意が必要です。

記録されたスプレッドシート

日付、睡眠時間、目覚めた状態の時間, レム睡眠の時間、浅い眠りの時間、 深い眠りの時間が記録されました。

ただ、睡眠時間を分で見ると分かりにくいです。

データを「時:分」で表示

「時:分」の形式に変換します。

GASから「時:分」形式でスプレッドシートにデータを書き込むように、getSleep()を調整します。

0:${分}でデータを送るように改修しています。

スプレッドシート側の自動変換が賢く、例えば100分は「0:100」という入力で「1:40」に変換されます。

また、睡眠時間は、レム睡眠+浅い眠り+深い眠りの時間が正確なため、修正しています。

睡眠記録は効果的?

今回は検証も兼ね、今年初めて8時間以上寝ました。

8時間寝ると、やはり仕事の作業効率も上がるような気がします。

睡眠データを記録すると、睡眠を客観的に観察できるメリットを感じます。

Fitbitデフォルトの睡眠目標は8時間ですが、毎日継続はちょっと厳しいかもしれません。

7時間くらいをできれば継続して、体調への変化を確認します。

Fitbitの活動データを自動でスプレッドシートに記録

FitbitのAPIで取得したデータを、GAS(Google Apps Script)を用いてスプレッドシートに自動で書き込みます。今回は歩数や消費カロリーなどの活動データの記録です。

GASのコード

スプレッドシートの用意までは、前回の体重データの書き込みと同じです。

スプレッドシートのシート名は「運動」としておきます。

GASのコードは下記を使います。(前回より汎用的にコードを修正しました)

getActivities()をタイマーで実行することで、自動的に記録が始まります。

活動データの記録タイミングは?

1日の活動データの記録が終わるのはデフォルトで深夜0時です。

そのため翌日に記録することになります。

注意しないといけないのは、Fitbitアプリとの同期です。

Fitbitアプリに活動データが同期されていないと、APIから最新データを取得できません。

私の場合は、朝起きてから睡眠時間の確認でFitbitアプリを立ち上げるため、朝一で前日までの活動データが同期されます。

午前中の遅めにGASのタイマーを設定しておけば、正常に活動データを書き込むことができます。

スプレッドシートの記録確認

タイマーでGASが正常に作動していれば、自動でスプレッドシートに書き込まれていきます。

日付、歩数、距離、消費カロリー、アクティブな時間が記録されています。

並べてデータを見ることで、新たな気づきがありました。

11,253歩、歩いた日より、7,016歩で縄跳びを途中やった日の方が、消費カロリーが高いです。

歩数や時間では分からない運動の質も、消費カロリーで把握できるようです。

 

以上、スプレッドシートに自動で活動データを記録する方法でした。

日々記録することで、運動の習慣化にもつながると思います。

Fitbitのスプレッドシート記録をGASで自動化

FitbitのAPIで取得したデータを、GAS(Google Apps Script)を用いてスプレッドシートに書き込みます。毎日タイマーを使って、記録を自動的に行えます。

FitbitのAPIを利用できるように

まずはFitbitのデータを持ってこれるように、APIを利用可能な状態にします。

FitbitのAPIを手っ取り早く試してみる方法」が参考になります。

スプレッドシートとGAS

FitbitのAPIを使えるようになったら、新規のスプレッドシートを作ります。

メニューの「ツール」から「スクリプト エディタ」を選択。

GASのエディタが現れたら、下記のコードを記述します。これは体重を取得してスプレッドシートに書き込むサンプルです。

[token]と[user-id]は自分のID(英数字の羅列)を入れます。

これを実行して、スプレッドシートに体重データが書き込まれれば成功です。

グラフを作っておくと、より変化が分かりやすくなるでしょう。

1日1回タイマーで記録

体重の場合は、1日1回測れば十分です。記録も1日1回タイマーで行います。

スクリプト エディタの左メニューから「トリガー」を選択。

右下の「トリガー追加」を選び、セレクトボックスを下記のように設定します。

  • 実行する関数を選択・・・getFitbitAPI
  • イベントのソースを選択・・・時間主導型
  • 時間ベースのトリガーのタイプを選択・・・日付ベースのタイマー
  • 時刻を選択・・・(好きな時間帯)

体重のように時間帯で変わってしまうものは、午後12時~1時をトリガーにして、午前のデータのみ記録するのも良いでしょう。体重推移が正確に分かります。

Fitbit APIでスプレッドシートに体重を記録(Node.js利用)

Withingsの体重計のデータを、FitbitのAPIから取得することができました。今回は、取得した体重データをスプレッドシートに記録します。

デバイスと環境

体重計・・・Withings「Body +」
活動量計・・・Fitbit「Alta HR」

Windows10
Node.js 14.15.4

スプレッドシートをサーバー化

まずは記録用のスプレッドシートを簡易サーバーとして設定ます。

Google Spreadsheet を簡易 Webサーバーとして動かして、手軽にWebHookを受け取る方法」を参考にしながら、下記のコードを用意しました。

デプロイ時にWebアプリケーションURLが発行されます。

Node.jsでFitbitのAPIを取得

Fitbitの体重データAPIの取得は、Node.jsを利用しました。

Fitbitのトークンと、先ほどスプレッドシートで発行したWebアプリケーションURLを使って、下記のJavaScriptを用意します。

これをapp.jsなどの名前で保存して、コマンドプロントで「node app.js」を実行すれば、スプレッドシートに体重・体脂肪などが記入されていきます。

体重データ取得の注意

Fitbitの体重取得APIで、不思議な結果が返ってくることがあります。

なぜか今日23時59分59秒の体重が返ってきます。まだ朝です。

取得しているデータをNode.jsのログで見てみます。

23時59分59秒に、fat(体脂肪率)がないデータが存在します。fatが記録できないのも問題なので、このデータは除外しましょう。前述のコードでは、fatがない時に1つ前のデータを取得するようにしています。

なぜこのデータが存在するのかは分かっていません。

スプレッドシートの確認

問題なく動作していれば、スプレッドシートに今日の体重が追記されます。

今回作ったNode.jsアプリを1日1回、体重を測った後に実行させると、体重推移を確認できます。

日付と体重の列を指定してグラフを作成すれば、データと連動してグラフも更新されていきます。

Withingsで測った体重をFitbit API経由で取得

WithingsのAPIが一時的に使えません。代案として、WithingsとFitbitを同期させ、FitbitのAPIから体重を取得することにしました。

デバイス

体重計・・・Withings「Body +」
活動量計・・・Fitbit「Alta HR」

※クラウドにデータを保存できれば、別のデバイスでも問題ないと思います。

WithingsのデータをFitbitに同期させる

下記URLで設定すれば、WithingsのデータをFitbitに同期させられます。

https://www.fitbit.com/weight/withings

もし、Withings、Fitbitのアカウントがない場合は作る必要があります。

体重データがFitbitのアプリでも確認できるようになったら、同期はうまくいっています。

FitbitのAPIを利用可能にする

Fitbitで体重データを見られるようになったら、FitbitのAPIを使えるように設定します。

FitbitのAPIを手っ取り早く試してみる方法」で、分かりやすく解説されています。

APIの取得が可能になったら、Fitbit公式ドキュメントの「Body & Weight」で体重を取得する書き方を確認します。

過去30日間の体重データを取得する

コマンドプロント(ターミナル)で下記のコマンドを実行してみます。※[token]、[user-id]、[yyyy-mm-dd]は書き換えてください。

すると最大30日分(存在していれば)の体重データを取得できます。

今朝は測った体重(”weight”:72.8)が、JSONで返ってきました。

Withingsアプリのオリジナルデータと、APIで取得したデータを比べると、正しく取得できていることを確認できます。

体重以外にも、体脂肪やBMI、計測時刻も取得できていました。

動作確認としてはOKです。

次回、スプレッドシートへの記録を行います。

サーバーダウン中?WithingsのAPI

体重管理を始めようと思い、Withingsの「Body+」というネットに接続可能な体重計を使うことにしました。しかし現在、WithingsのAPIが使えない状態のようです。

※追記 2021年2月13日復旧していることを確認しました。

サーバーエラー

WithingsのData APIの使い方を見ると、まずWithings APIに登録が必要とのことです。

しかし、掲載されているリンク先へ移動すると、「Service Unavailable」と表示されてしまいます。

サーバーにエラーが起こっているようで、数分後にもう一度試すよう、促されます。

数分後に試したものの、表示は変わらず、結局翌日確認してもサーバーエラーは改善されていませんでした。

IFTTTでも連携不可

IFTTTを使うと連携できるかも試しましたが、やはりIFTTTとWithingsの接続でエラーがでます。

他、調べてみると、WithingsとFitbitの接続はうまくいくことに気づきました。

こうなったら 一度Fitbitに体重データを同期して、FitbitのAPIを利用することにします。