서모 센서를 라즈파이에 연결하여 검온해 보았다 (Python)

용도



어떤 제작으로 비접촉 검온을 시스템에 통합하게 되었으므로, 라즈파이 + 서모 센서를 사용하여 실장했습니다. 소지 형식이 아니라, 거치형의 이미지입니다.

※ 먼저 말해 두면, 거기까지 정밀도는 높지 않고, 오차도 경우에 따라서는 1번 정도 생기는 경우가 있습니다. 하지만, 원래 비접촉형의 검온기는 거기까지 정밀도 높지 않은 인상이고, 뭐 이런 것일까라고 생각하고 사용하고 있습니다. (오차에 관해서는, 자신은 복수회 검온하고, 중앙값을 취해 완화하고 있습니다)

사용한 장비



PC OS: macOS Catalina v10.15
온도 센서 : htps //w w. 슈 tch-s 시엔세. 코 m/타타 g/3395/
라즈파이 3B + : htps //w w. 슈 tch-s 시엔세. 코 m/타타 g/3920/

서모 센서 개요

각 소자마다의 온도 측정 범위는 0℃~80℃입니다. 측정 영역은 센서 정면(상하 좌우 약 60도)의 사각형추로, 이 영역을 8x8픽셀로 분할한 2차원 화상을 얻을 수 있습니다.

준비



라즈파이의 환경 구축



라즈파이 설정 및 연결 설명은 생략합니다. SSH나 디스플레이 접속 등으로 터미널을 사용할 수 있는 상태인 것을 전제로 합니다.

지금이라면, 라즈파이에 OS를 인스톨 하기 위한 툴이 있는 것 같기 때문에, 아래의 기사당을 참고로 하면 좋다고 생각합니다.

I2C 활성화



terminal
sudo raspi-config

CUI의 선택 화면이 나오므로,
I2C -> enabled로 활성화할 수 있습니다.

배선



브레드 보트를 사용하는 것이 좋습니다. 참고



배선이 끝나면 연결되어 있는지 확인하는 명령을 실행합니다.

terminal
i2cdetect -y 1

68이 있으면 올바르게 인식됩니다.
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

파이썬으로 온도 획득



필수 모듈 설치
sudo pip3 install adafruit-circuitpython-amg88xx

검온 프로그램
import time
import busio
import board
import adafruit_amg88xx

i2c_bus = busio.I2C(board.SCL, board.SDA)
sensor = adafruit_amg88xx.AMG88XX(i2c_bus, addr=0x68)
time.sleep(0.5) #スリープを挟まないとsensor.pixelsが取得できない
print(sensor.pixels)

실행하면 2차원 배열이 반환됩니다.

terminal
sudo python3 test.py
[[23.5, 23.5, 24.25, 23.75, 23.25, 24.5, 24.25, 23.25], [23.0, 24.0, 23.5, 24.0, 23.75, 24.25, 24.5, 24.25], [23.75, 23.25, 23.75, 24.0, 23.75, 24.5, 24.5, 24.75], [23.25, 23.25, 23.25, 24.0, 23.5, 24.25, 24.5, 25.75], [23.5, 23.75, 23.75, 24.0, 23.5, 24.25, 24.0, 24.0], [23.75, 23.25, 24.25, 23.5, 23.75, 23.25, 23.75, 24.0], [23.25, 23.75, 23.5, 24.25, 23.75, 23.5, 24.0, 24.0], [23.5, 23.0, 24.0, 23.75, 23.25, 23.25, 24.75, 23.75]]

알기 쉽게 플롯 해 보면 ...
import time
import busio
import board
import adafruit_amg88xx
import matplotlib.pyplot as plt

i2c_bus = busio.I2C(board.SCL, board.SDA)
sensor = adafruit_amg88xx.AMG88XX(i2c_bus, addr=0x68)
time.sleep(0.5)
fig = plt.imshow(sensor.pixels, cmap="inferno")
plt.colorbar()
plt.savefig("plot.png")

얼굴입니다. 그렇게 얻을 수 있습니다.



검온 구현



이마 주변을 검온할 필요가 있기 때문에, 거치 상태에서 검온하면, 이용자에게 얼굴의 위치를 ​​고정시켜 줄 필요가 있습니다. 게다가, 이상은 얼굴을 제자리에 맞추면 검온이 시작되면 UX적으로 좋다.

이것을 실현하기 위해서 자신은 카메라 모듈을 별도 준비해, 소정의 위치에 얼굴이 있는 것을 검지한 것을 트리거로 해 검온을 실시했습니다. 이용자에게는 디스플레이에 표시된 카메라와 프레임을 의지하여 얼굴을 맞춰 달라고 합니다. 물론 이 실장을 실시하는 경우는, 카메라의 위치와 서모 센서의 상대 위치를 고정할 필요가 있습니다.

다음은 샘플 프로그램입니다. 얼굴 감지는 OpenCV를 사용했습니다. (실제의 코드를 샘플용으로 변경한 것으로, 동작 확인은 할 수 없습니다)
import picamera
import picamera.array
import time
import cv2
import busio
import board
import adafruit_amg88xx

#カスケードファイルは配布されている物を使ってます
CascadeFile = "./haarcascade_frontalface_default.xml"

with picamera.PiCamera() as camera:
    #カメラの設定
    camera.resolution = (400, 400)
    camera.rotation = 180
    camera.start_preview()
    time.sleep(2)

    with picamera.array.PiRGBArray(camera) as stream:
        while True:
            #カメラの(50,50)から(350,350)の範囲を顔認識の対象かつ顔判定される最小サイズが250x250なので、認識する位置と大きさが絞られます
            camera.capture(stream, 'bgr', use_video_port=True)
            gray = cv2.cvtColor(stream.array[50:350, 50:350], cv2.COLOR_BGR2GRAY)
            cascade = cv2.CascadeClassifier(CascadeFile)
            face_list = cascade.detectMultiScale(gray, minSize=(250, 250), minNeighbors=3)

            if len(face_list) > 0:
                x, y, w, h = face_list[0]:
                temps = []
                i2c_bus = busio.I2C(board.SCL, board.SDA)
                sensor = adafruit_amg88xx.AMG88XX(i2c_bus, addr=0x68)

                #5回検温
                for i in range(5):
                    time.sleep(0.3)
                    _max = 0
                    for j in sensor.pixels[2:6]:
                        for k in j[3:5]:
                            _max = max(_max, k) #範囲内の最大値を扱う
                    temps.append(_max + 5) #表面温度と体温のギャップ埋め
                print(round(sum(sorted(temps)[1:4]) / 3, 1)) #検温結果をソートし中3つの平均を出力
                break

            stream.seek(0)
            stream.truncate()
        camera.stop_preview()

이 부분은 정밀도 향상의 여지가 있을 수 있습니다. (기온을 바탕으로 이 값을 결정하는 등)
temps.append(_max + 5) #表面温度と体温のギャップ埋め

이 코드에 대해 세세하게 설명하는 것은 힘들기 때문에, 자세한 것은 OpenCV PiCamera 근처에서 조사해 보세요.

마지막으로



어디까지나 학생이 제작으로 싹둑 실장한 것이므로, 확실성이 요구되는 경우는 너무 참고로 지나지 않도록 부탁합니다.

고마워요.

좋은 웹페이지 즐겨찾기