ipazc/MTCNN のインストールと動作確認(顔検出)(Python を使用)(Windows 上)
MTCNN は Multi-task CNN (参考 Web ページ: https://github.com/open-face/mtcnn, 原論文: https://kpzhang93.github.io/MTCNN_face_detection_alignment/paper/spl.pdf)
ソフトウェア等の利用条件等は,利用者で確認すること.
【サイト内の関連ページ】
謝辞:MTCNN の考案者、そして、プログラムの作者に感謝します
MTCNN のWebページ: https://www.github.com/ipazc/mtcnn
前準備
Python のインストールと必要なPythonライブラリのインストール(Windows上)
- Python のインストール
注:既にPython(バージョン3.12を推奨)がインストール済みの場合は,この手順は不要である.
winget(Windowsパッケージマネージャー)を使用してインストールを行う
- 必要なPythonライブラリのインストール
【関連する外部ページ】
【サイト内の関連ページ】
このページで説明のために使用するビデオ、写真
必要であればダウンロードして使ってください.
- ここで使用する mp4 形式動画ファイル: sample1.mp4
- ここで使用する顔写真: 126.png, 127.png
顔検出(ipazc/MTCNN を使用)
- ipazc/MTCNN のインストール
python -m pip install -U mtcnn
- mtcnn の factory.py を書き換える.
現在の TensorFlow で動くようにするための変更
次のようなコマンドで,エディタを起動.
notepad c:\program files\python39\lib\site-packages\mtcnn\network\factory.py
先頭部分を次のように書き換える.
from __future__ import absolute_import, division, print_function, unicode_literals import tensorflow.compat.v1 as tf # tf.enable_v1_behavior() import tensorflow.keras as keras import os os.environ['CUDA_VISIBLE_DEVICES'] = '0' # 0 = GPU use; -1 = CPU use config = tf.compat.v1.ConfigProto( device_count = {'GPU': 1 , 'CPU': 3} ) sess = tf.compat.v1.Session(config=config) tf.keras.backend.set_session(sess) from tensorflow.keras.applications.resnet50 import ResNet50 from tensorflow.keras.preprocessing import image from tensorflow.keras.applications.resnet50 import preprocess_input, decode_predictions from tensorflow.keras.utils import plot_model from tensorflow.keras.models import Model from tensorflow.keras.layers import Dense, Dropout, GlobalAveragePooling2D, Input, Conv2D, MaxPooling2D, PReLU, Flatten, Softmax import numpy as np
- C:\face-image のような作業用のディレクトリ(フォルダ)を作る
- このディレクトリに、顔写真: 126.png, 127.png をダウンロード
- 次の Python プログラムを実行する
https://github.com/ipazc/mtcnn で公開されているプログラムを変更して使用
import cv2 import numpy as np from mtcnn.mtcnn import MTCNN img = cv2.imread("c:/image/126.png") detector = MTCNN() print(detector.detect_faces(img)) img = cv2.imread("c:/image/127.png") detector = MTCNN() print(detector.detect_faces(img))
顔検出と、5点(左目、右目、鼻、口の左、口の右)の検出結果が表示されるので確認する
-
矩形(四角形)を書き、情報を表示する関数 box_label
これは,顔検出は行っていない. 画像の上に矩形(四角形)を書き,情報を表示する関数 box_label をテスト実行するもの.
Python プログラムを実行する
import cv2 import numpy as np bgr = cv2.imread("c:/image/127.png") def box_label(bgr, x1, y1, x2, y2, label): cv2.rectangle(bgr, (x1, y1), (x2, y2), (255, 0, 0), 1, 1) cv2.rectangle(bgr, (int(x1), int(y1-25)), (x2, y1), (255,255,255), -1) cv2.putText(bgr, label, (x1, int(y1-5)), cv2.FONT_HERSHEY_COMPLEX, 0.7, (0,0,0), 1) box_label(bgr, 100, 300, 200, 400, "hello") cv2.imshow('', bgr) cv2.waitKey(0) cv2.destroyAllWindows()
画像が表示されるので確認. このあと,ウインドウの右上の「x」をクリックしない.画面の中をクリックしてから,何かのキーを押して閉じる
-
顔検出と、5点(左目、右目、鼻、口の左、口の右)の検出結果を、グラフィックスで表示
Python プログラムを実行する
import cv2 import numpy as np from mtcnn.mtcnn import MTCNN def box_label(bgr, x1, y1, x2, y2, label): cv2.rectangle(bgr, (x1, y1), (x2, y2), (255, 0, 0), 1, 1) cv2.rectangle(bgr, (int(x1), int(y1-25)), (x2, y1), (255,255,255), -1) cv2.putText(bgr, label, (x1, int(y1-5)), cv2.FONT_HERSHEY_COMPLEX, 0.7, (0,0,0), 1) bgr = cv2.imread("c:/image/127.png") detector = MTCNN() a1 = detector.detect_faces(bgr) for i, d in enumerate(a1): x1, y1 = tuple( d['box'][0:2] ) x2, y2 = tuple( np.array( d['box'][0:2] ) + np.array( d['box'][2:4] ) ) box_label(bgr, x1, y1, x2, y2, '{:0.2f}'.format(d['confidence'])) left_eye = d['keypoints']['left_eye'] if len(left_eye) == 2: cv2.circle(bgr, left_eye, 6, (255,255,255), -1) right_eye = d['keypoints']['right_eye'] if len(right_eye) == 2: cv2.circle(bgr, right_eye, 6, (255,255,255), -1) nose = d['keypoints']['nose'] if len(nose) == 2: cv2.circle(bgr, nose, 6, (255,255,255), -1) mouth_left = d['keypoints']['mouth_left'] if len(mouth_left) == 2: cv2.circle(bgr, mouth_left, 6, (255,255,255), -1) mouth_right = d['keypoints']['mouth_right'] if len(mouth_right) == 2: cv2.circle(bgr, mouth_right, 6, (255,255,255), -1) cv2.imshow('', bgr) cv2.waitKey(0) cv2.destroyAllWindows()
画像が表示されるので確認. このあと,ウインドウの右上の「x」をクリックしない.画面の中をクリックしてから,何かのキーを押して閉じる
動画ファイルで動かしてみる
- C:\face-image のような作業用のディレクトリ(フォルダ)に、mp4 形式動画ファイル: sample1.mp4 をダウンロード
- 次の Python プログラムを実行
「c:/image/sample1.mp4」のところは、実際のファイル名に置き換えること
OpenCV による動画表示を行う.
Python プログラムを実行する
import cv2 import numpy as np from mtcnn.mtcnn import MTCNN def box_label(bgr, x1, y1, x2, y2, label): cv2.rectangle(bgr, (x1, y1), (x2, y2), (255, 0, 0), 1, 1) cv2.rectangle(bgr, (int(x1), int(y1-25)), (x2, y1), (255,255,255), -1) cv2.putText(bgr, label, (x1, int(y1-5)), cv2.FONT_HERSHEY_COMPLEX, 0.7, (0,0,0), 1) detector = MTCNN() v = cv2.VideoCapture("c:/image/sample1.mp4") while(v.isOpened()): r, bgr = v.read() if ( r == False ): break a1 = detector.detect_faces(bgr) for i, d in enumerate(a1): x1, y1 = tuple( d['box'][0:2] ) x2, y2 = tuple( np.array( d['box'][0:2] ) + np.array( d['box'][2:4] ) ) box_label(bgr, x1, y1, x2, y2, '{:0.2f}'.format(d['confidence'])) left_eye = d['keypoints']['left_eye'] if len(left_eye) == 2: cv2.circle(bgr, left_eye, 6, (255,255,255), -1) right_eye = d['keypoints']['right_eye'] if len(right_eye) == 2: cv2.circle(bgr, right_eye, 6, (255,255,255), -1) nose = d['keypoints']['nose'] if len(nose) == 2: cv2.circle(bgr, nose, 6, (255,255,255), -1) mouth_left = d['keypoints']['mouth_left'] if len(mouth_left) == 2: cv2.circle(bgr, mouth_left, 6, (255,255,255), -1) mouth_right = d['keypoints']['mouth_right'] if len(mouth_right) == 2: cv2.circle(bgr, mouth_right, 6, (255,255,255), -1) cv2.imshow("", bgr) # Press Q to exit if cv2.waitKey(1) & 0xFF == ord('q'): break v.release() cv2.destroyAllWindows()
* 途中で止めたいとき,右上の「x」をクリックしない.画面の中をクリックしてから,「q」のキーを押して閉じる
パソコンの USB カメラで動かしてみる
「v = cv2.VideoCapture(0) 」は、USB カメラを使うためのもの。他の部分は、上のプログラムと同じ。
Python プログラムを実行する
import cv2
import numpy as np
from mtcnn.mtcnn import MTCNN
def box_label(bgr, x1, y1, x2, y2, label):
cv2.rectangle(bgr, (x1, y1), (x2, y2), (255, 0, 0), 1, 1)
cv2.rectangle(bgr, (int(x1), int(y1-25)), (x2, y1), (255,255,255), -1)
cv2.putText(bgr, label, (x1, int(y1-5)), cv2.FONT_HERSHEY_COMPLEX, 0.7, (0,0,0), 1)
detector = MTCNN()
v = cv2.VideoCapture(0)
while(v.isOpened()):
r, bgr = v.read()
if ( r == False ):
break
a1 = detector.detect_faces(bgr)
for i, d in enumerate(a1):
x1, y1 = tuple( d['box'][0:2] )
x2, y2 = tuple( np.array( d['box'][0:2] ) + np.array( d['box'][2:4] ) )
box_label(bgr, x1, y1, x2, y2, '{:0.2f}'.format(d['confidence']))
left_eye = d['keypoints']['left_eye']
if len(left_eye) == 2:
cv2.circle(bgr, left_eye, 6, (255,255,255), -1)
right_eye = d['keypoints']['right_eye']
if len(right_eye) == 2:
cv2.circle(bgr, right_eye, 6, (255,255,255), -1)
nose = d['keypoints']['nose']
if len(nose) == 2:
cv2.circle(bgr, nose, 6, (255,255,255), -1)
mouth_left = d['keypoints']['mouth_left']
if len(mouth_left) == 2:
cv2.circle(bgr, mouth_left, 6, (255,255,255), -1)
mouth_right = d['keypoints']['mouth_right']
if len(mouth_right) == 2:
cv2.circle(bgr, mouth_right, 6, (255,255,255), -1)
cv2.imshow("", bgr)
if cv2.waitKey(1) & 0xFF == ord('q'):
cv2.destroyAllWindows()
break
* 途中で止めたいとき,右上の「x」をクリックしない.画面の中をクリックしてから,「q」のキーを押して閉じる
