LoginSignup
15
18

More than 5 years have passed since last update.

dlibの顔ランドマーク認識の結果をリアルタイムにmatplotlibで表示する

Posted at

背景

リアルタイムにカメラ映像の処理結果を表示する場合には、OpenCVのimshowを使うことが多いですが、テキストの表示等は色々不便なのでmatplotlibで表示してみたら、意外と便利だったのでメモ書きです。
例えばdlibの顔認識結果を可視化すると下記のようになります。dlibにも独自GUIモジュールがありますが、一般的な表示処理ができるわけではないので使い勝手は良くないです。

result

前提とか

macOS Sierraで、brew install python3でインストールしたPythonを利用。
下記ではdlibの認識結果を表示しているのでdlibをインストールしていますが、matplotlibでの表示には関係ありません。基本はOpenCVでキャプチャして、matplotlibで表示するだけです。

  • OpenCVのインストール
brew tap homebrew/python
brew install opencv3 --with-python3 --with-ffmpeg --with-tbb --with-contrib

# 利用するPython環境からシンボリックリンクを貼る
cd /usr/local/lib/python3.6/site-packages
ln -s /usr/local/Cellar/opencv3/3.2.0/lib/python3.6/site-packages/cv2.cpython-36m-darwin.so cv2.so
  • matplotlibのインストール
pip3 install matplotlib
  • dlibのインストール
brew install boost
brew install boost-python --with-python3 --without-python
pip3 install dlib

リアルタイム表示

plt.showの代わりにplt.pauseを使うと実現できるようです。
http://qiita.com/hausen6/items/b1b54f7325745ae43e47

コード

リアルタイムにカメラ画像から顔認識→顔ランドマーク認識を行い結果をplotします。
https://gist.github.com/yu4u/18de62c37138ff60f6fcb4cfd5d03ad5

import cv2
import dlib
import matplotlib.pyplot as plt
import matplotlib.patches as patches
import os

predictor_path = "shape_predictor_68_face_landmarks.dat"

# download trained model
if not os.path.isfile(predictor_path):
    os.system("wget http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2")
    os.system("bunzip2 shape_predictor_68_face_landmarks.dat.bz2")

cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)

detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(predictor_path)

fig, ax = plt.subplots()

while True:
    ret, frame = cap.read()
    frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
    dets = detector(frame, 1)

    # for each detected face
    for d in dets:
        # draw bounding box of the detected face
        rect = patches.Rectangle((d.left(), d.top()), d.width(), d.height(), fill=False)
        ax.add_patch(rect)

        # draw landmarks
        parts = predictor(frame, d).parts()
        ax.scatter([point.x for point in parts], [point.y for point in parts])

        for k, point in enumerate(parts):
            ax.text(point.x, point.y, k)

        ax.imshow(frame)
        plt.pause(0.1)
        plt.cla()
15
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
18