如何使用AWS Rekognition批量匹配人脸?PHP SDK场景优化咨询
优化AWS Rekognition人脸匹配效率的方案
AWS Rekognition的CompareFaces本身是一对一的比对接口,没有直接的批量多目标匹配API,但可以通过以下两种方式大幅缩短耗时:
方案一:用人脸集合(Collection)实现高效匹配
适合需要反复用同一张/多张源人脸比对大量自拍照的场景,步骤如下:
1. 创建人脸集合(仅需执行一次)
先创建一个专属的人脸集合,用来存储相册里的源人脸:
<?php try { $this->client->createCollection([ 'CollectionId' => 'user_album_faces' // 自定义集合ID,比如关联用户ID ]); } catch (Exception $e) { // 集合已存在时会抛异常,直接忽略即可 }
2. 把源相册照片的人脸索引到集合(仅需执行一次,源照片更新时重新执行)
将你用来比对的相册照片人脸存入集合,建立索引:
<?php $binary_source_face_image = file_get_contents($source_photo_path); try { $this->client->indexFaces([ 'CollectionId' => 'user_album_faces', 'Image' => ['Bytes' => $binary_source_face_image], 'QualityFilter' => 'HIGH' ]); } catch (Exception $e) { // 处理索引失败的情况,比如照片无清晰人脸 }
3. 批量搜索自拍照
对每张自拍照调用SearchFacesByImage,直接在集合中查找匹配的人脸,比CompareFaces效率更高:
<?php $matched_images = []; foreach ($user_bio_selfies as $selfi) { $selfi_path = $user_selfi_path . $selfi['image']; if (!file_exists($selfi_path)) continue; $binary_target_image = file_get_contents($selfi_path); try { $result = $this->client->searchFacesByImage([ 'CollectionId' => 'user_album_faces', 'Image' => ['Bytes' => $binary_target_image], 'SimilarityThreshold' => 70, 'QualityFilter' => 'HIGH' ]); $response = $result->toArray(); if (!empty($response['FaceMatches'])) { // 注意这里取的是Similarity字段,和CompareFaces的返回略有不同 $matched_face = number_format($response['FaceMatches'][0]['Similarity'], 2, '.', ''); if ($matched_face >= 30) { $matched_images[] = [ 'image' => base_url(USER_IMAGE_SITE_PATH) . $selfi['image'], 'confidence' => $matched_face ]; } } } catch (Exception $e) { // 处理单张照片的比对异常 } }
优势:集合是索引化的,搜索速度远高于两两比对;后续新增自拍照时,无需重复处理源照片。
方案二:并发调用API减少串行等待时间
如果只是临时一次性比对,不想创建集合,可以用并发请求同时发起多个CompareFaces调用,避免串行等待的时间损耗。比如用Guzzle实现并发:
<?php use GuzzleHttp\Client; use GuzzleHttp\Promise; // 初始化Guzzle客户端,需要配置AWS签名(可复用SDK的签名逻辑) $guzzleClient = new Client(); $promises = []; $matched_images = []; // 预先编码源照片,避免重复处理 $sourceBase64 = base64_encode($binary_source_face_image); foreach ($user_bio_selfies as $selfi) { $selfi_path = $user_selfi_path . $selfi['image']; if (!file_exists($selfi_path)) continue; $targetBase64 = base64_encode(file_get_contents($selfi_path)); // 构造CompareFaces的异步请求 $promises[$selfi['image']] = $guzzleClient->postAsync('https://rekognition.us-east-1.amazonaws.com/', [ 'headers' => [ 'Content-Type' => 'application/x-amz-json-1.1', 'X-Amz-Target' => 'RekognitionService.CompareFaces', // 这里需要添加AWS签名的Header,可参考AWS SDK的签名方式 ], 'json' => [ 'QualityFilter' => 'HIGH', 'SimilarityThreshold' => 70, 'SourceImage' => ['Bytes' => $sourceBase64], 'TargetImage' => ['Bytes' => $targetBase64] ] ]); } // 等待所有请求完成并处理结果 $results = Promise\Utils::unwrap($promises); foreach ($results as $imageName => $response) { $data = json_decode($response->getBody(), true); if (!empty($data['FaceMatches'])) { $matched_face = number_format($data['FaceMatches'][0]['Face']['Confidence'], 2, '.', ''); if ($matched_face >= 30) { $matched_images[] = [ 'image' => base_url(USER_IMAGE_SITE_PATH) . $imageName, 'confidence' => $matched_face ]; } } }
注意:并发请求要控制数量,避免触发AWS的API调用限额;可以根据限额调整并发数(比如一次同时发10个请求)。
额外优化点
- 把照片存在S3里,用
S3Object参数替代Bytes传递,减少本地IO和数据传输量 - 合理调整
SimilarityThreshold和QualityFilter,过滤低质量照片减少无效调用 - 比对完成后,调用
DeleteCollection删除临时集合,避免占用资源
内容的提问来源于stack exchange,提问作者Mitesh Rathod
相关产品推荐
相关产品推荐

