(別の課題もあって)いつまでもこれにかかっているワケにはいかないのだが、気になる(+結果が分かりやすい)ので引き続き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