grasys blog

Raspberry Pi で顔認証からパスワード入力までやってみる【Raspberry Pi/Python/face-recognition】

はじめまして!エンジニアの Uemaです。

前回は、face-recognition を使って顔認証をやってみて、手軽に顔認証を行うことができました。


今回は、Raspberry Pi と face-recognition を使ってパスワードの自動入力システムを作ってみました。

Raspberry Pi の設定で大変なところもあったので、同じように設定で苦戦している方の助けになればなと思います。

背景

パスワードの自動入力システムを作ろうかと思った背景として、家で MacBook を使う時にはクラムシェルモードで作業をしています。

その際に、TouchID が使えず毎回パスワードの入力を行っていましたが、毎回入力するのは面倒でした。

そこで、Raspberry Pi と face-recognition を使って、自作のパスワードの自動入力システムを作ろうと思い立ちました。

Raspberry Pi

今回は以下を使いました。(Raspberry Pi 正規代理店の KSY で購入)

  • Raspberry Pi Zero 2 W
  • Raspberry Pi Camera V2

最新の Raspberry Pi OS Lite ( Bookworm, 64bit ) を使用しています。

環境構築

Raspberry Pi Imager をインストール

Raspberry Pi OS を Raspberry Pi にインストールするには Raspberry Pi Imager が必要になるので、ダウンロードしましょう。

https://www.raspberrypi.com/software


Raspberry Pi 初期設定

SD カードを PC に接続して、下記サイトを参考に Raspberry Pi の初期設定を行っていきます。

https://www.ingenious.jp/articles/howto/raspberry-pi-howto/raspberry-pi-basic-setup

ユーザー作成と SSH の設定は必ずやってください。

初期設定が終わったら、SD カードを PC から取り外して、Raspberry Pi に入れて起動します。


SSH で Raspberry Pi に接続

先ほど初期設定で指定したユーザー名とパスワードで SSH ログインできます。

ssh {ユーザー名}@raspberrypi.local


管理者( root )に切り替える

adafruit_hid を使った HID キーボードのプログラムを実行していく時に管理者じゃないと権限エラーで実行できないため、管理者に切り替えておく(何かいい方法があれば、、、)。

sudo su -


Raspberry Pi の設定

/boot/firmware/config.txt[all] に下記を追記し、元々ある dtoverlay をコメントアウトする。

dtoverlay=dwc2,imx219

dwc2 は OTG モードに設定、imx219 はカメラの設定になります。

/etc/modules に下記を追記

dwc2
libcomposite

libcomposite モジュールを有効にすると、USB デバイスとして振る舞わせることができる。(下記のブログ参照)

Hatena Blog

再起動する

sudo reboot


face-recognition をインストール

顔認証で必要な face-recognition を公式のドキュメントを参考にインストールしていきます。

1.パッケージの最新化

sudo apt update
sudo apt upgrade


2.必要なパッケージをインストール

sudo apt-get install build-essential \
    cmake \
    gfortran \
    git \
    wget \
    curl \
    graphicsmagick \
    libgraphicsmagick1-dev \
    libatlas-base-dev \
    libavcodec-dev \
    libavformat-dev \
    libboost-all-dev \
    libgtk-3-dev \
    libjpeg-dev \
    liblapack-dev \
    libswscale-dev \
    pkg-config \
    python3-dev \
    python3-numpy \
    python3-pip \
    python3-picamera2 \
    zip

※ 公式ドキュメントだと libatlas-dev だが、今は libatlas-base-dev に置き換わっているので差し替える。
※ pip install だと picamera2 がインストールできなかったため、apt で python3-picamera2 をインストールする。


3. dlib インストールする際に、メモリ不足により dlib コンパイルが失敗しないようにするため、スワップサイズを変更する

sudo vi /etc/dphys-swapfile
# CONF_SWAPSIZEを200から2048に変更


4. pip でライブラリをインストール

# 仮想環境を作成
python -m venv venv --system-site-packages
source venv/bin/activate
# ライブラリインストール
pip install opencv-python
pip install dlib
pip install face_recognition

