ラズパイとOpenCVで顔認証するメモ

Image from Gyazo

はじめに

こちらの記事を参考に、Raspberry PiOpen CVで顔認証を行う手順のメモです。

用意したもの

  • Raspberry Pi 4 Computer Model B 8GB RAM
  • Raspberry Pi カメラモジュール V2
  • SDカード 32GB
  • ケース
  • 電源ケーブル (USB Type C)
  • キーボード
  • マウス (なくてもキーボードで操作できます)

ラズパイのセットアップ

SDカードにOSをインストールする

今回はRaspberry Pi Imagerを利用してOSをインストールしていきます。

Raspberry Pi Imagerをダウンロード&インストールする

こちらから最新版をダウンロードします。

Image from Gyazo

ダウンロードが終わったら、Raspberry Pi Imagerをインストールします。

Image from Gyazo

Image from Gyazo

チェックをつけてFinishをクリックすると、Raspberry Pi Imagerが起動します。

Image from Gyazo

スタートメニューからも起動できます。

Image from Gyazo

OSを書き込む

Raspberry Pi Imagerを使えば、3ステップでOSを書き込むことができます。

まずはラズパイにインストールするOSを選択します。
今回はRaspberry Pi OS (32-bit)を選択しました。

Image from Gyazo

Image from Gyazo

他にもUbuntuKodiなども簡単にインストールできるようです。

Image from Gyazo

続いて、書き込み対象のSDカードを選択します。

Image from Gyazo

Image from Gyazo

最後にWRITEボタンをクリックして、書き込み処理を開始します。
書き込みには数分~数十分かかります。

Image from Gyazo

OSを書き込む際にSDカードのフォーマットが必要となるので、YESをクリックします。

Image from Gyazo

Image from Gyazo

Image from Gyazo

これでOSの書き込みが終わりました。

Raspberry Piを起動する

SDカードをRaspberry Piに差し込んで、電源を入れます。

Image from Gyazo

無事起動しました!

セキュリティ対策として、以下の記事の手順を一通り行いました。

ラズパイカメラの動作確認をする

OpenCVをインストールする

こちらの記事を参考にOpenCVをインストールしていきます。

詳細は記事をご覧ください。

ここではインストールコマンドだけを抜き出します。

sudo apt update
sudo apt upgrade

sudo apt install -y cmake build-essential pkg-config git
sudo apt install -y libjpeg-dev libtiff-dev libjasper-dev libpng-dev libwebp-dev libopenexr-dev
sudo apt install -y libavcodec-dev libavformat-dev libswscale-dev libv4l-dev libxvidcore-dev libx264-dev libdc1394-22-dev libgstreamer-plugins-base1.0-dev libgstreamer1.0-dev
sudo apt install -y libgtk-3-dev libqtgui4 libqtwebkit4 libqt4-test python3-pyqt5
sudo apt install -y libatlas-base-dev liblapacke-dev gfortran
sudo apt install -y libhdf5-dev libhdf5-103
sudo apt install -y python3-dev python3-pip python3-numpy

sudo cp /etc/dphys-swapfile /etc/dphys-swapfile.org
sudo sed -i -e 's/CONF_SWAPSIZE=100/CONF_SWAPSIZE=2048/g'
sudo systemctl restart dphys-swapfile

git clone https://github.com/opencv/opencv.git
git clone https://github.com/opencv/opencv_contrib.git

mkdir ~/opencv/build
cd ~/opencv/build

cmake -D CMAKE_BUILD_TYPE=RELEASE \
    -D CMAKE_INSTALL_PREFIX=/usr/local \
    -D OPENCV_EXTRA_MODULES_PATH=~/opencv_contrib/modules \
    -D ENABLE_NEON=ON \
    -D ENABLE_VFPV3=ON \
    -D BUILD_TESTS=OFF \
    -D INSTALL_PYTHON_EXAMPLES=OFF \
    -D OPENCV_ENABLE_NONFREE=ON \
    -D CMAKE_SHARED_LINKER_FLAGS=-latomic \
    -D BUILD_EXAMPLES=OFF ..

