サーマルカメラ「AMG8833」+「OV5640」

前回Webカメラとサーモグラフィーのセンサーが干渉する問題が起こりました。干渉を極力避けるため、小さなWebカメラモジュール「OV5640」を用いて、サーマルカメラを作ることにしました。

動作サンプル

手を使ってサーモグラフィーとWebカメラの映像の重なりを確認します。

サーモグラフィーのフレームレートを低く設定しており、カメラ映像に遅れてサーモの色が重なります。

遅れ意外、映像の重なりは問題ないように感じます。

※掲載していませんが、人間を映すと、人の顔にサーモが追従してくれます。

Webカメラ見直し

映像とサーモグラフィーを重ねるため、できる限りWebカメラとサーモグラフィー「AMG8833」のレンズの距離を近づけたいです。

そこで、Webカメラの基板とカメラが分離したタイプの「OV5640 USBカメラモジュール」を使うことで、干渉を最小限に抑えることを考えました。

カメラマウントを3Dプリント

「AMG8833」のレンズとWebカメラをはめるカメラマウントを3Dプリントします。

ゴムのようなTPU素材で3Dプリントすると、ちょっとくらいサイズが違っても伸縮してカメラがはまります。

家にあったクリップと合体します。

ディスプレイの上に挟んで、サーマルカメラになりました。

まだ若干、干渉を受けて温度が安定しないような気がしますが、キャリブレーションで何とかなるか?

次回、検温に使っているコードを記載します。

検温に影響「AMG8833」の取り付け位置に注意

前回まで作っていた検温用サーモグラフィー。カメラを増設しようと改修していたら、問題が発生しました。体温が低く表示されてしまいます。どうやら「AMG8833」の設置場所で温度が変わってしまうようです。

Webカメラと「AMG8833」が干渉?

サーモグラフィーとカメラ映像を重ねるには、サーモグラフィー「AMG8833」のレンズとWebカメラのレンズを極力近づけたほうが良いです。

Webカメラはロジクールのc270n(諸事情で、カバーを取って基板むき出しの状態)を使っています。

仮止めでWebカメラと「AMG8833」を合体させ、サーマルカメラとしました。

そして検温すると・・・体温が31℃?プログラムで補正しているので実際は人肌を22℃と認識しています。

温度のブレも大きく、数値が安定しません。

カメラを併設したことによる電流不足を疑いましたが、カメラを外しても検温が安定しません。

「AMG8833」の設置場所が影響しているようです。

ディスプレイとも干渉

今度は、Webカメラと「AMG8833」を離して、ディスプレイに取り付けてみました。

少し改善されましたが、体温はまだ低く表示されています。

「AMG8833」の裏側のディスプレイが干渉しているのでしょうか?

干渉しない場所に「AMG8833」を移動

ディスプレイの下に「AMG8833」を移動することで、ようやく検温が安定してきました。

「AMG8833」は周囲にあるもので、検温結果に影響があるようです。

熱源か電磁波が影響?

「AMG8833」をラズパイのプラスチックケースに取り付けても、検温温度が6℃くらい下がってしまう現象が起きました。

ただのプラスチックに取り付けた場合、この現象は起こらないため、熱源か電磁波が影響するのかもしれません。

Webカメラ、ディスプレイ、ラズパイの発する何かが、検温に影響している可能性はあります。

「AMG8833」の設置場所には注意が必要です。

次回、干渉に注意しながらサーマルカメラを改善します。

余談:ラズパイ用カメラモジュールが使えなかった

最初、Webカメラではなく、ラズパイ用カメラモジュールを使おうとしていました。

・・・しかし、ラズパイのカメラ機能は有効なのに、カメラを認識せず。

原因は自分か、カメラか、ラズパイか特定できません。

あきらめてUSBのWebカメラに切り替えたら、簡単に認識してくれました。

ハードで問題が起こったら、原因特定が難しいので、別の方法に切り替えて進めるのも良いかもしれません。

サーモグラフィー「AMG8833」で非接触検温

前回「AMG8833」で温度を計測できるようにしました。ただ、対象物までの距離によって温度が変わってしまうので、このままでは人の検温に使えません。今回は一定距離を保って検温できる仕組みを作ります。

動作サンプル

シルエットに顔を合わせると、検温できます。

近すぎると高温になってしまうため、「はなれて!」と警告文がでます。

シルエットで距離を保つ

「AMG8833」で検温した場合、距離によって温度が変わってしまいます。

この問題を解決するには、距離センサーを併用して補正するか、人が動かないようにするか、どちらかです。

簡単な後者にします。

シルエットの枠を用意して、その枠に収まる距離のところでじっとします。

単純に床にラインテープを貼っても良いでしょう。

距離が一定なら、温度の補正もしやすいです。

自分の体温を別の体温計で測り、「AMG8833」で測った温度を補正して同じ値になるようにします。

37℃以上でアラート

