AWS Amplify iOSで画像から著名人を検出する #reinvent

ネイティブアプリ用の新しいSDK「Amplify iOS」と「Amplify Android」がプレビューにて公開されました。iOSではPrediction(予測機能)が実装されています。本記事では、Amplify iOSを使って画像からの著名人の検出を試してみました。
2019.12.31

Rekognitionで画像から著名人を検出しよう

re:Invent 2019の期間中、ネイティブアプリ用の新しいSDKAmplify iOSAmplify Androidがプレビューにて公開されました。

その中で、iOSでは新たにPrediction(予測機能)が利用できるようになっています。これはつまりAWSのAI/ML系のサービスがiOSアプリから直接利用できる形になります。

本記事では、Amplify iOSを使って画像から著名人を検出する機能を試してみました。

AWSサービスとしてはAmazon Rekognitionを利用する形となります。

インストール

それではまずはインストールしていきます。なお、AmplifyのiOSアプリ向けプロジェクトはすでに作成済みの前提で進めます。また、今回は対話形式でのインストールが必要なためAmplify CLIを利用します。

まずは predictions というプラグインを追加します。

$ amplify add predictions

対話形式で、どのような機能を作りたいか問われます。

? Please select from one of the categories below : Identify
? What would you like to identify? : Identify Entities
? Provide a friendly name for your resource : identifyEntitiesec505499
? Would you like use the default configuration? : Default Configuration
? Who should have access? : Auth and Guest users

Prediction機能は以下のように分類されているので、自分の作りたい機能に合わせて設定します。本記事では Identify を選択しています。

? Please select from one of the categories below
❯ Identify
  Convert
  Interpret
  Infer
  Learn More

Identify を選択すると ? What would you like to identify? と、どのような種類の解釈を行いたいのか問われます。今回は Identify Entities とします。

? What would you like to identify?
  Identify Text
❯ Identify Entities
  Identify Labels

また、最後の Who should have access?Auth and Guest users を選び、Cognito User Poolsの作成を行うようにします。これはAWSリソースへのアクセスを行うため必須になります。

Successfully added resource identifyEntitiesec505499 locally

ローカルでの設定が完了したので amplify push でAWSリソースを作成します。

$ amplify push

| Category    | Resource name            | Operation | Provider plugin   |
| ----------- | ------------------------ | --------- | ----------------- |
| Predictions | identifyEntitiesec505499 | Create    | awscloudformation |
| Auth        | amplifysample93d65ae8    | No Change | awscloudformation |

以上でAWSリソースの作成は完了です。

次に AWSPredictionsPlugin というPodを追加します。Podfile 全体としては以下のようになります。

target 'AmplifySample' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for AmplifySample
  pod 'Amplify'
  pod 'AWSPluginsCore'
  pod 'AWSPredictionsPlugin'
  pod 'AWSMobileClient', '~> 2.12.0'
end

最後に pod install を実行して終わりです。

$ pod install --repo-update

実装

今回は画像から著名人の検出を行いたいだけなので、iOSアプリでは画面なしで実装します。

まずは AppDelegate でセットアップする処理を書きます。

AppDelegate.swift

import UIKit
import Amplify
import AWSPredictionsPlugin
import AmplifyPlugins

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        let predictionsPlugin = AWSPredictionsPlugin()
        do {
            try Amplify.add(plugin: predictionsPlugin)
            try Amplify.configure()
            print("Amplify initialized")
        } catch {
            print("Failed to configure Amplify \(error)")
        }
        return true
    }

}

次に ViewController で画像から著名人の検出を行う処理を実装します。detectCelebs() というメソッドを用意しました。

ViewController.swift

import UIKit
import Amplify

class ViewController: UIViewController {
    
    override func viewDidLoad() {
        super.viewDidLoad()
        detectCelebs()
    }
    
    func detectCelebs() {
        guard let path = Bundle.main.path(forResource: "sample-image-celeb", ofType: "jpg") else { return }
        let image = URL(fileURLWithPath: path)
        _ = Amplify.Predictions.identify(type: .detectCelebrity, image: image, options: PredictionsIdentifyRequest.Options(), listener: { (event) in
            switch event {
            case .completed(let result):
                let data = result as! IdentifyCelebritiesResult
                print(data)
            case .failed(let error):
                print(error)
            default:
                print("")
            }
        })
    }

}

対象の画像は URL 型で指定します。ローカルまたはWeb上の画像から指定します。上記は sample-image-celeb.jpg という画像ファイルをXcodeプロジェクト内に追加した場合のコードです。オフラインでの動作を試したい場合はXcodeプロジェクトに追加するようにしてください。

試してみる

それでは実行してみましょう。写真は適当な著名人の写真を用意します。本記事では以下のTaylor Swiftの画像をお借りしてみました。試したい場合はどのような画像でも良いです。

実行すると、著名人の名前と検出した顔のパーツの位置などがコンソールに表示されます(以下は見やすいように整形しています)。

IdentifyCelebritiesResult(
  celebrities: [
    Amplify.Celebrity(
      metadata: Amplify.CelebrityMetadata(
        name: "Taylor Swift", 
        identifier: "432Vg7K", 
        urls: [www.imdb.com/name/nm2357847], 
        pose: Amplify.Pose(
          pitch: -6.4970703125, 
          roll: -1.7734267711639404, 
          yaw: 2.1205666065216064
        )
      ), 
      boundingBox: (0.4216666519641876, 0.16342857480049133, 0.15166667103767395, 0.10400000214576721), 
      landmarks: [
        Amplify.Landmark(type: Amplify.LandmarkType.allPoints, points: [(0.46682244539260864, 0.2029060274362564), (0.5285396575927734, 0.20177385210990906), (0.5015084743499756, 0.22609077394008636), (0.4766225814819336, 0.24476268887519836),  (0.5215086340904236, 0.24332195520401)]), 
        Amplify.Landmark(type: Amplify.LandmarkType.leftEye, points: [(0.46682244539260864, 0.2029060274362564)]), 
        Amplify.Landmark(type: Amplify.LandmarkType.rightEye, points: [(0.5285396575927734, 0.20177385210990906)]), 
        Amplify.Landmark(type: Amplify.LandmarkType.leftEyebrow, points: []), 
        Amplify.Landmark(type: Amplify.LandmarkType.rightEyebrow, points: []), 
        Amplify.Landmark(type: Amplify.LandmarkType.nose, points: [(0.5015084743499756, 0.22609077394008636)]), 
        Amplify.Landmark(type: Amplify.LandmarkType.noseCrest, points: []), 
        Amplify.Landmark(type: Amplify.LandmarkType.outerLips, points: [(0.4766225814819336, 0.24476268887519836), (0.5215086340904236, 0.24332195520401)]), 
        Amplify.Landmark(type: Amplify.LandmarkType.leftPupil, points: []), 
        Amplify.Landmark(type: Amplify.LandmarkType.rightPupil, points: []), 
        Amplify.Landmark(type: Amplify.LandmarkType.faceContour, points: [])
      ]
    )
  ]
)

画像からスピーディに顔検出する仕組みを作ろう

著名人の顔検索を行うアプリは若者ウケが良さそうです。

著名人を扱う場合トレンドが非常に重要ですが、著名人情報のアップデートはRekognitionサービスにお任せできます。この辺りはサービスならではの利点ですね。

まずはぜひ試してみてください!