近頃、新型コロナウイルスの影響で職場や学校、施設に入るときなど、体温測定が日常化している人も多い世の中になってきました。
ただ毎回体温を測るのは時間がかかることや、測定するのを忘れてしまう人もいるのではないでしょうか?
今回はそんな体温測定をRaspberry Piを活用して、人を認識したら体温測定できるように挑戦してみようと思います。

チャレンジ&ナレッジ最終更新日: 20210112

Raspberry Piと温度センサーで体温を測る

  • このエントリーをはてなブックマークに追加

Raspberry Piと温度センサーを組み合わせると、簡易的な体温測定機器として利用することが可能です。 今回はRaspberry Pi 4と温度センサー人を認識したら体温が測定できるプログラムを組んで動かしてみたいと思います。

サーモセンサーAMG8833の接続準備

今回体温測定に使う外部センサーは、AMG8833というサーモセンサーです。
解像度は8×8、0〜80度まで測定可能のセンサーとなっています。

Raspberry Pi4とセンサーを接続するために、それぞれの端子を指定された箇所に接続します。

基盤に名称が書いてあるので、下記を参考にしながら接続してください。

AMG8833(3.3v) → Raspberry Pi (3.3V)
AMG8833(GND) → Raspberry Pi (GND)
AMG8833(SDA) → Raspberry Pi (SDA)
AMG8833(SCL) → Raspberry Pi (SCL)

しっかりと端子に接続しないと、誤認識や認識が不安定になるので外れないように接続します。

Raspberry Pi側の設定

Raspberry Piの電源を入れ設定します。起動したら画面左上部のラスベリーパイアイコンをクリックして、Raspberry Piの設定開きます。

「インターフェイス」のタブ開いて、そのなかの「I2C」の項目が有効になっているかどうかを確認します。無効になっていた場合は有効に変更します。

ここで、先ほどRaspberry Piに接続したサーモセンサーが正常に読み取れるか確認するために、「ターミナル」を開いて、下記のコマンドを実行します。

sudo i2cdetect -y 1

正常にセンサーが接続されてる場合は下図のように「68」が表示されています。
もし表示されていない場合は、しっかり接続できているか確認してください。

無事に接続されてるのが確認できたら、次はサーモセンサーを制御できるように外部からドライバーをダウンロードします。
下記のコマンドを実行します。

sudo pip3 install adafruit-circuitpython-amg88xx

ここまでで、正常にセンサーが動作しているのかをプログラムを書いて確認します。

作業ディレクトリーの中に、新しいファイルを作成して下記のソースコードを書いてください。

import time
import busio
import board

import adafruit_amg88xx

# I2Cの初期化
i2c = busio.I2C(board.SCL, board.SDA)
# サーモセンサーの初期化
sensor = adafruit_amg88xx.AMG88XX(i2c, addr=0x68)

# 初期化のために待つ
time.sleep(0.2)

# 8x8の温度配列
print(sensor.pixels)

プログラムが用意できたら下記のコマンドを実行します。

python3 thermo1.py

実行すると、ターミナル上に「8×8ピクセルの配列」が表示されます。
センサーの部分に手をかざすことで、数値が変化していくのが確認できます。

取得したデータをOpenCVで表示してみる

次に先ほど表示した8×8ピクセルの配列をOpenCVを可視化させます。
Raspberry PiにOpenCVのインストールをしていない場合は、下記のコマンドを実行してOpenCVをインストールしてください。
最初にOpenCVに必要なライブラリーのインストールを行います。
下記のコマンドを一行ずつ実行してください。

    sudo apt-get install libhdf5-dev libhdf5-serial-dev libhdf5-100
    sudo apt-get install libqtgui4 libqtwebkit4 libqt4-test 
    python3-pyqt5sudo apt-get install libatlas-base-dev
    sudo apt-get install libjasper-devsudo pip3 --default-timeout=1000 install opencv-python

次にOpenCV本体をインストールします。

sudo pip3 --default-timeout=1000 install opencv-python

次に大量のデータ処理をするために数値計算の時間を短縮するプラグインをインストールします。

sudo pip3 install numpy

必要なプラグインがインストールができたら、プログラムを作成するために、ファイルを作成して下記のプログラムを書きます。

import cv2 as cv
import numpy as np

import time
import busio
import board

import adafruit_amg88xx
import colorsys

# I2Cの初期化
i2c = busio.I2C(board.SCL, board.SDA)
# サーモセンサーの初期化
sensor = adafruit_amg88xx.AMG88XX(i2c, addr=0x68)

# 初期化のために待つ
time.sleep(0.2)

# 表示のための配列を用意する
img = np.full((320, 320, 3), 128, dtype=np.uint8)

# セルサイズ
cellsize = 40

def hsv2rgb(h,s,v):
    return tuple(round(i * 255) for i in colorsys.hsv_to_rgb(h,s,v))

def mapVal(val, inMin, inMax, outMin, outMax):
    return (val - inMin) * (outMax - outMin) / (inMax - inMin) + outMin

