You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于AWS Rekognition人脸边界框裁剪图片并检索人脸集的技术问询

刚好我之前在Lambda里实现过一模一样的流程,给你整理了Python和Node.js两种版本的代码,直接就能用,还附带了关键步骤的说明:

Python 实现方案

前置准备

Lambda默认环境没有图片处理库,所以需要把Pillow打包成Lambda层(或者本地打包后和代码一起上传)。如果用层的话,在本地执行pip install pillow -t python/lib/python3.x/site-packages(替换成你Lambda用的Python版本),然后压缩成zip上传为Lambda层即可。

完整代码示例

import boto3
from PIL import Image
import io

# 初始化客户端
rekognition = boto3.client('rekognition')
s3 = boto3.client('s3')

def lambda_handler(event, context):
    # 假设输入是S3的桶名和文件名,你也可以改成处理base64图片的逻辑
    bucket = event['bucket']
    image_key = event['image_key']
    collection_id = '你的人脸集合ID'

    # 第一步:调用DetectFaces获取人脸边界框
    detect_response = rekognition.detect_faces(
        Image={'S3Object': {'Bucket': bucket, 'Name': image_key}},
        Attributes=['DEFAULT']
    )

    if not detect_response['FaceDetails']:
        return {'message': '未检测到人脸'}

    # 获取第一张人脸的边界框(如果有多张可以循环处理)
    face_box = detect_response['FaceDetails'][0]['BoundingBox']
    
    # 第二步:下载原始图片并裁剪
    # 从S3下载图片到内存
    s3_response = s3.get_object(Bucket=bucket, Key=image_key)
    image_bytes = s3_response['Body'].read()
    img = Image.open(io.BytesIO(image_bytes))
    img_width, img_height = img.size

    # 把相对比例的边界框转成像素坐标
    left = int(face_box['Left'] * img_width)
    top = int(face_box['Top'] * img_height)
    width = int(face_box['Width'] * img_width)
    height = int(face_box['Height'] * img_height)

    # 裁剪人脸区域
    cropped_img = img.crop((left, top, left + width, top + height))

    # 把裁剪后的图片转成字节流
    buffer = io.BytesIO()
    cropped_img.save(buffer, format='JPEG')
    cropped_bytes = buffer.getvalue()

    # 第三步:调用SearchFacesByImage检索人脸集合
    search_response = rekognition.search_faces_by_image(
        CollectionId=collection_id,
        Image={'Bytes': cropped_bytes},
        MaxFaces=5,
        FaceMatchThreshold=80.0
    )

    return {
        'face_matches': search_response['FaceMatches'],
        'original_face_count': len(detect_response['FaceDetails'])
    }

关键注意点

  • 边界框转换:DetectFaces返回的是相对比例值,必须乘以图片实际宽高才能得到像素坐标,不然裁剪出来的区域会完全不对
  • 权限配置:Lambda角色需要添加RekognitionDetectFaces、RekognitionSearchFacesByImage权限,如果图片存在S3,还要加上s3:GetObject权限
  • 内存/超时:建议给Lambda分配至少256MB内存,超时设置为10-15秒,避免处理大图片时超时

Node.js 实现方案

前置准备

我们用sharp来处理图片(比jimp更高效,适合Lambda环境),需要把依赖打包。本地执行npm install sharp,然后把node_modules和代码一起压缩上传,或者做成Lambda层。

完整代码示例

const AWS = require('aws-sdk');
const sharp = require('sharp');

// 初始化客户端
const rekognition = new AWS.Rekognition();
const s3 = new AWS.S3();

exports.handler = async (event) => {
    // 同样假设输入是S3桶名和文件名,可自行修改为base64处理逻辑
    const { bucket, image_key, collection_id = '你的人脸集合ID' } = event;

    try {
        // 第一步:调用DetectFaces获取人脸边界框
        const detectParams = {
            Image: { S3Object: { Bucket: bucket, Name: image_key } },
            Attributes: ['DEFAULT']
        };
        const detectResponse = await rekognition.detectFaces(detectParams).promise();

        if (!detectResponse.FaceDetails || detectResponse.FaceDetails.length === 0) {
            return { message: '未检测到人脸' };
        }

        // 获取第一张人脸的边界框
        const faceBox = detectResponse.FaceDetails[0].BoundingBox;

        // 第二步:下载图片并裁剪
        const s3Response = await s3.getObject({ Bucket: bucket, Key: image_key }).promise();
        const imageBuffer = s3Response.Body;

        // 获取图片实际尺寸
        const metadata = await sharp(imageBuffer).metadata();
        const imgWidth = metadata.width;
        const imgHeight = metadata.height;

        // 转换边界框为像素坐标
        const left = Math.floor(faceBox.Left * imgWidth);
        const top = Math.floor(faceBox.Top * imgHeight);
        const width = Math.floor(faceBox.Width * imgWidth);
        const height = Math.floor(faceBox.Height * imgHeight);

        // 裁剪人脸区域
        const croppedBuffer = await sharp(imageBuffer)
            .extract({ left, top, width, height })
            .jpeg()
            .toBuffer();

        // 第三步:调用SearchFacesByImage检索集合
        const searchParams = {
            CollectionId: collection_id,
            Image: { Bytes: croppedBuffer },
            MaxFaces: 5,
            FaceMatchThreshold: 80.0
        };
        const searchResponse = await rekognition.searchFacesByImage(searchParams).promise();

        return {
            face_matches: searchResponse.FaceMatches,
            original_face_count: detectResponse.FaceDetails.length
        };
    } catch (error) {
        console.error('处理出错:', error);
        return { error: error.message };
    }
};

关键注意点

  • sharp的extract方法接受的是像素坐标,所以必须做好比例转换
  • Lambda环境需要Node.js 16+版本来兼容最新的sharp版本
  • 同样要确保Lambda角色拥有对应的Rekognition和S3权限

内容的提问来源于stack exchange,提问作者db46

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:33:34