(割り込みアドベントしましたm(_ _ )m.)
前置き
以前、GoogleのFirebaseを使用して
「[Swift]Firebase MLKitを使って動画の顔認識をさせる」
のようなことを行ってみました。
今回はAWSで提供されている「AWS Rekognition」を使用して、同じようなことができるのでは、と思い試してみました。
AWS Rekognitionとは?
公式サイトのデモから
Amazon Rekognition では、機械学習の専門知識を必要とせずに、実績のある高度にスケーラブルなっ深層学習テクノロジーを使用して、アプリケーションに画像およびビデオ分析を簡単に追加できるようになります。
Amazon Rekognition を使用すると、画像と動画の物体、人物、テキスト、シーン、活動を特定し、不適切なコンテンツを検出できます。Amazon Rekognition は、非常に正確な顔分析および顔検索機能も備えています。これを使用して、さまざまなユーザー検証、人数のカウント、および公共安全のユースケースで顔を検出、分析、比較できます。
とあるように、画像に対してAmazonが保有する学習データを簡単に使える機能になります。
導入
2つの方法で実装が可能です。
(1) AWS Amplifyを使って設定を簡単に行う
(2) デフォルトのSDKを使う(自分でAWSを設定していく)
AWSを実際使うとなると設定周りのハードルが高くなってしまいます。
アプリで使用するにしても、以下のような認証部分の設定は最低限必要になってきます。
AWS Amplifyではその部分をまるっとCLIで行ってくれるため、アプリ開発者はその部分に注力しなくて済むのです。
今回はせっかくなので、どちらの方法でも実装方法を説明していきたいと思います。
前提
AWSのアカウント作成
まずは前提としてアカウントが必要になるので、公式から作成しましょう。
作成自体は流れに沿って入力していけば完了します。
(無料で使用できる期間はありますが、登録にあたりクレジットカード登録は必須なので用意しておきましょう)
(1) AWS Amplifyで実装する
コマンドラインツールを使うことで、AWSの管理画面側をほとんど触らずに済ますことができます。
以下で体験してみましょう。
1. AWSの設定
① Amplifyの準備
必要なものをインストールします。以下のサイトを参考にすると良いでしょう。
② 認証機能の準備
アプリで使用可能にするため、認証機能を追加します。
$ amplify add auth
terminalでの質問は、以下の選択肢を選べば大丈夫です。
③ Rekognitionの準備
Rekognitionの機能を追加します。
$ amplify add predictions
terminalでの質問は、以下の選択肢を選べば大丈夫です。
今回は特定の機能(Identity Entities)を使用する前提で進めています。
それ以外の機能を使用したい場合は、こちらで別のものを選択してください。
選択したものしか使用許可が出ないため、アプリ上でAPIを叩いてもエラーが返ってきます。
④ 設定の反映
AWS側に設定を反映します。
$ amplify add auth
また、生成されているamplifyconfiguration.json
をXcodeのプロジェクトに追加しておきましょう。
(場所はどこでも良く、Xcode上にリファレンスがついている必要があります。)
これで準備は完了です。
2. アプリ側の実装
① Podの準備
適当なプロジェクト作成し、CocoaPodsを導入しましょう。
pod 'Amplify'
pod 'AmplifyPlugins'
pod 'AWSPluginsCore'
pod 'CoreMLPredictionsPlugin'
pod 'AWSPredictionsPlugin'
pod 'AWSMobileClient', '~> 2.12.2'
バージョン指定をしています。
現状ではAWSPredictionsPlugin
が最新のものに対応しておらずで、エラーが出てしまうためです。
② AWSのセットアップ
起動した時にAWSのセットアップを行います。
import Amplify
import AWSMobileClient
import AWSPredictionsPlugin
@UIApplicationMain
final class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let apiPlugin = AWSPredictionsPlugin()
do {
try Amplify.add(plugin: apiPlugin)
try Amplify.configure()
} catch {
print("Failed to configure Amplify \(error)")
}
return true
}
問題がある場合は起動時にコンソールでエラーが出てきます。
(jsonが読み込めていない場合など)
③ 「顔認識」をしてみる
先ほどの設定でIdentity Entities
を指定したので、それを呼び出してみます。
import Amplify
guard let path = Bundle.main.path(forResource: name, ofType: "jpg") else { return }
let url = URL(fileURLWithPath: path)
_ = Amplify.Predictions.identify(type: .detectEntities, image: url, listener: { [weak self] event in
switch event {
case .completed(let result):
debugPrint("----completed----", "\(result)")
case .failed(let error):
debugPrint("----failed----", error.errorDescription)
case .notInProcess, .inProcess, .unknown:
debugPrint("----other----", event.description)
}
})
プロジェクト内にあるjpgファイルを読み込み使用しています。
うまくいけば、省略していますが、顔から推察されるデータがこのように返却されてきます。
コード自体は数行で済みとても簡単でしたね!
(2) デフォルトのSDKを使って実装する
アプリをスケールさせるとなった時には、やはり細かい設定を触れた方がメリットも大きいです。
それでは、管理画面を触りながら実装していく方法をみていきましょう。
1. AWSの設定
① IDプールの作成
AWSサービスへのアクセスを許可するために、任意のIDを発行(作成)します。
(このIDは、あとでアプリ側で設定することになるものです。)
① ホーム画面の検索窓で「Cognito」と検索し選択します
② 「IDプール管理」を選択します
③ 適当に「プール名」を付け、チェックボックスにチェックを入れ、「プールを作成」を押します※
④ 特に何もせず「許可」を押します
完了すると、セットアップコードとともに自分のIDが表示されているはずです。※
(以下はiOSの場合)
他の画面でも閲覧可能ですが、探すのが面倒になるので一旦こちらで入手できるIDを控えておきましょう。
※
AWS Cognitoを使用することで、サインアップ・サインインの機能を実装できます。
今回はその機能は実装せずにRekognitionの機能だけを使用したいので、チェックを入れることで回避します。
※
ドキュメントのコードが少し古いので、そのまま使用することはできないので注意が必要です。
② Rekognitionを使用する権限を与える
先ほど作成したIDに、RekognitionのIAMポリシー(権限)をアタッチ(付与)していきます。※
(IDとは管理画面が違うので注意してください。)
① IAMポリシーコンソールから「ポリシー」を選択します
② 検索窓から「AmazonRekognitionReadOnly」を絞り込みます。
③ 絞り込んだものにチェックをつけ、「ポリシーアクション」から「アタッチ」を選択します
④ 「Cognito_xxx Unauth_Role」にチェックをつけ、「ポリシーのアタッチ」を押します(xxxは作成したプール名が入る)
AWS側の設定はこれで完了です。
※
AWSでは各機能のアクセス権のことをポリシーという名称で表しており、それをIAMで管理します。
(IAM = Identity and Access Management)
2. アプリ側の実装
① Podの準備
適当なプロジェクト作成し、CocoaPodsを導入しましょう。
pod 'AWSRekognition'
AWS Rekognitionを使用するために、Podfileに記載してインストールします。
② AWSのセットアップ
起動した時にAWSのセットアップを行います。
import UIKit
import AWSCore
@UIApplicationMain
final class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
let credentialsProvider = AWSCognitoCredentialsProvider(
regionType: .USEast2,
identityPoolId: "xxxxxx" // set your pool id
)
let configuration = AWSServiceConfiguration(
region: .USEast2,
credentialsProvider: credentialsProvider
)
AWSServiceManager.default().defaultServiceConfiguration = configuration
return true
}
}
(regionは人によって違う可能性があります)
identityPoolIdは各自が作成したものをセットしてください。
先ほどは、CIが設定してくれたものを自前で行っています。
③ 「顔認識」をしてみる
(1) 「顔認識」をしてみる
プロジェクト上にある画像をImage Literalでおいて読み込んでいます。
(先ほどと同じくBundleを使用しても可能です。ただし、変換が必要になります。)
import AWSRekognition
private var rekognitionObject: AWSRekognition?
private func detectFaces(with image: UIImage) {
let image: UIImage = /* image literal */
let rekognitionImage = AWSRekognitionImage()
rekognitionImage?.bytes = image.jpegData(compressionQuality: 0.5)
guard let frequest = facesRequest else { return }
rekognitionObject = AWSRekognition.default()
rekognitionObject?.detectFaces(frequest) { response, error in
if let r = response {
debugPrint("----success----", r)
} else if let e = error {
debugPrint("----failure----", e)
}
}
}
このあたりは、先ほどのAmplifyとはメソッド名が少し変わりましたが、大体同じような仕様になっています。
(2) 「有名人の認識」をしてみる
せっかくなので、先ほどとは違う機能を試してみます。
import AWSRekognition
private var rekognitionObject: AWSRekognition?
private func recognizeCelebrities() {
// 画像のリクエスト作成
let image: UIImage = /* image literal */
let rekognitionImage = AWSRekognitionImage()
rekognitionImage?.bytes = image.jpegData(compressionQuality: 0.5)
let rekognitionRequest = AWSRekognitionRecognizeCelebritiesRequest()
rekognitionRequest?.image = rekognitionImage
guard let request = rekognitionRequest else { return }
// リクエスト
rekognitionObject = AWSRekognition.default()
rekognitionObject?.recognizeCelebrities(request) { result, error in
if let r = result {
debugPrint("----success----", r)
} else if let e = error {
debugPrint("----failure----", e)
}
}
}
試しにドナルド・トランプの画像を使用してみたところ
ちゃんと画像が判定されていることがわかります。
AWSの設定がうまくいってないと、以下のようなエラーが返ってきます。
Error Domain=com.amazonaws.AWSCognitoIdentityErrorDomain Code=10 "(null)"
UserInfo={__type=ResourceNotFoundException, message=IdentityPool 'xxxxxx’ not found.}
(この場合は権限が設定されていないというエラー)
あとがき
公式のリファレンスではIAMについての記述が少しわかりずらく、管理画面を操作するのに若干苦労しましたが、、
firebaseと比べると、サーバーとの通信が走る分1秒ほど体感速度は遅いようにも感じます。
普通に設定すると面倒だなぁ、、
とは思いつつも、アプリをスケールさせる前提で機能を使うにはとても良いような気がします。
AWS Amplifyを使用することでサクっとアプリを開発。
大きくなったらちゃんと設定運用するといった手法が取れるのは、firebaseよりもメリットなような気はします。
撮影している動画の顔をリアルタイムに行えるかどうか、の検証は時間があれば行いたいと思いますが、、
おそらく細切れにした画像をいくつもリクエストすることになり、無料枠がすぐに埋まってしまいそうな気がしている、、笑