iOSアプリに顔認識を導入しようと思うと、昔ならOpenCVやTensorFlowでモデルをつくって…というようにいささかハードルが高く感じられたものですが、AppleさんがVisionフレームワークを用意してくれたおかけで、そのハードルは大きく下がりました。
今回、Appleのサンプルコードを使いながら、リアルタイムでユーザーの顔をトラッキングしてみました。
できるアプリ
このように顔の中の特徴的な部分(ランドマーク)を勝手に検出し、Bounding Box(境界ボックス)で囲ってくれます!
境界ボックスは、顔が移動すると追跡してくれるので、境界ボックスの座標をもとにして、顔が画面のどこに寄っているかなどもとることができます。
サンプルコード
https://developer.apple.com/documentation/vision/tracking_the_user_s_face_in_real_time
このページのDownloadボタンからダウンロードして、実機でビルドすると顔認識アプリができます。
解説
サンプルコードの239行目あたりの
let faceDetectionRequest = VNDetectFaceRectanglesRequest(completionHandler: { (request, error) in
if error != nil {
print("FaceDetection error: \(String(describing: error)).")
}
guard let faceDetectionRequest = request as? VNDetectFaceRectanglesRequest,
let results = faceDetectionRequest.results as? [VNFaceObservation] else {
return
}
DispatchQueue.main.async {
// Add the observations to the tracking list
for observation in results {
let faceTrackingRequest = VNTrackObjectRequest(detectedObjectObservation: observation)
requests.append(faceTrackingRequest)
}
self.trackingRequests = requests
}
})
で、検出された顔の解析が行われています。
ここの
for observation in results {
let faceTrackingRequest = VNTrackObjectRequest(detectedObjectObservation: observation)
requests.append(faceTrackingRequest)
}
のobservationから顔のランドマークやロール、ヨー角など様々な情報にアクセスできます。
たとえば、
for observation in results {
let faceTrackingRequest = VNTrackObjectRequest(detectedObjectObservation: observation)
requests.append(faceTrackingRequest)
// 顔のロールの取得
print(observation.roll)
}
のようなイメージです。
ついでに境界ボックスから顔が画面のどこに寄っているかもとってみましょう。
サンプルコードの554行目あたりの
guard let observation = trackingResults[0] as? VNDetectedObjectObservation else {
return
}
で、トラッキングしたユーザーの顔の結果を取得しているので、このobservation
を使って、境界ボックスの座標を取得します。
if observation.boundingBox.maxX >= 0.9 {
print("顔が画面の右に寄っています")
}
上のように書くことで境界ボックスのX座標の画面からの比率を取得することができます。(画面の右端が1です)
今回は境界ボックスのX座標が0.9以上で画面の右に寄っていると出力するようにしてみました。
まとめ
Appleの機械学習で良いイメージはあまりなかったのですが、Visionフレームワークは予想以上に便利だなと思いました。
ただ、動画内でのまばたきや笑顔の検出はVisionだけでは厳しそうなので、Amazon Rekognition Videoなどを使う必要がありそうです。
とはいっても予想以上に面白かったので、これからもCore MLやCreate MLなどで遊んでみたいと思います。