11
9

More than 1 year has passed since last update.

face-api.jsで複数の顔を検出する

Last updated at Posted at 2022-03-17

はじめに

先日face-api.jsを使ってみました。
前回の記事↓

今回はface-api.jsについてもう少し調べてみたいと思います。

face-api.jsとは?

繰り返しになりますが、face-api.jsはブラウザで顔検出(face detection:人の顔を自動的に見つける)と顔認識(face recognition:個人を識別する)ができるJavaScript APIです
機械学習用のライブラリTensorFlow.jsが利用されています
face-api.js

face-api.jsを使う準備

前回参照。
まだNode.jsは勉強中なので
今回も自分のプロジェクトにスクリプトを含める方法です。

今回試すもの

「トラニナル」はとにかく動くものを短時間で作る。という
マッチョな目標があったので読み飛ばしましたが
face-api.jsの内容をもう少し読んでいきます。

⇒読んだ結果、複数顔の検出を試しました!

Available Models

Face Detection Models

顔検出モデルについて書かれています。

SSD Mobilenet V1

画像内の各顔の位置を計算し、
各顔の確率とともにバウンディングボックスを返します。

face-api.js内で一番標準的な(?)顔検出のモデルだと思われます。
よく見かけるコードではこちらが使われていることが多いので、
私も「トラニナル」では思考停止状態でこちらを使用しました。

Tiny Face Detector

パフォーマンスの高いリアルタイムの顔検出器。
SSD Mobilenet V1顔検出器と比較して、高速・小型・リソース消費が少なく、
パフォーマンスはわずかに低下します。
モバイルデバイスやクライアントのリソースが限られているときはこちらを使用すべき。

「トラニナル」は使用者から「重い」という声を聞きました。
というか、自分でもテストして「重いなぁ」と思ったんですが
その時点で12/27だったので諦めました。
そんな問題を解決してくれそうな話がさっそく書いてあります!
これは使ってみたい。

MTCNN

MTCNN:マルチタスクカスケード畳み込みニューラルネットワーク。
(Google翻訳頼みですが合ってるのかな?)
一般に、他の顔検出器の方がパフォーマンスが優れている。

実験のためにリポジトリに入っている顔検出器のようです。
試すのはもちろんOK。

顔検出ついては上記3つについて書かれていました。

68 Point Face Landmark Detection Models

68点面顔ランドマーク検出モデル。
デフォルトのモデル(face_landmark_68_model)は350KB
小さなモデル(face_landmark_68_tiny_model)は80KB

顔ランドマーク検出の検出器にも小さいものがあることが分かりました!
これまた朗報ですね。

Face Recognition Model

顔認識のモデル。あらゆる人物の顔認識に使用できます。
ResNet-34のようなアーキテクチャが実装され、
人物の顔の特性を記述するために
任意の顔画像から顔記述子(face descriptor:128個の値を持つ特徴ベクトル)が計算されます。
2つの任意の顔の類似性は、それらの顔記述子を比較することによって
(たとえばユークリッド距離を計算することによって)決定できます。

ResNetとはニューラルネットワークのモデルのようですね。
難しいところは理解できなかったのですが
このモデルを使えば特定人物のお顔を認識出来るようです。

Face Expression Recognition Model

顔の表情認識モデル。
軽量、高速で、適度な精度を提供。
眼鏡をかけると、予測結果の精度が低下する可能性がある。

表情認識も気になりますよね~
笑顔の瞬間で撮影してくれたら面白いなぁ。

Detecting Faces

「トラニナル」で使ったのは
detectSingleFaceと言うメソッドでした。

ここも他の方法について調べる時間が無かっただけなので、
今回もう少し調べてみます。

画像内で最も信頼度の高い顔を検出する

const detection = await faceapi.detectSingleFace(input)

FaceDetection が返ってきます。

画像内のすべての顔を検出する

const detections = await faceapi.detectAllFaces(input)

Array < FaceDetection >が返ってきます。

detectAllFacesとdetectSingleFaceはデフォルトではSSD Mobilenet V1顔検出モデルを利用します。
対応するオプションオブジェクトを渡すことで、顔検出器を指定することができます。

const detections1 = await faceapi.detectAllFaces(input, new faceapi.SsdMobilenetv1Options())
const detections2 = await faceapi.detectAllFaces(input, new faceapi.TinyFaceDetectorOptions())
const detections3 = await faceapi.detectAllFaces(input, new faceapi.MtcnnOptions())

顔のランドマーク検出

「画像内で最も信頼度の高い顔を検出」し
「その顔の68点顔ランドマークを計算」

const detectionWithLandmarks = await faceapi.detectSingleFace(input).withFaceLandmarks()

「画像内のすべての顔を検出」し、
「検出された顔ごとに68点顔ランドマークを計算」

const detectionsWithLandmarks = await faceapi.detectAllFaces(input).withFaceLandmarks()

detectSingleFaceを使うかdetectAllFacesを使うか、と言うことですね。

デフォルトのモデルではなく小さなモデルを使うには

const useTinyModel = true
const detectionsWithLandmarks = await faceapi.detectAllFaces(input).withFaceLandmarks(useTinyModel)

と、withFaceLandmarks()の引数にtrueを与えればよさそうです。

複数顔検出をやってみる

ということで、色々試してみたくはなったのですが、
今回は「複数の顔を検出する」ことにします。

image.png
早速結果です。

やったことは
detectSingleFacedetectAllFaces
だけです!
あとは返ってきたFaceDetectionのデータが配列に入っているので
複数人分の描画を行うように書き換えました。

今回はココまで。

おわりに

用意されている顔モデルについて確認し、
複数人の顔検出・顔ランドマーク検出が出来ました。

小さいサイズのモデルも使ってみたいですし、
顔認識や表情検出も気になります。
次の機会に試してみたいと思います。

11
9
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
11
9