# 8x8の温度配列
pixels = sensor.pixels
for x in range(len(pixels)):
    for y in range(len(pixels[0])):
        # 15〜28の値を、270〜0の範囲に変換する
        val = mapVal(pixels[x][y], 15, 28, 270, 0)
        # 値を0〜270の範囲に収める
        val = min(max(0, val), 270)
        # HSVで指定した色をRGBに変換する
        color = tuple(reversed(hsv2rgb(val/360, 1.0, 0.5)))
        # 1ピクセルずつ表示する
        cv.rectangle(img, (x*cellsize, y*cellsize), (x*cellsize+cellsize, y*cellsize+cellsize), color, thickness=-1)

# 結果の画像を表示する
cv.imshow('image', img);
# 何かキーが押されるまで待機する
cv.waitKey()

# 表示したウィンドウを閉じる
cv.destroyAllWindows()

ファイルを保存して下記のコマンドを入力してプログラムを実行します。

python3 thermo2.py

実行すると、OpenCVによってサーモカメラから取得した数値を画像として表示されるようになりました。

色が赤くなるほど、サーモカメラから取得した数値、つまり温度が高いことを表しています。

手を覆うなどして、色が変化するのを確認してください。

人を認識したら検温する

次にUSBカメラを接続して、映像を表示しつつ、人を認識したら体温を測定できるようにします。
USBカメラは市販で売られているカメラを使います。Raspberry Piに接続します。

次に人を認識させるために、OpenCVであらかじめに用意されている人の顔が含まれる画像の特徴をまとめたデータ(カスケード分類器ファイル)を準備する必要があります。

細かい手順は下記の記事にまとめてあるので、確認してください。
https://www.pc-koubou.jp/magazine/19205

カスケード分類器ファイルは、フォルダーでまとめられているので、フォルダーごとコピーして設置します。

今回使うのは「haarcascade_frontalface_default」ファイルです。

カスケード分類器のファイルを準備ができたら、次に下記のプログラムを書いてファイルを保存してください。

import time
import numpy as np
import cv2 as cv

import busio
import board

import adafruit_amg88xx

i2c = busio.I2C(board.SCL, board.SDA)
sensor = adafruit_amg88xx.AMG88XX(i2c, addr=0x68)

time.sleep(0.2)

# カメラ初期化
cap = cv.VideoCapture(0)

# 顔の分類器の作成
faceCascade = cv.CascadeClassifier('haarcascades/haarcascade_frontalface_default.xml')

while True:
    ret, frame = cap.read()
    h, w, c = frame.shape

    # カメラの画像を半分にする
    gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)

    # 顔の認識
    facerect = faceCascade.detectMultiScale(gray, scaleFactor=1.2, minNeighbors=6, minSize=(1, 1))

    if len(facerect) > 0:
        for rect in facerect:
            # 配列のスライス→ rect[開始位置:終了位置] rect[0:2]→[左上X座標, 左上Y座標]
            cv.rectangle(frame, tuple(rect[0:2]), tuple(rect[0:2]+rect[2:4]), (0, 0, 255), thickness=2)
        
        max_temp = 0.0
        # 8x8の温度配列
        pixels = sensor.pixels
        for x in range(len(pixels)):
            for y in range(len(pixels[0])):
                # 最大温度を格納する
                if (pixels[x][y] > max_temp):
                    max_temp = pixels[x][y]
        
        print('人を検知しました: '+str(max_temp))

    cv.imshow('camera capture', frame)

    # ESC
    if cv.waitKey(1) == 27:
        break

cap.release()
# 表示したウィンドウを閉じる
cv.destroyAllWindows()

ファイルの保存ができたら、プログラムを実行します。
下記のコマンドを実行してください。

python3 thermo3_face

実行すると、USBのカメラからの映像が出力されます。
カメラの映像内に顔が認識すると、赤い枠が表示されターミナル上にサーモカメラセンサーの8×8内の最大温度が表示されています。

Raspberry Piでサーモカメラセンサーを使って体温検出

今回は、サーモカメラセンサーで実際に人を認識すると体温検出するまでをチャレンジしてみました。
さらに精度を高くする場合は、他のセンサーを使うことを考える必要がありますが、人を認識するたびに検温することができるため、職場などのオフィスに置き、ざっくりとした検温システムとして動作させることができそうです。
すでに Raspberry Pi を防犯カメラとして動作させている場合は、追加機能として実装することもできるので、組み合わせてみるのも面白いと思います。

ライタープロフィール 合同会社 4D Pocket
石郷祐介

大学卒業後、公設研究機関勤務を経て、「情報科学芸術大学院大学[IAMAS]」に入学。
専門学校講師を経て、企業の研究開発をコンセプトから開発まで支援する「合同会社4D Pocket」代表、エンジニアを養成するフリースクール「一般社団法人HOPTER TECH SCHOOL」代表理事、「名古屋文理大学」及び「名古屋造形大学」非常勤講師。

記事を
シェア