顔検出の機械学習ではモデル作成も含め、OpenCVしか使ってなかったのでほかも使ってみることにした。
ということでMTCNN使ってみました。
MTCNNは裏側でtensorflow使ってるようですね。
ディープランニングに片足突っ込んでる感じでいい気分です。
準備
pip3 install cv2
pip3 install matplotlib
pip3 install mtcnn
pip3 install tensorflow
テストで使った画像
検証に丁度いいんですよね。顔いろんなむき出し。顔以外のもの色々写ってるし
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)
結果
すべて正しく検出されていますね。
この画像に関しては誤検出もしていないようです。
ちなみにOpenCV(haarcascade_frontalface_default)使ったものがこちらになります。
顔は全部検知できてますけど、めっちゃ誤検出しています。
アイスとかほんと顔だわw
前にデフォルトのモデルに納得できなくて自分で作ったものが以下です。
誤検出はしなくなったけど、1人検出できてませんね。
参考) とあるgopherが OpenCVをさわってみた話
https://speakerdeck.com/usk81/introduction-about-opencv-for-gophers
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)
結果
備考
画像ファイルの読み込みが、 pyplot.imread
で読み込めなかったのが謎です。
関数内だと使えるんだけどなぁ...