Amazon Rekognitionを利用してAndrodアプリから顔の類似度を確認する


Amazon Rekognitionを利用して人物の顔の類似度の確認を行ってみたので、まとめておきます。
今回はAndroidアプリから確認しています。

Amazon Rekognitionって?

詳しい説明については、多くのわかりやすい記事があるのでそちらに譲ります。
ざっくり説明すると、顔同士を比較し類似度を確認することができるAWSのサービスです。
類似度の確認以外にも、表情の分析や有名人の判別など、色々と面白いことができそうです。

Amplifyの初期設定

AndroidアプリからAmazon Rekognitionを利用するため、AWSの環境はAmplifyを使って構築していきます。
ドキュメントが非常にわかりやすいので、基本はドキュメント通りに進めていけば問題有りません。

まずは、CLIからAmplifyを利用するためにパッケージをインストールします。

$ npm install -g @aws-amplify/cli

下記コマンドで正しくバージョンが表示されれば、インストール成功です。

$ amplify --version

次に、Amplifyの設定を行っていきます。

$ amplify configure
Follow these steps to set up access to your AWS account:

Sign in to your AWS administrator account:
https://console.aws.amazon.com/
Press Enter to continue

Specify the AWS Region
? region:  us-east-1  # 任意のリージョンを指定してください
? user name:  amplify  # Amprify操作用の任意のIAMユーザーを指定してください
Complete the user creation using the AWS console
Press Enter to continue

ここまで設定してEnterボタンを押下すると、AWSコンソールが開いてIAMユーザーの作成へと進みます。
今回は AdministorAccess を付与していますが、適宜適切な権限を付与してください。
最後の アクセスキーIDシークレットアクセスキー は後ほど使用するので、控えておいてください。

ターミナルに戻って、上記で控えた アクセスキーIDシークレットアクセスキー を設定します。
Profile Name はわかりやすいように amplify としています。

Enter the access key of the newly created user:
? accessKeyId:  ********************
? secretAccessKey:  ****************************************
? Profile Name:  amplify  # 任意の名前

Successfully set up the new user.

aws cliのプロファイルを追加しておきます。

$ aws configure --profile amplify
AWS Access Key ID: ********************
AWS Secret Access Key: ****************************************
Default region name: us-east-1
Default output format: json

Androidアプリの初期設定

Androidアプリ側に設定を行っていきます。
こちらも、基本的にドキュメント通りです。

アプリの build.gradle を下記のように設定します。

