Raspberry Pi でカメラをつなぎ顔検出
【目次】
前準備(Python 仮想環境の作成)
Raspberry Pi OS では、PEP 668 により、システムの Python に pip でパッケージを追加しようとすると externally-managed-environment のエラーになる。パッケージの追加は、Python に標準で付属する venv で仮想環境を作成し、その中で行う。
- Raspberry Pi にリモートログインする
画面表示を伴うプログラムを実行するため、ssh では -X オプション(X11 転送)を付ける。ユーザ名とホスト名は、Raspberry Pi Imager で設定したものを指定する。
ssh -X pi@raspberrypi.local - ビルドに必要なパッケージのインストール
dlib は C++ で書かれており、Python から使うためにはソースコードからのビルドが必要である。そのために cmake とコンパイラを導入する。
# パッケージリストの情報を更新 sudo apt update sudo apt -y install cmake build-essential pkg-config python3-dev python3-venv libopenblas-dev libjpeg-dev libpng-dev - venv を使って、隔離された Python 環境を作る
ここでは、仮想環境を $HOME/dlibenv に作成する
python3 -m venv $HOME/dlibenv source $HOME/dlibenv/bin/activate python -m pip install -U pip setuptools wheel
dlib のインストール
- 端末で、次のコマンドを実行し、Python 仮想環境 $HOME/dlibenv を有効にする
source $HOME/dlibenv/bin/activate - dlib と、画像処理に使う numpy, pillow のインストール
dlib はソースコードからビルドされるため、Raspberry Pi では 20 分から 40 分程度かかる。
python -m pip install -U numpy pillow python -m pip install -U dlib搭載メモリが 2G バイト以下の Raspberry Pi では、ビルド中にメモリ不足でエラーになることがある。その場合は、次のコマンドでスワップ領域を 2048M バイトに増やしてからビルドを行う。ビルド後は、CONF_SWAPSIZE を元の値に戻しておく。sudo sed -i 's/^CONF_SWAPSIZE=.*/CONF_SWAPSIZE=2048/' /etc/dphys-swapfile sudo systemctl restart dphys-swapfile - 確認
バージョン番号が表示されれば、インストールは成功している
python -c "import dlib; print( dlib.__version__ )"
学習済みモデルファイルのダウンロード
- 次のコマンドで、3つのファイルをダウンロードする
この3つのファイルについての説明は、trydlib.html の「学習済みモデルデータのダウンロードの展開(解凍)」のところにある
cd /tmp wget http://dlib.net/files/shape_predictor_5_face_landmarks.dat.bz2 wget http://dlib.net/files/dlib_face_recognition_resnet_model_v1.dat.bz2 wget http://dlib.net/files/mmod_human_face_detector.dat.bz2 ls -la *.bz2 - 展開(解凍)し、/usr/local/dlib にコピー
cd /tmp bzip2 -d shape_predictor_5_face_landmarks.dat.bz2 bzip2 -d dlib_face_recognition_resnet_model_v1.dat.bz2 bzip2 -d mmod_human_face_detector.dat.bz2 sudo mkdir -p /usr/local/dlib sudo cp /tmp/*.dat /usr/local/dlib ls -la /usr/local/dlib
サンプル画像を用いた動作確認
- 端末で、次のコマンドを実行し、Python 仮想環境 $HOME/dlibenv を有効にする
source $HOME/dlibenv/bin/activate - dlib のソースコード一式を取得する
サンプルプログラムとサンプル画像を使うために取得する
cd /tmp rm -rf dlib git clone https://github.com/davisking/dlib - 動作確認
サンプル画像から顔を検出し、顔の特徴量(128 次元のベクトル)を求めるプログラムである。検出結果が画面に表示されるため、ssh の -X オプションによる X11 転送が必要である。
cd /tmp/dlib/examples/faces python /tmp/dlib/python_examples/face_recognition.py /usr/local/dlib/shape_predictor_5_face_landmarks.dat /usr/local/dlib/dlib_face_recognition_resnet_model_v1.dat .
カメラで撮影した画像で顔検出
- Raspberry Pi の電源を切った状態で、カメラモジュールを CSI コネクタに接続する
ケーブルの金属端子の向きを合わせて差し込む。接続後に電源を入れる。
- 端末で、カメラが認識されていることを確認する
接続されているカメラの一覧が表示される
rpicam-hello --list-camerasRaspberry Pi OS の Bookworm 以降では、カメラ用のコマンド名は rpicam-* である。Bullseye 以前では libcamera-*(libcamera-hello, libcamera-jpeg など)を使用する。 - 静止画を撮影し、/tmp/capture.jpg に保存する
rpicam-jpeg --output /tmp/capture.jpg --width 1280 --height 960 --timeout 2000 - 端末で、次のコマンドを実行し、Python 仮想環境 $HOME/dlibenv を有効にする
source $HOME/dlibenv/bin/activate - 撮影した画像に対して顔検出を行う
dlib の get_frontal_face_detector(HOG 特徴量と SVM による顔検出器)を用いる。検出された顔の個数と、顔の外接矩形の座標を表示し、矩形を描き込んだ画像を /tmp/result.jpg に保存する。
python << 'EOS' import dlib from PIL import Image, ImageDraw img_path = '/tmp/capture.jpg' detector = dlib.get_frontal_face_detector() img = dlib.load_rgb_image(img_path) # 第2引数は画像の拡大回数。1 にすると小さい顔も検出しやすくなる dets = detector(img, 1) print("Number of faces detected: {}".format(len(dets))) pil_img = Image.open(img_path).convert('RGB') draw = ImageDraw.Draw(pil_img) for i, d in enumerate(dets): print("Face {}: Left {} Top {} Right {} Bottom {}".format( i, d.left(), d.top(), d.right(), d.bottom())) draw.rectangle([d.left(), d.top(), d.right(), d.bottom()], outline=(0, 255, 0), width=3) pil_img.save('/tmp/result.jpg') print('saved: /tmp/result.jpg') EOS - 結果の画像を表示して確認する
ImageMagick の display コマンドで表示する。画面表示には、ssh の -X オプションによる X11 転送が必要である。
sudo apt -y install imagemagick display /tmp/result.jpg