make -j$(nproc)
sudo make install
sudo ldconfig

上のコマンドをgistにアップしたので、wgetで取得して実行することもできます。

wget https://gist.githubusercontent.com/tmitsuoka0423/b0e87293be375df11032589e465037e6/raw/0e931540c42128757a0e013e3b31a4a97ec55a9b/install-opencv-rpi.sh
bash install-opencv-rpi.sh

pip経由でインストールする方法もありますが、私の環境では失敗してしまいました。
https://pypi.org/project/opencv-contrib-python/

OpenCVがインストールできたか確認します。

PythonのREPLを起動します。

python3

以下、PythonのREPL上で実行します。

import cv2
cv2.__version__

以下のようなにバージョンが出力されればOKです。

Image from Gyazo

カメラの動作確認をする

まずはシンプルに写真と撮ってみる

下記のコマンドを実行します。

sudo raspistill -o image.jpg

こんな感じの写真が撮れました。カメラの接続は大丈夫ですね。

Image from Gyazo

CV2を使ったカメラの動作確認

公開されているサンプルコードを一部改修したものを利用します。

github.com

もとのサンプルコードはこちら。
https://github.com/Mjrovai/OpenCV-Object-Face-Tracking

好きなディレクトリに移動し、クローンします。(ここではホームディレクトリにクローンします)

cd ~
git clone https://github.com/tmitsuoka0423/OpenCV-Object-Face-Tracking

Raspberry Piにカメラを接続します。

(raspi-configのインターフェース設定でカメラを有効にしておいてください。)

先程クローンしたOpenCV-Object-Face-Trackingの中にsimpleCamTest.pyがあるのでこちらを実行します。

cd OpenCV-Object-Face-Tracking
python3 simpleCamTest.py

実行すると以下のように、ウィンドウが2つ立ち上がり、カメラの出力がカラーとグレースケールで表示されます。

Image from Gyazo

かなりピンぼけしていますが、カメラの動作確認ができました。

(オプション)ピントを調節する

ピントの調節には、付属の白いパーツを利用します。

Image from Gyazo

レンズの周辺の凹凸に白いパーツがはまるので、はめた状態で左右に回してピント調節します。

Image from Gyazo

simpleCamTest.pyを実行した状態でピント調節すると、リアルタイムで確認できるのでおすすめです。

エラーが発生する場合

こちらのエラーを修正済みのリポジトリを作成しました。 https://github.com/tmitsuoka0423/OpenCV-Object-Face-Tracking のコードを利用しているか確認してください。

エラー内容

$ python3 simpleCamTest.py 
[ WARN:0] global /home/pi/opencv/modules/videoio/src/cap_gstreamer.cpp (2057) handleMessage OpenCV | GStreamer warning: Embedded video playback halted; module v4l2src0 reported: Failed to allocate required memory.
[ WARN:0] global /home/pi/opencv/modules/videoio/src/cap_gstreamer.cpp (1034) open OpenCV | GStreamer warning: unable to start pipeline
[ WARN:0] global /home/pi/opencv/modules/videoio/src/cap_gstreamer.cpp (597) isPipelinePlaying OpenCV | GStreamer warning: GStreamer: pipeline have not been created
[ WARN:0] global /home/pi/opencv/modules/videoio/src/cap_v4l.cpp (890) open VIDEOIO(V4L2:/dev/video0): can't open camera by index
Traceback (most recent call last):
  File "simpleCamTest.py", line 16, in <module>
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.error: OpenCV(4.5.2-dev) /home/pi/opencv/modules/imgproc/src/color.cpp:182: error: (-215:Assertion failed) !_src.empty() in function 'cvtColor'

teratail.com