もし37℃以上だったら、アラートが出るようにします。

画面が赤くなるようにしました。

効果音を付け加えても良いかもしれません。

距離が近すぎたら「はなれて!」

センサーが取得した8×8の温度データの中に、体温と思われる画素が多い場合は近すぎるということです。

「はなれて!」と警告文を出します。

検温に使ったコード

開発環境、サーバー側のコードは変わっていません。HTMLのみ下記コードに改修しています。

80行目のlet calibration = 9;が、体温の補正値です。

私の環境では約9度低く出るので、+9度補正しています。

センサーまでの距離に応じて、調整が必要です。

続いて、サーモグラフィーとWebカメラの映像を重ねる予定ですが、先に解決しないといけない問題が発生しました。

「AMG8833」でブラウザに温度を表示

前回は非接触温度センサー「AMG8833」を使い、サーモグラフィーを作りました。今度はセンサーが捉えたものの温度を計測できるようにします。

動作サンプル

まずはモルモットを検温。

・・・逃げてしまいました。

今回作ったサーモグラフィーでは、検温に5秒程度かかってしまいます。

動いている動物では難しいので、静物で実験します。

温めたおにぎりが39.8℃、氷水が0.3℃。

センサーに映したものの中で、一番高い温度を表示しています。

検温に使ったコード

開発環境、サーバー側のコードはこちらをご確認ください。HTMLのみ下記コードに改修しています。

10回計測して、温度の中央値を表示する仕様です。

体温を調べたい

「AMG8833」を人間の検温に使いたいと思う人は、今のご時世多いかもしれません。

通常、人間の体温は周囲より高いため、「AMG8833」を人間にかざした場合、最も高い温度を体温として取得すればよいでしょう。

実際に自分にセンサーを向け、0.5秒ごとに体温を測ってみました。

若干低めですが、検温はできます。ただ、2つ問題がありました。

体温が安定しない

一つ目の問題。恒温動物である人間が、突然38℃になったり、30℃になったり、頻繁に異常値がでます。これに関しては10回取得した温度の中央値を取ることで解決しました。

中央値を使うことで、異常値を除外できます。

例えば、10回計測した温度が[35,35,34,34,38,35,34,38,35,35]だった場合、35℃が中央値になります。平均値と違い、38℃の影響を受けません。

距離によって体温が変わる

もう一つの問題は、距離によって温度が変わることです。センサーと人との距離が近いほど温度が正確になるようです。

そのため、おでこにセンサーをかざして検温すると、より正確な体温を知ることができます。

しかし、それではサーモグラフィーの意味がない・・・「AMG8833」の64の解像度はいらないです。

サーモグラフィーを生かすため、次回、離れた場所で正確に検温できるように調整します。

「AMG8833」でサーモグラフィーをブラウザに表示

非接触温度センサー「AMG8833」を使い、サーモグラフィーをブラウザに表示します。8×8の温度配列を、canvasで描画し、CSSで拡大しています。

「AMG8833」の温度データをブラウザで読み込む

「AMG8833」をラズパイに繋いぎ、非接触で温度を確認します。

開発環境やサーバー側(node.js、Python)は、前回の記事をご確認ください。

今回はフロント側、HTMLのみ書き換えます。

8×8のサーモグラフィーをcanvas描画

「AMG8833」で取得した8×8の温度配列を、canvasでサーモグラフィーのように描画します。

8×8のcanvasを用意して、1pxずつ色を塗ります。

温度によって色を変えるには、hslで色指定をすると簡単です。

h(色相)を温度が高いほど0(赤)。低いほど250(青)に近づけます。

色相環になっているため、hが250を越えていくと赤に近づいき、逆にhがマイナスになると青に近づいてしまいます。

hの値は0~250からはみ出ないように制限は必要です。

これでちっちゃいですが、サーモグラフィーをcanvasで描画することができます。

ブラウザでバイキュービック補間

「AMG8833」の解像度は8×8しかありません。これをブラウザ標準のバイキュービック補間を使って、滑らかな画像にします。

単純にtransform: scale(30);を指定して、30倍にしています。

すると、ブラウザ側で滑らかに補完してくれます。

OpenCVでもできますが、CSSで行うのが最も軽量で簡単だと思います。

最終的なコード

「検温!」ボタンを押したら、0.5秒おきにサーモグラフィーが更新されていくようにしました。

次回、サーモグラフィーと合わせて体温を表示するように改修します。

「AMG8833」の温度データをブラウザで表示

サーモグラフィー「AMG8833」で取得した温度データをブラウザで表示します。ブラウザまで持ってくれば、Web系の制作者にとって視覚化が簡単になります。

開発環境

ハード

Raspberry Pi 3 model B+
スイッチサイエンス「AMG8833」モジュール

ソフト

OS:raspbian 10.7
Python 3.7.3
Node.js 10.21.0
Chromium 86

検温ボタンで温度配列取得

