LoginSignup
20
19

More than 3 years have passed since last update.

MTCNNで顔検出してみた

Last updated at Posted at 2019-12-10

顔検出の機械学習ではモデル作成も含め、OpenCVしか使ってなかったのでほかも使ってみることにした。
ということでMTCNN使ってみました。

MTCNNは裏側でtensorflow使ってるようですね。
ディープランニングに片足突っ込んでる感じでいい気分です。

準備

pip3 install cv2
pip3 install matplotlib
pip3 install mtcnn
pip3 install tensorflow

テストで使った画像

検証に丁度いいんですよね。顔いろんなむき出し。顔以外のもの色々写ってるし

test.png

MTCNNで顔検出

検証コード

# face detection with mtcnn on a photograph
from matplotlib import pyplot
from matplotlib.patches import Rectangle
from matplotlib.patches import Circle
from mtcnn.mtcnn import MTCNN
import cv2

# draw an image with detected objects
def draw_image_with_boxes(filename, result_list):
    # load the image
    data = pyplot.imread(filename)
    # plot the image
    pyplot.imshow(data)
    # get the context for drawing boxes
    ax = pyplot.gca()
    # plot each box
    for result in result_list:
        # get coordinates
        x, y, width, height = result['box']
        # create the shape
        rect = Rectangle((x, y), width, height, fill=False, color='red')
        # draw the box
        ax.add_patch(rect)
        # draw the dots
        for key, value in result['keypoints'].items():
            # create and draw dot
            dot = Circle(value, radius=2, color='red')
            ax.add_patch(dot)
    # show the plot
    pyplot.show()

filename = 'test.png'
# load image from file
pixels = cv2.cvtColor(cv2.imread(filename), cv2.COLOR_BGR2RGB)
# create the detector, using default weights
detector = MTCNN()
# detect faces in the image
faces = detector.detect_faces(pixels)
# display faces on the original image
draw_image_with_boxes(filename, faces)

結果

すべて正しく検出されていますね。
この画像に関しては誤検出もしていないようです。

result_1.png

ちなみにOpenCV(haarcascade_frontalface_default)使ったものがこちらになります。
顔は全部検知できてますけど、めっちゃ誤検出しています。
アイスとかほんと顔だわw

result_cv.png

前にデフォルトのモデルに納得できなくて自分で作ったものが以下です。
誤検出はしなくなったけど、1人検出できてませんね。

参考) とあるgopherが OpenCVをさわってみた話
https://speakerdeck.com/usk81/introduction-about-opencv-for-gophers

mine.png

MTCNN... 完敗や... 40時間ぐらいかけたのに
_| ̄|○ il||li

切り出しもしてみた

一番大きく切り出せてるやつを1つだけ保存するようにしてみました。

コード

# face detection with mtcnn on a photograph
from matplotlib import pyplot
from mtcnn.mtcnn import MTCNN
import cv2

# draw each face separately
def save_biggest_face_image(filename, result_list):
    # load the image
    # data = pyplot.imread(filename)
    data = cv2.imread(filename)
    # plot each face as a subplot
    maxlen = -1
    for i in range(len(result_list)):
        # get coordinates
        x1, y1, width, height = result_list[i]['box']
        if width > height:
            length = width 
        else:
            length = height
        x2, y2 = x1 + length, y1 + length
        # # define subplot
        # pyplot.subplot(1, len(result_list), i+1)
        # pyplot.axis('off')
        # # plot face
        # pyplot.imshow(data[y1:y2, x1:x2])
        d = data[y1:y2, x1:x2]
        if length > 100 and length > maxlen:
            maxlen = length
            md = d
        # cv2.imwrite('/Users/komatsu/Desktop/'+str(i)+'.png', d)

    # show the plot
    # pyplot.show()
    if maxlen > 0:
        cv2.imwrite('result.png', md)

filename = 'test.png'
# load image from file
pixels = cv2.cvtColor(cv2.imread(filename), cv2.COLOR_BGR2RGB)
# create the detector, using default weights
detector = MTCNN()
# detect faces in the image
faces = detector.detect_faces(pixels)
# save face image
save_biggest_face_image(filename, faces)

結果

result_2.png

備考

画像ファイルの読み込みが、 pyplot.imread で読み込めなかったのが謎です。
関数内だと使えるんだけどなぁ...

20
19
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
20
19