(別の課題もあって)いつまでもこれにかかっているワケにはいかないのだが、気になる(+結果が分かりやすい)ので引き続きCompare facesを調査
AWSが提供しているサンプルコードは以下。めちゃくちゃシンプル。S3上ではなく、ローカルに存在するイメージファイルを2つ指定して画像間の一致を計算するサンプルと理解。
# Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved. # PDX-License-Identifier: MIT-0 (For details, see https://github.com/awsdocs/amazon-rekognition-developer-guide/blob/master/LICENSE-SAMPLECODE.) import boto3 def compare_faces(sourceFile, targetFile): session = boto3.Session(profile_name='profile-name') client = session.client('rekognition') imageSource = open(sourceFile, 'rb') imageTarget = open(targetFile, 'rb') response = client.compare_faces(SimilarityThreshold=80, SourceImage={'Bytes': imageSource.read()}, TargetImage={'Bytes': imageTarget.read()}) for faceMatch in response['FaceMatches']: position = faceMatch['Face']['BoundingBox'] similarity = str(faceMatch['Similarity']) print('The face at ' + str(position['Left']) + ' ' + str(position['Top']) + ' matches with ' + similarity + '% confidence') imageSource.close() imageTarget.close() return len(response['FaceMatches']) def main(): source_file = 'source-file-name' target_file = 'target-file-name' face_matches = compare_faces(source_file, target_file) print("Face matches: " + str(face_matches)) if __name__ == "__main__": main()
Boto3の仕様書によると、対象ファイルはローカルに置かれている場合、S3に置かれている場合の両方が可能。教材としては、まずS3に画像をアップしてから、S3上のSourceとTargetを比較する方法で実装する方針
JSのサンプルは以下。前回作成した、Face Detectとほぼ同じ手順で実行できるので、ファイルを2つにして、API名を変えるだけでNodeを流用できそうだ
// Load the SDK var AWS = require('aws-sdk'); const bucket = 'bucket-name' // the bucketname without s3:// const photo_source = 'photo-source-name' // the name of file const photo_target = 'photo-target-name' var credentials = new AWS.SharedIniFileCredentials({profile: 'profile-name'}); AWS.config.credentials = credentials; AWS.config.update({region:'region-name'}); const client = new AWS.Rekognition(); const params = { SourceImage: { S3Object: { Bucket: bucket, Name: photo_source }, }, TargetImage: { S3Object: { Bucket: bucket, Name: photo_target }, }, SimilarityThreshold: 70 } client.compareFaces(params, function(err, response) { if (err) { console.log(err, err.stack); // an error occurred } else { response.FaceMatches.forEach(data => { let position = data.Face.BoundingBox let similarity = data.Similarity console.log(`The face at: ${position.Left}, ${position.Top} matches with ${similarity} % confidence`) }) // for response.faceDetails } // if });
Node-REDのオリジナルNodeのソースは以下
module.exports = (RED) => { function compareFacesNode(config) { RED.nodes.createNode(this,config); var node = this; node.on('input', function(msg) { cmpFaces(node, msg); }); } RED.nodes.registerType("compareFaces", compareFacesNode); } function cmpFaces(node, msg) { const AWS = require('aws-sdk'); const REGION = 'us-east-1'; const BUCKET = <bucket_name>; // e.g 'rekognition-bucket' const PHOTO_SRC = <src_photo_path_filename>; // e.g. 'face001.jpg' const PHOTO_TGT = <src_photo_path_filename>; // e.g. 'face002.jpg' const PROFILENAME = 'default'; const credentials = new AWS.SharedIniFileCredentials({profile: PROFILENAME}); AWS.config.credentials = credentials; AWS.config.update({region:REGION}); const client = new AWS.Rekognition(); const params = { SourceImage: { S3Object: { Bucket: BUCKET, Name: PHOTO_SRC}, }, TargetImage: { S3Object: { Bucket: BUCKET, Name: PHOTO_TGT}, }, SimilarityThreshold: 70 } console.log("i'll call AWS Recognition (comparing faces)"); client.compareFaces(params, (err, response) => { if (err) { console.log(err, err.stack); // an error occurred msg.payload = "Error at AWS Rekognition (comparing faces)"; msg.payload = err; node.send(msg); } else { console.log(`comparing faces with: ${PHOTO_SRC}/${PHOTO_TGT}`); msg.payload = response.FaceMatches[0]; // care... take first object without check node.send(msg); } }); return (true); // no need return value }
上記オリジナルNodeをNode-REDに登録して、2枚の写真をS3にアップして比較してみた。適当に自分の顔を撮影した2枚の写真ですが、類似度は99.996と判定された。上記JSソースは、一致度配列の要素が1以上を前提に組んでしまっているので、一致しないケースを想定して、sizeチェックしてから、先頭要素を取り出すべし
残作業
- ソースの仕上げ(要素数確認、エラー処理等)
- S3アップロードNodeにおいて、ファイルが固定なので、上流Nodeでファイル名指定できるように改良
- 全体を1フローにまとめた場合に正常に動作するのかを確認
- compareFacesでは、ループで連続的に一致判断できるかを確認
おまけ
この4日間は、JS三昧であった(Pythonをほとんど使っていない)
■参考URL
イメージ間の顔の比較 - Amazon Rekognition
compare_faces - Boto3 1.28.35 documentation
Amazon Rekognition(高精度の画像・動画分析サービス)| AWS