Swift Playgroundsで学ぶiOSプログラミング

顔の位置と顔のパーツを認識するプログラム

文●柴田文彦 編集●吉田ヒロ

2018年05月16日 17時00分

顔のパーツを認識してその骨格を描く

 次にもう1つの顔認識機能、顔のパーツを認識する機能を試しましょう。これはVNDetectFaceLandmarksRequestというクラスによります。上の例と比べて大きく異なるのは、長方形認識のリクエストに代えて、このランドマークの認識リクエストのクラスを使うことです。ランドマークは、一般には地理的な目標物ということになっていますが、「境界線」といった意味もあるのです。

 リクエストハンドラーは上の例と同じです。ただし、結果はlandmarksというプロパティに入ってきます。このプロパティには、顔の上のさまざまなパーツの境界線が含まれています。例えば顔の輪郭は、さらにfaceContourというプロパティに入っています。

Visionフレームワークを使って、目鼻口など顔のパーツを認識させることも簡単にできます。その場合は、認識リクエストのクラスとしてVNDetectFaceLandmarksRequestを使います。あとの処理は、顔の領域の認識とほとんど同じです

 とりあえず、そのプロパティの値をプレイグラウンドのデバッグ機能で確認してみましょう。

この例では顔の輪郭だけを認識させてみました。結果は座標点の羅列として返ってきます

 中身は複数の座標の羅列ですが、いかにも顔の輪郭線が描けそうな気がします。顔のパーツの境界線も、上の例と同じように元の画像に重ねて描画して見てみましょう。やはりグラフィックコンテキストを使います。その設定部分は、上の例とまったく同じです。

認識した顔のパーツの境界線を元の画像の上に描画するために、やはりグラフィックコンテキストを使います。コンテキストの準備の処理までは前の例とほとんど同じです

 ここでは、顔の輪郭だけでなく、目、鼻、唇も描くために、得られた座標地をパスとして描画するdrawPathというメソッドを定義しました。

いろいろな顔のパーツの境界線を同じ処理で描けるように、drawPathというメソッドを定義しました。パーツの境界線の座標を含むVNFaceLandmarkRegion2D型と顔全体を囲む長方形のCGRect型、2つの引数を受け取ります

 あとは認識された結果から顔のいろいろなパーツの境界線をパスとして描いていきます。その際の座標の基準となるのは、顔を囲う長方形なので、まずはその長方形の位置と大きさを確定します。

 その後、結果からfaceContour(顔の輪郭)、leftEye(左目)、rightEye(右目)、noze(鼻)、outerLips(唇の外形)、innerLips(唇の内形)を順に取り出して描画していきます。

実際の顔のパーツの境界線の描画では、上で定義したdrawPathメソッドを使って、顔の輪郭、左目、右目、鼻、唇の外側、唇の内側の境界線を描いています

 やはり結果はデバッグ機能で確認しましょう。

顔のパーツの認識結果は秀逸で、顔が傾いていることをものともせず、かなり正確に認識していることがわかります

 ノイズも多く、顔自体も傾いていますが、見事に顔のパーツの境界線を認識して描くことができました。

次回の予定

 今回も、Core MLがらみの機能ながらCoreMLフレームワークを直接利用せずに使えるものを試しました。これで、人の顔の特徴を数値として捉えることができるようになったのです。いろいろな応用が可能だと思うので、ぜひ試してみてください。このVisionフレームワークは、まだまだ奥が深いので次回も引き続き探っていきたいと思います。

mobileASCII.jp TOPページへ