今回は、ラズパイの標準ブラウザChromiumで、「検温!」ボタンを押した時、Consoleに8×8の温度配列を表示するところまで進めます。

処理の流れとしては、

HTML→Node.js→Python→センサー→Python→Node.js→HTML

・・・と、なかなか遠回りです。しかし、HTMLまでセンサーデータを持ってくれば、Web系の人にとっては自由度が増すでしょう。

ディレクトリ構造

htdocs/
┗thermal-camera.html(検温ボタンのあるHTML)
python/
┗amg8833.py(センサー値を取得するPython)
app.js(サーバーとなるNode.js)

app.js(Node.js)のコード

Node.jsはExpressを使い、Webサーバーとして立てます。

HTMLとはsocket.io(Websoket)でデータをやり取りし、PythonとはPythonShellでデータをやり取りします。

Pythonから受け取ったセンサーの配列が文字列となるので、JavaScriptで配列データに変換しています。17行目からがその処理です。もっと簡単な書き方があるかもしれません。

PythonShellで実行している「python/amg8833.py」のコードは下記になります。

amg8833.py(Python)のコード

AMG8833センサーにアクセスし、8×8の温度配列データを出力します。

この出力結果が、node.jsに渡ります。

thermal-camera.html(HTML)のコード

最後にブラウザに表示するHTMLです。

「検温!」ボタンをクリックすると、Websocketで「thermal」というメッセージをNode.jsサーバーに渡します。

それをトリガーにして、温度取得が始まり、取得完了後にデータがまたWebsocketで戻ってくる仕組みです。

次回、canvasとCSSで、サーモグラフィーを作ります。

「AMG8833」をラズパイで使う

ラズパイ(Raspberry Pi 3 model B+)にサーモグラフィー「AMG8833」を取り付けました。もしobnizに取り付けようとして苦戦している場合、ラズパイに切り替えるのも手だと思います。

スイッチサイエンスのAMG8833

スイッチサイエンスで売られていたAMG8833搭載のモジュールを購入。

もともとはobnizで使う予定でした。

しかし、obnizのパーツライブラリでAMG8833については、「Adafruit社製以外のモジュールを使用する場合は注意してください。」とのことです。

スイッチサイエンスのモジュールは少し違い、センサー知識なしで使おうとするとハードルが高いです。

センサーを壊すと悲しいので、安全にラズパイを使います。

センサーの配線とデータ取得

このセンサーの使い方は、「RaspberryPiで赤外線アレイセンサAMG8833(Grid-EYE)からデータ取得」を見ると、完璧に分かります。

温度データ8×8の配列を、取得することに成功しました。

次回、このデータをブラウザで読み込みます。

簡略化!モルモット・スマートホーム 2.0

自宅でモルモットの温度管理にIoTを導入しています。しかし、目の前のホットカーペットの電源を入れるのに、アメリカと中国を経由する地球規模の仕組みは必要なのでしょうか?簡略化して再構築します。

今までのモルモット・スマートホーム

Webサービス連携の「IFTTT」とスマートプラグ「Meross」を使って、モルモット・スマートホームを運用していました。

室温が下がったら、ホットカーペットの電源を入れる。

ただそれだけの仕組みなのですが、アメリカと中国を経由しているようです。正確にはどこのサーバーを経由しているのか分かりません。

リレー回路でシンプルにする

モルモット・スマートホームを見直します。

ホットカーペットの電源をリレー回路でONにすることにしました。

室温に応じて電源のON/OFFを切り替えるくらいであれば、本来はインターネット不要です。

ただ、開発速度や管理のしやすさを考え、obnizは利用し続けることにします。

加湿器を追加する

簡略化したら、設備追加したくなりました。湿度も管理できるように、加湿器を接続できるにします。

ホットカーペットと加湿器、2つの家電をリレーで制御します。写真では動作テストのため、スマホのブラウザで家電を操作しています。

実際は温度センサーを取り付けて、家電の電源管理を自動化します。

温度・湿度センサー取り付け

温度・湿度センサー「SHT20」を使うことにしました。

2つのリレーとSHT20、obnizへの接続は下記です。

IO 0・・・リレー1と2 GND
IO 1・・・リレー1と2 VCC
IO 2・・・リレー1 SIG(ホットカーペットのON/OFF)
IO 3・・・リレー2 SIG(加湿器のON/OFF)
IO 4・・・SHT20 GND
IO 5・・・SHT20 VCC
IO 6・・・SHT20 SDA
IO 7・・・SHT20 SCL

モルモット・スマートホームのコード

配線が完了したら、HTMLのJavaScriptで、スマートホームを運用します。ラズパイでブラウザを立ち上げっぱなしで運用している状態です。

18℃未満でホットカーペットの電源ON。

湿度40%未満で加湿器ON。

これで、アメリカや中国のサーバーがダウンしても、モルモットは快適な生活が送れるでしょう。