こちらの記事を参考に、simpleCamTest.pyに下記の変更を加えると動きました。

cap = cv2.VideoCapture(0)
↓
cap = cv2.VideoCapture(-1)

cv2.VideoCaptureの引数に-1を指定するとカメラを自動指定してくれるそうなのですが、OpenCVのドキュメントを読んでもその記載が見当たりませんでした。(もやもや)

docs.opencv.org

顔検出してみる

こちらのリポジトリを好きなディレクトリにクローンします。

https://github.com/Mjrovai/OpenCV-Face-Recognitionリポジトリのコードを一部変更したものです。

git clone https://github.com/tmitsuoka0423/OpenCV-Face-Recognition.git

リポジトリの中に、OpenCV-Face-Recognition/FaceDetection/faceDetection.pyがあるので実行します。

cd OpenCV-Face-Recognition/FaceDetection
python3 faceDetection.py

するとウィンドウが立ち上がるので、顔を写すと枠が表示されるようになります。

Image from Gyazo

顔認証する

顔認証を行うには、

  1. 顔写真を集める
  2. 顔写真を使って顔認証モデルを作成する
  3. 顔認証モデルを使って推論する

というステップを踏む必要があります。
まずは顔写真を集めていきます。

こちらのリポジトリをクローンしていない方はクローンしておいてください。

git clone https://github.com/tmitsuoka0423/OpenCV-Face-Recognition.git

顔写真を集める

ラズパイに接続したカメラを利用して、顔写真を撮影してくれるプログラムが用意されています。
画像はdatasetフォルダに出力されるようになっているので、先にフォルダを作成しておきます。

cd FacialRecognition
mkdir dataset
python3 01_face_dataset.py

ユーザーIDの入力を求められるので、学習させる人ごとにIDを振りましょう。
(今回は自分と坂本龍馬の顔を学習させるので、自分:0、坂本龍馬:1、という風にしました。)

 enter user id end press <return> ==>  0
 [INFO] Initializing face capture. Look the camera and wait ...

と言われるのでカメラの方を向くと、自動で学習用の顔写真が撮影されていきます。

Image from Gyazo

datasetフォルダに画像が溜まっていき、30枚撮影が終わったタイミングでプログラムが終了します。

撮影が進まない場合は、ピントの調節や光の当たり方を変えると進むようになったので、試してみてください。

顔認証モデルを作成する

画像処理ライブラリpillowを使用するので、先にインストールしておきます。

pip install pillow

学習用のプログラムを実行します。

mkdir trainer
python3 02_face_training.py

学習が終わると以下のように表示され、trainerフォルダにtrainer.ymlが作成されます。

 [INFO] Training faces. It will take a few seconds. Wait ...

 [INFO] 2 faces trained. Exiting Program

Image from Gyazo

顔認証する

認証結果にラベルを表示させるため、03_face_recognition.py26行目にあるnamesを修正します。
顔写真を撮影したときのIDが配列のインデックスになるように、ラベルを設定します。
(ID=0→配列の0番目:mitsuoka、ID=1→配列の1番目:ryoma)

names = ['None', 'Marcelo', 'Paula', 'Ilza', 'Z', 'W'] 
↓
names = ['mitsuoka', 'ryoma']

変更できたら、プログラムを実行します。

python3 03_face_recognition.py

するとカメラウィンドウが立ち上がり、顔が写ると枠が表示され、ラベルと顔の一致度が表示されました!

Image from Gyazo

まとめ

Raspberry PiOpenCVを使った顔認証のチュートリアルを実施し、手順をメモしました。
3ステップで顔認証システムのプロトタイプが作れるのはとても良いですね。

光の当たり方や写る角度によって顔認証されないので、学習データの集め方に工夫する余地がありそうです。

参考サイト

日本語でざっくり概要を掴みたい方におすすめ ai-coordinator.jp

英語。解説してるおじさんが良い。 www.instructables.com