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