※ dlib のインストールはかなりの時間がかかる。数時間かかった。


Adafruit Blinka をインストール

Raspberry Pi を HID キーボードとして認識させて、パスワードを入力するために CircuitPython が必要になります。

Adafruit Blinka はハードウェアを制御する CircuitPython をエミュレートするソフトウェア ライブラリで、Linux ベースの Raspberry Pi で CircuitPython の互換モジュールを利用できます。

1.こちらのドキュメントを参考に Adafruit Blinka をインストールする。

cd
pip3 install --upgrade adafruit-python-shell
wget https://raw.githubusercontent.com/adafruit/Raspberry-Pi-Installer-Scripts/master/raspi-blinka.py
sudo -E venv PATH=$PATH python3 raspi-blinka.py
pip install --upgrade adafruit-blinka


2. HID 用のライブラリをインストール

pip install adafruit-circuitpython-hid

これで、環境構築は完了です。

実装

下記のサイトを参考に顔認証後にパスワードの自動入力を実装する。

https://github.com/ageitgey/face_recognition/blob/master/examples/facerec_on_raspberry_pi.py

https://zenn.dev/ncdc/articles/dcc8f28bf54279

https://docs.circuitpython.org/projects/hid/en/latest

import sys

from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS
import cv2
import face_recognition
from picamera2 import Picamera2
import usb_hid


# カメラの設定
camera = Picamera2()
camera.configure(camera.create_preview_configuration(main={
        "format": 'XRGB8888',
        "size": (320, 240)
}))
camera.start()

# 画像を読み込み、顔の特徴値を取得する
uema_image = face_recognition.load_image_file("images/uema.jpg")
uema_face_encoding = face_recognition.face_encodings(uema_image)[0]

# HIDキーボードの設定
usb_hid.enable((usb_hid.Device.KEYBOARD,),)
keyboard = Keyboard(usb_hid.devices)
keyboard_layout = KeyboardLayoutUS(keyboard)

face_locations = []
face_encodings = []

print("Start capture image")

while True:
    # カメラからイメージを撮る
    image = camera.capture_array()
    output = cv2.cvtColor(image, cv2.COLOR_BGRA2BGR)

    # 顔を検知する
    face_locations = face_recognition.face_locations(output)
    print(f"Found {len(face_locations)} faces")
    face_encodings = face_recognition.face_encodings(output, face_locations)

    for face_encoding in face_encodings:
        # 読み込んだ顔の特徴量とカメラから取得した顔の特徴量を比較する
        match = face_recognition.compare_faces([uema_face_encoding], face_encoding)
        name = "Unknown"
        password = ""

        if match[0]:
            # 一致していたらパスワードを出力する
            name = "uema"
            password = "password"
            keyboard_layout.write(password)
            print(f"I see someone named {name}!")
            # プログラムを終了する
            sys.exit(0)

Python を実行して、顔が一致した時にパスワードを入力し、終了します。

これにて、Raspberry Pi と face-recognition を使って、自作のパスワードの自動入力システムは完成となります。

今後の展望

今回は顔認証からパスワード入力までを実装しました。しかし、実用としてはまだまだなところがあります。

今のままだと Raspberry Pi を接続、SSH 接続して Python を実行するといった手順が必要となります。

接続後に顔認証が動くようにするためにタクトスイッチを利用して Python プログラムを実行する必要があり、そこについてはまだ未実装となっているので、次で実装したいと思います。

最後に

Raspberry Pi でのカメラの設定や HID キーボードの設定が、古い情報で設定しても機能しなかったりしました。(4回くらい OS を焼き直ししました。。。)

ドキュメントを見たり、同じ現象の対処をしているサイトなどを調べまくってそれらを参考に実装することができました。大変でしたが、いい勉強になりました。

次回は、タクトスイッチで今回作成したパスワードの自動入力システムを起動できるようにしたいと思います。楽しみにしてください。

もしご興味があれば、前回の記事もご覧ください!


採用情報
お問い合わせ