build.gradle
android {
    compileOptions {
        // Support for Java 8 features
        coreLibraryDesugaringEnabled true
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

dependencies {
    // Amplify core dependency
    implementation 'com.amplifyframework:core:1.17.0'

    // Support for Java 8 features
    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5'
}

正常にビルドできればOKです!

Amplifyの設定

引き続き、Amplifyの設定をターミナルから行います。

$ amplify init
? Enter a name for the project YourAppName  # 任意のアプリ名
? Enter a name for the environment dev  # Amplifyで管理する任意の環境名
? Choose your default editor: Visual Studio Code  # 任意のIDEの指定
? Choose the type of app that you are building: android
? Where is your Res directory:  app/src/main/res
? Select the authentication method you want to use: AWS profile
? Please choose the profile you want to use amplify  # 先程作成したaws cliのプロファイル名を指定

以上で環境が構築され、AWS Amplifyのコンソールから確認できるようになります。

Amazon Rekognitionの設定

AmplifyからAmazon Rekognitionを利用するための設定して行っていきます。
こちらも詳細についてはドキュメントを確認してください。

Amplifyで predictions を追加します。
Detect pre-determined entities in an imageの設定を参考に進めます。

$ amplify add predictions
? Please select from one of the categories below Identify
? You need to add auth (Amazon Cognito) to your project in order to add storage for user files. Do you want to add auth now? Yes

Using service: Cognito, provided by: awscloudformation

 The current configured provider is Amazon Cognito. 

 Do you want to use the default authentication and security configuration? Default configuration
 Warning: you will not be able to edit these selections. 
 How do you want users to be able to sign in? Email
 Do you want to configure advanced settings? No, I am done.
Successfully added auth resource hogehoge locally

? Please select from one of the categories below Identify
? What would you like to identify? Identify Entities
? Provide a friendly name for your resource identifyEntitiesfugafuga
? Would you like use the default configuration? Advanced Configuration
? Would you like to enable celebrity detection? No
? Would you like to identify entities from a collection of images? Yes
? How many entities would you like to identify? 10
? Would you like to allow users to add images to this collection? Yes
? Who should have access? Auth and Guest users

設定完了後、下記のコマンドで反映します。

$ amplify push

比較する顔画像の登録

Androidアプリから送信される画像と比較するための画像を登録します。(ドキュメントはこちら
CLIから行っていきます。

まずは、コレクションの一覧表示を行って、作成されたコレクションを確認しましょう。

$ aws rekognition list-collections
{
    "FaceModelVersions": [
        "5.0"
    ],
    "CollectionIds": [
        "identifyEntitiesfugafuga-dev"  # コレクションのID
    ]
}

次に、作成されたコレクションに対し画像を追加します。
比較するための画像として、フリー素材で見つけた下記の素敵な女性を利用させていただきます。
この画像を任意のS3バケットに保存してください。

下記コマンドから、コレクションに対して画像を追加します。
bucket-name には画像を保存したS3バケット名、file-name には画像名を指定してください。
collection-id には、先程確認したコレクションのIDを指定してください。
また、 example-image.jpg の部分には、画像を判別するための一意の名前を指定してください。

aws rekognition index-faces \
      --image '{"S3Object":{"Bucket":"bucket-name","Name":"file-name"}}' \
      --collection-id "collection-id" \
      --max-faces 1 \
      --quality-filter "AUTO" \
      --detection-attributes "ALL" \
      --external-image-id "example-image.jpg" 

以上で、比較用の画像が登録されました。

Androidアプリの設定

Androidアプリ側に、下記のように設定していきます。

アプリのbuild.gradleに追記します。

build.gradle
dependencies {
    implementation 'com.amplifyframework:aws-predictions:1.16.15'
    implementation 'com.amplifyframework:aws-auth-cognito:1.16.15'
}

次に MainActivity.kt を修正します。
比較対象の顔画像として、先程の画像と同一人物の別のフリー画像を用意しました。
drawable 内に woman.jpg として保存します。

今回はアプリ内に保存した画像を使用しますが、実際の運用ではカメラやギャラリーから画像を取得して比較する形になるかと思います。

MainActivity.kt
class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        try {
            Amplify.addPlugin(AWSCognitoAuthPlugin())
            Amplify.addPlugin(AWSPredictionsPlugin())
            Amplify.configure(applicationContext)
            Log.i("MainActivity", "Initialized Amplify")
        } catch (error: AmplifyException) {
            Log.e("MainActivity", "Could not initialize Amplify", error)
        }

        // 顔画像を取得
        val image = BitmapFactory.decodeResource(resources, R.drawable.woman)

        Amplify.Predictions.identify(IdentifyActionType.DETECT_ENTITIES, image,
                { result ->
                    val identifyResult = result as IdentifyEntityMatchesResult
                    val match = identifyResult.entityMatches.firstOrNull()
                    Log.i("AmplifyQuickstart", "externalImageId: ${match?.externalImageId}")
                    Log.i("AmplifyQuickstart", "confidence: ${match?.confidence}")
                },
                { Log.e("AmplifyQuickstart", "Identify failed", it) }
        )
    }
}

類似度の確認

Androidアプリを起動しましょう。
Logcatに下記のように出力されます。

I/AmplifyQuickstart: externalImageId: 設定したexternal-image-id
I/AmplifyQuickstart: confidence: 99.99981

confidence が類似度(信頼度)を表します。
同一人物なので、もちろん類似度は高いですね!

手順は少し多いですが、比較的簡単に顔画像の比較が実装できたと思います!