#はじめに
re:Invent 2016でRekognitionというAIを活用した画像認識サービスが発表されました。
ということで、今回はこのサービスを使用して顔認証システムを作ってみました。
#Rekognitionとは
ここから「Try Demo」で試すことができます。
開発する時には、様々な言語をサポートしているので、得意なもので書きましょう。
残念ながら、東京リージョンにはまだありませんのでご注意ください。
できることは大きく分けて以下の4つです。
####1.物体とシーンの検出
「この写真には○○が写ってる」や「こんな場面で撮られたんでは」などなどをラベル付けしてくれます。
例えばこんな感じ。
朝食っぽい画像をアップロードしてみました。
ちゃんとラベルに「Breakfast」がありますね。
ラベルの隣の数値は信頼度です。「97%朝食の画像っぽい」ということを判定してくれているようです。
####2.顔分析
画像内の顔の位置を特定して、その人の感情を判定してくれます。
例えば
こちらの画像のタイトルは「腕を組んで怒る彼女」でした。
ちゃんと顔の位置を判断してくれていて、ラベルも「not smailing」や「angry」などタイトル通りの結果を返してくれています。
性別も判定してくれるようですね。
####3.顔照合
同じ人が写っている2枚の画像を比較して、同一人物かどうかを判定してくれます。
またまた例えば
こんな風に顔を抽出して同一人物か判定してくれます。
(ちなみに写真は「日本一インターネットで顔写真が使われているフリー素材モデル」さんです。)
####4.顔認識
あらかじめ作っておいたコレクションから、判定してほしい画像と同一人物を探してくれます。
顔照合が「1:1」だったのに対し、こちらは「1:多」で使用できます。
今回作ったものはこれを利用しています。
#今回作ったもの
今回作成した顔認証システムについてご紹介します。
JavaScriptで実装しました。大まかな構成は以下の図です。
■画像の登録
①S3バケットに画像をアップロードする
②それをトリガーにLambdaが動く
③LambdaがRekognitionのコレクションに画像を登録する
// 一部抜粋
exports.handler = function(event, context) {
console.log("strat import");
//pathを取得
var key = event.Records[0].s3.object.key;
var ids = key.split('/');
var params = {
CollectionId: "コレクション名",
DetectionAttributes: [
],
ExternalImageId: ids[ids.length-1],
Image: {
S3Object: {
Bucket: "バケット名",
Name: key
}
}
};
rekognition.indexFaces(params, function(err, data) {
if (err) console.log(err, err.stack);
else console.log(data);
});
}
■画像の削除
①S3バケット内の画像を削除する
②それをトリガーにLambdaが動く
③LambdaがRekognitionのコレクションの画像から削除対象を検索し、削除する
// 一部抜粋
exports.handler = (event, context, callback) => {
//共通変数
var collectionId = 'コレクション名'
//pathを取得
var key = event.Records[0].s3.object.key;
var ids = key.split('/');
var externalImageId = ids[ids.length-1];
// 検索用
function isThisName(element, index, array){
if(element == null || element.ExternalImageId!=externalImageId){
var param = {};
param.elementExternalImageId=element.ExternalImageId;
param.externalImageId=externalImageId;
param.message = 'error:Image not found';
return false;
}
return true;
}
// コレクションの顔一覧から名前を指定して探し出してDelete
var params = {
CollectionId: collectionId,
MaxResults: 20
};
rekognition.listFaces(params, function(err, data) {
if (err) console.log(err, err.stack);
else{
try{
var deleteId = data.Faces.find(isThisName).FaceId;
console.log('Face name detected! : ' + externalImageId); // コンソールに見つけた画像のIDを出力
var params = {
CollectionId: collectionId,
FaceIds: [
deleteId
]
};
rekognition.deleteFaces(params, function(err, data) {
if (err) console.log(err, err.stack);
else console.log(data + ' delete completed'); //正常に削除された場合
});
}catch(err){
console.log(err);
}
}
});
};
↑ここまでが顔認証するための下準備的な感じ↑
■顔認証
①画像をAPI GatewayにPOSTする
②それを(略)
③LambdaがRekognitionのコレクションから類似率の高い画像を探してくる
④類似率と類似率の高い画像の名前を返す
// 一部抜粋
exports.handler = (event, context, callback) => {
var response = {};
response.result = "ERROR";// デフォルトはエラー
response.matchedFaces = null;
response.stackTrace = null;
console.log(JSON.stringify(event));
console.log(JSON.stringify(event.base64Image));
var bufferImage = new Buffer(event.base64Image, 'base64');
var params = {
CollectionId: "コレクション名",
FaceMatchThreshold: 0,
Image: {
Bytes: bufferImage
},
MaxFaces: 5
};
rekognition.searchFacesByImage(params, function(err, data) {
if (err){
console.log(err, err.stack);
response.stackTrace = err.stack;
callback( null , response);
}
else{
if(data == null || data.FaceMatches == null || data.FaceMatches.length <= 0){
response.result = "NG";
response.matchedFaces = null;
callback( null , response);// マッチする顔画像がなかった場合
}else{
response.result = "OK";
response.matchedFaces = data.FaceMatches;
callback( null , response);// マッチする顔画像があった場合
}
}
});
};
そして顔認証を実行した結果がこちら
{
"result": "OK",
"matchedFaces": [
{
"Similarity": 99.94152069091797,
"Face": {
"FaceId": "852daf16-fe77-5867-a5b2-d1474ca69297",
"BoundingBox": {
"Width": 0.6410260200500488,
"Height": 0.48076900839805603,
"Left": 0.19658100605010986,
"Top": 0.25641000270843506
},
"ImageId": "fa85cbbe-78ce-5e45-bd35-22aee327f427",
"ExternalImageId": "類似率の高い画像のタイトル",
"Confidence": 99.99440002441406
}
}
],
"stackTrace": null
}
result:同一人物っぽい画像があったらOKなかったらNGを返しています
Similarity:同一人物である確度は何%かどうか(今回は99%)
ExternalImageId:コレクション内の類似度の高い画像のタイトル
だいたいこれらの値を見れば、POSTした画像の人がどの写真の人と、どのくらいの確率で同一人物かが分かります。
#おわりに
ということで、今回はRekognitionを使って顔認証をしてみました。
AIとか顔認証とか、ちょっとハードルが高そうだと思っていましたが、いよいよ身近になってきたなぁという感じがします。
ドラ○もんの誕生もそう遠くないかもしれませんね。