CloudBrum
CloudBrum · Cloud decision-support platform
AWS AI and machine learning

Amazon RekognitionLast reviewedReading time~12 minLevelBeginner to advanced

Amazon Web Services · AI and machine learning · Image and video analysis

Amazon Rekognition is AWS’s ready-made picture and video analyser: you send an image, it sends back JSON that says what is in it. Labels, text, unsafe content, faces and whether a live person is in front of the camera are all separate calls, and none of them needs a model of your own. The part that takes care is what you do with the answer. A confidence score is not a verdict, and a face match is a statement about similarity, not about identity.

On this page (17 sections)

    Mind map: Amazon Rekognition at a glance

    Amazon Rekognition mind map Amazon Rekognition at a glance: Pictures: Labels and colours, Text in photos, Image quality; Safety: Moderation labels, Custom adapters, Review queue; Faces: Detect and compare, Collections and search, Users and vectors; Identity checks: Face Liveness, Audit images, Thresholds; Video: Stored video jobs, SNS notices, Streaming (closed to new); Your own model: Custom Labels, Training hours, Inference hours; Security: IAM and S3 access, KMS and VPC endpoints, AI opt-out policy; Pricing: Per image, Per video minute, Per stored face. Amazon Rekognition at a glance Picture and video analysis on AWS: the main building blocks and decisions CloudBrum Cloud decision-support platform CloudBrum Labels and colours Text in photos Image quality Pictures Moderation labels Custom adapters Review queue Safety Detect and compare Collections and search Users and vectors Faces Face Liveness Audit images Thresholds Identity checks Stored video jobs SNS notices Streaming (closed to new) Video Custom Labels Training hours Inference hours Your own model IAM and S3 access KMS and VPC endpoints AI opt-out policy Security Per image Per video minute Per stored face Pricing Rekognition17-point analysis CloudBrum· 17-point cloud service analysis cloudbrum.com
    CloudBrum Rekognition at a glance · 17-point analysis Pictures Labels and colours Text in photos Image quality Safety Moderation labels Custom adapters Review queue Faces Detect and compare Collections and search Users and vectors Identity checks Face Liveness Audit images Thresholds Video Stored video jobs SNS notices Streaming (closed to new) Your own model Custom Labels Training hours Inference hours Security IAM and S3 access KMS and VPC endpoints AI opt-out policy Pricing Per image Per video minute Per stored face CloudBrum · cloudbrum.com

    Free to share. The downloaded image includes the CloudBrum link.

    Key features (summary)

    • LabelsDetectLabels names the objects, scenes and activities in a picture, groups them into categories and can add the dominant colours and a rough quality reading (brightness, sharpness). It is the call behind most photo search and auto-tagging.
    • ModerationDetectModerationLabels scores a picture against a two-level list of unsafe topics. A child label always comes with its parent, so you can write one rule for the parent. Custom moderation adapters let you correct its mistakes on your own content.
    • Text in the sceneDetectText reads signs, packaging, number plates and captions in a photo and returns words and lines with positions. It is made for scene text. For a scanned form or invoice, Amazon Textract is the better tool.
    • Face detection and comparisonDetectFaces returns where each face is, its landmarks, pose and quality, and attributes such as an open mouth or glasses. CompareFaces measures how alike a face in one picture is to faces in another.
    • Face collectionsIndexFaces stores a mathematical vector for each face, not the photo. SearchFacesByImage then finds the closest stored faces. Several vectors of one person can be grouped under a user to make matching steadier.
    • Face LivenessA short session in which the user’s phone or browser records a face while a coloured light plays over it. The service answers with a live-or-not score and a few audit images. It targets photo, screen and mask spoofing at sign-up.
    • Stored videoStart a job on a video in S3 for labels, faces, moderation, text, people tracking or shot detection. The job runs in the background, tells an SNS topic when it ends, and you read the results page by page.
    • Custom LabelsTrain a model on your own labelled pictures to find things Rekognition has no name for, such as your own parts or defects. You pay for training time and for every hour a trained model is running.

    Basic concepts

    Label
    A name Rekognition gives to something it sees, with a confidence between 0 and 100. Labels have parents, so "Sedan" sits under "Car" under "Vehicle".
    Confidence
    How sure the model is that its answer is right. It is not the share of the picture covered or a probability you can calibrate for your own data.
    Moderation label
    A name from the unsafe-content taxonomy. A top-level category such as Violence has child labels, and every child returns its parent in ParentName.
    Bounding box
    A rectangle given as fractions of the image width and height, so it works at any resolution. Multiply by the pixel size to draw it.
    Face collection
    A server-side store of face vectors in one Region. It holds no pictures, and one collection should serve one purpose.
    Face vector
    The numbers Rekognition derives from a face. Each one gets a FaceId, and the ExternalImageId you pass with the picture is attached to every face found in it, so index one person per picture.
    User vector
    A person in a collection, made by associating several face vectors with a user id. A search by user compares against all of that person’s faces.
    Similarity
    The score from CompareFaces and SearchFaces. It says how close two faces are. It does not say that they belong to the same person.
    Face model version
    The version of the matching model a collection was built with. Vectors from different versions can’t be compared, so a new model means re-indexing from the pictures.
    Quality filter
    A setting on IndexFaces and SearchFacesByImage that drops faces that are blurred, dark, tiny or turned away. AUTO is the usual choice.
    Face Liveness session
    A one-time session you create on the server, run in the user’s app or browser, then read results from by session id. It returns a score and up to four audit images.
    Audit image
    A frame saved during liveness, kept so a person can look at a doubtful case later.
    Job
    An asynchronous video analysis. You start it, get a JobId, wait for the SNS message and then page through results with the matching Get call.
    Custom Labels project
    A container for the datasets and trained model versions of one custom detection task.
    Inference unit
    The capacity a Custom Labels model runs on while it is started. It bills for every hour it runs, used or not.

    How to create & configure it

    Screen an upload and search a face collection with the AWS CLI

    1. Write down the decision first"Block unsafe pictures", "tag photos for search" and "let staff in" are very different jobs. Say what a wrong answer costs, because that decides thresholds and whether a person reviews the result.
    2. Pick the Region and keep the pictures in itRekognition reads from S3 in the same Region as the call. The pages here assume Mumbai (ap-south-1); check that each feature you need is offered there, Face Liveness included.
    3. Create a private bucketBlock public access, turn on encryption, and give uploads a lifecycle rule. The application’s role reads from it; nobody else needs to.
    4. Try the calls by handRun detect-labels, detect-moderation-labels and detect-text on twenty real pictures from your own users, not stock photos. Note where the scores are wrong.
    5. Choose thresholds from that samplePick a confidence for reject, a lower one for human review, and keep the rest. Write the numbers down next to the date you tested.
    6. Add faces only with consentCreate a collection per purpose, set ExternalImageId to your own person id, use the quality filter, and write a way to delete a person’s vectors on request.
    7. Put the calls behind one small moduleModeration first, then the other calls only for pictures that pass. One place to change thresholds, retries and logging.
    8. Run videos as jobsStart the job, publish to an SNS topic (its name must start with AmazonRekognition to work with the AWS managed role), and read all pages of the result when the message arrives.
    9. Watch the bill and the errorsAlarm on throttling and on spend. Re-run your twenty-picture sample every few months, because models change.

    Tip: keep the original picture and the raw response for a while, and log which thresholds were in force. When someone asks why a photo was blocked, "the model said 91" is not an answer, but a stored response and a rule number is. See the code references for the same setup as Terraform.

    Common issues after configuration

    SymptomLikely causeWhat to check / fix
    InvalidS3ObjectExceptionThe bucket is in another Region, the key has a typo, or the caller can’t read the objectCall Rekognition in the bucket’s Region, check the key, and give the caller s3:GetObject (and kms:Decrypt if the bucket uses a customer key).
    ImageTooLargeException or InvalidImageFormatExceptionThe picture is over the size limit or isn’t a JPEG or PNGResize before upload, convert other formats, and strip huge originals to a few megabytes.
    InvalidParameterException: There are no faces in the imageA face search or index call got a picture with no usable faceTreat it as "no match" in your code, and show the user a message about lighting and framing.
    ProvisionedThroughputExceededException or ThrottlingExceptionA burst of calls is above the account’s rate for that APIRetry with exponential backoff and jitter (boto3’s adaptive mode does this), spread uploads over time and ask for a higher limit when you have real numbers.
    Labels are right but the wrong ones matterDetectLabels returns what is in the picture, not what matters to your businessFilter with label and category inclusion lists, or train Custom Labels for your own objects.
    Text is missing or in the wrong orderSmall, curved, low-contrast or rotated text, or text mixed with a dense layoutCrop to the area, raise the resolution, set a word filter by confidence, and use Textract for documents.
    A harmless picture is flaggedModeration models see a skin tone, a swimsuit or a medical photo as riskySend the middle band to a person, and consider a custom moderation adapter trained on your own approved examples.
    Someone else’s face matchedThe threshold is too low for the use, or the enrolled photo is poorRaise the similarity threshold (99 where a wrong match has consequences), enrol better pictures and keep a human in the loop.
    The same person is not foundThe enrolled and the new photo differ in pose, light or age, or the quality filter dropped oneEnrol two or three varied photos, group them under a user, and ask the user to retake the photo when the quality filter rejects it.
    Video job stays IN_PROGRESS or failsThe video is long, in an unsupported codec, or the SNS role or topic is wrongCheck the job status and StatusMessage, use H.264 in MP4 or MOV, and confirm the topic name starts with AmazonRekognition if you use the managed role.
    The feature isn’t available to my accountStreaming video analysis and bulk image analysis closed to new customers on 30 April 2026Use stored-video jobs and the image APIs, or call the image APIs yourself from Lambda for batches. Read the AWS availability-change page before planning around either.

    Use cases: when and where to use it

    Good fit

    • Auto-tagging and search for a photo library or a product catalogue
    • Screening user uploads before they are shown to other people
    • Reading text from photos of shop fronts, vehicles or packaging
    • Sign-up flows that need proof that a live person is present
    • Finding the moments in recorded video where something appears
    • Checking that a photo has one clear, well-lit face before it goes on a card or record

    Consider something else

    Pros: why consider it?

    Why teams choose it

    • Nothing to train for the common tasks, and results in a single call
    • Face collections, liveness and video jobs in one service
    • Scales with traffic and bills per use
    • Tight fit with S3, Lambda and SNS for event-driven pipelines
    • Mumbai Region support for data that should stay in India
    • Custom Labels and moderation adapters when the stock models don’t fit

    Trade-offs to weigh

    • Accuracy varies with lighting, pose, skin tone and image quality, so you must test on your own pictures
    • A face match is a similarity score, and the legal and ethical weight of a wrong one is on you
    • Streaming video analysis and bulk image analysis are closed to new customers
    • Custom Labels bills every hour a model runs, used or not
    • Images must be in S3 in the same Region, or sent as smaller byte payloads
    • Scene-text reading is weaker than a document tool on dense pages

    Common threats, vulnerabilities & risks

    RiskSeverityWhy it mattersMitigation
    Biometric data kept without consent or a purposeHighFace vectors identify a person. Holding them without a clear reason or a way to delete them creates legal and trust problems under India’s data protection law and similar rules elsewhere.Get consent, keep one collection per purpose, store the minimum, and build deletion (DeleteFaces, DeleteCollection) before launch.
    A wrong match acted on automaticallyHighA similarity of 90 can still be a stranger. Letting it open a door or flag a person without a check hurts real people.Use 99 or higher where a mistake has consequences, require a second factor or a person, and log every decision.
    Unsafe content shown because only one score was usedHighModels miss things, and attackers crop or edit pictures to slip under a threshold.Keep two lines, a high one that rejects and a lower one that sends a picture to a person, read a sample of what passed, and let users report.
    Pictures readable by the wrong peopleMediumA public bucket or a broad role exposes the very images you are screening.Block public access, encrypt, and grant s3:GetObject only to the application role.
    Content used to improve the serviceMediumBy default AWS may store and use content processed by some AI services to improve them.Set an AI services opt-out policy in AWS Organizations if your rules or contracts forbid it.
    Bias in accuracy across groupsMediumError rates differ by skin tone, age, gender presentation and image conditions.Test on a sample that looks like your users, publish the limits, and keep an appeal route.
    Spoofing at sign-upMediumA photo, a screen or a mask can fool a plain face match.Use Face Liveness, check the audit images on doubtful results, and add rate limits.
    Cost surprise from video or a running modelLow–MedVideo is billed by the minute, and a Custom Labels model bills every hour it is started.Set budgets and alarms, stop models when idle, and sample frames instead of scanning every second.
    Dependence on a closed featureLow–MedA workflow built on streaming video analysis can’t be rebuilt on a new account.Read the availability page before design, and keep the analysis step behind an interface you can swap.

    Performance optimisation

    • Send less pixels. A 12-megapixel phone photo takes longer to upload than it takes to analyse, and labels rarely need more than about 1,500 pixels on the long side.
    • Run moderation first and the other calls only for pictures that pass. A rejected picture then costs one call.
    • Ask for the features you use. DetectLabels with image properties adds work you may not need.
    • Use asynchronous jobs for video and read results by page with MaxResults, not by waiting on a long request.
    • Process uploads from an S3 event through a queue, so a spike waits in the queue instead of hitting a throttle.
    • Use adaptive retries and a cap on parallel calls. Hammering a throttled API makes it slower.
    • Remember results by a hash of the picture; an identical upload then costs nothing.
    • Keep collections small and purposeful. A search that only needs staff should not look through visitors.

    Reduce monthly cost

    FinOps is the habit of managing cloud spend together with engineering. These are the FinOps checks that matter most for Amazon Rekognition.

    • Call moderation first and stop there for rejected pictures.
    • Resize and deduplicate pictures before calling. Identical uploads cost the same each time.
    • Sample video frames or use a job with a sensible minimum confidence, instead of analysing every second at maximum detail.
    • Stop Custom Labels models when nobody is calling them. A started model bills by the hour.
    • Delete unused face vectors. Stored face metadata bills every month.
    • Use the free tier for testing only, and set a budget alert so a loop in your code can’t run up a bill overnight.
    • Choose the cheapest API that answers the question. Labels, moderation and text are priced in different groups.
    • Tag the account or project and watch spend by API in Cost Explorer.

    No dollar rates are quoted here because AWS prices differ by Region, are grouped in tiers and change. AWS lists a limited free tier for new accounts; the amount differs between older posts and its pricing page, so read the live page (see Pricing).

    Security optimisation

    • Give the application role only the calls it uses, and limit face calls to one collection by its ARN.
    • Keep the bucket private and encrypted, and add a lifecycle rule so pictures of people don’t stay for ever.
    • Use a VPC endpoint for Rekognition and S3 where the workload runs in private subnets.
    • Decide on the AI services opt-out policy in AWS Organizations before sending customer content.
    • Log calls with CloudTrail and alert on DeleteCollection, DeleteFaces and changes to collections.
    • Store no secret in the picture metadata and no personal data in ExternalImageId; use an opaque id.
    • Protect Face Liveness sessions: create them on the server, bind them to the signed-in user, and use each only once.
    • Delete face vectors when consent is withdrawn or the person leaves, and record that you did.
    • Limit who can start Custom Labels models and who can read training images.
    • Publish a short notice to users explaining what is analysed, why and for how long.

    Governance & compliance

    Guardrails

    • A shared Terraform module for the bucket, the collection and the application policy, with tags and an owner
    • A rule that no collection exists without a named purpose and a deletion process
    • A service control policy that blocks Rekognition calls outside approved Regions
    • A privacy review before any new use of face features

    Continuous checks (AWS Config, CloudTrail and your own scripts)

    • A scheduled script that lists collections, face counts and owner tags (the C# tab does this)
    • CloudTrail alerts for collection and face deletion and for calls from unexpected roles
    • Budget alerts on Rekognition spend and on any running Custom Labels model
    • A monthly sample of rejected and approved pictures read by a reviewer
    • A yearly retest of thresholds on fresh pictures

    AWS CloudTrail logs who called which API, AWS Config keeps the history of related resources such as the bucket, and AWS Artifact has the compliance reports. AWS runs the models and the infrastructure. What is analysed, how long it is kept, the thresholds and the consequences of a wrong answer are yours.

    Reduce carbon footprint

    • Analyse each picture once and cache the answer.
    • Resize before upload so less data moves and less is processed.
    • Sample video frames instead of scanning everything.
    • Stop Custom Labels models when they are idle, since a started model keeps its capacity busy.
    • Delete pictures and vectors you no longer need.
    • The AWS carbon tool reports per account and doesn’t list Rekognition on its own, so quote no Rekognition figure.

    Pricing

    Purchase options

    Image APIs Per image processed

    Each call on one picture counts as one image. APIs are grouped, with different prices per group, and the price per image falls as monthly volume passes tier limits. Image properties are billed separately.

    Video Per minute of video

    Stored video is billed for the minutes analysed by each job, and different video features have different rates.

    Face storage and Liveness Per face stored, per check

    Each stored face (and user) vector bills monthly, and each Face Liveness check is billed per session.

    Custom Labels Per training hour and per inference hour

    Training bills by the hour, and a trained model bills for each hour it is running, so stop it when it is idle.

    What you actually pay for

    • Images processed, by API group and monthly volume tier
    • Minutes of stored video analysed
    • Face and user vectors stored each month
    • Face Liveness checks
    • Custom Labels training and inference hours
    • Data transfer, S3 storage and requests, and any Lambda or SNS you use around it

    AWS lists the rates, the tiers and any free allowance for new accounts on its pricing page, and rates differ by Region. See the official Amazon Rekognition pricing page and the AWS Pricing Calculator.

    Important code references

    An image-intake setup: a private encrypted bucket, a face collection, an SNS topic and a role for video jobs, and an application policy that can only use the calls it needs. The CLI tab runs labels, moderation, text, face enrolment and search, a stored-video job, a liveness session and the clean-up. Terraform describes the bucket, collection, topic, role and policy. The Python tab screens an upload (moderation first), enrols and identifies faces and reads every page of a video job, and the C# tab audits the face collections in a Region. Replace the Region, bucket and account with your own.

    # Placeholders: replace the Region, the bucket and the keys. Rekognition reads each image from S3 in the same Region as the call.
    REGION=ap-south-1
    BUCKET=my-image-intake
    KEY=uploads/shopfront.jpg
    ACCOUNT_ID=111122223333
    
    # 1. What is in the picture? Labels above 80 percent confidence, plus the three dominant colours.
    aws rekognition detect-labels --region $REGION \
      --image "S3Object={Bucket=$BUCKET,Name=$KEY}" \
      --features GENERAL_LABELS IMAGE_PROPERTIES --settings "ImageProperties={MaxDominantColors=3}" \
      --max-labels 15 --min-confidence 80
    
    # 2. Is it safe to publish? Moderation labels come with a parent category, so you can block on the parent.
    aws rekognition detect-moderation-labels --region $REGION \
      --image "S3Object={Bucket=$BUCKET,Name=$KEY}" --min-confidence 60
    
    # 3. Text in the picture (signs, labels, plates). Keep only words detected at 85 percent or better.
    aws rekognition detect-text --region $REGION \
      --image "S3Object={Bucket=$BUCKET,Name=$KEY}" --filters "WordFilter={MinConfidence=85}"
    
    # 4. A face collection: create it, add one face for a known person, then search it with a new photo. 99 percent is the bar for decisions that matter.
    aws rekognition create-collection --region $REGION --collection-id staff-faces --tags team=security,owner=platform
    aws rekognition index-faces --region $REGION --collection-id staff-faces \
      --image "S3Object={Bucket=$BUCKET,Name=enrol/employee-1042.jpg}" \
      --external-image-id employee-1042 --max-faces 1 --quality-filter AUTO --detection-attributes DEFAULT
    aws rekognition search-faces-by-image --region $REGION --collection-id staff-faces \
      --image "S3Object={Bucket=$BUCKET,Name=$KEY}" --face-match-threshold 99 --max-faces 1 --quality-filter AUTO
    aws rekognition describe-collection --region $REGION --collection-id staff-faces
    aws rekognition list-faces --region $REGION --collection-id staff-faces --max-results 10
    
    # 5. Compare two photos directly, with no collection.
    aws rekognition compare-faces --region $REGION --similarity-threshold 90 \
      --source-image "S3Object={Bucket=$BUCKET,Name=enrol/employee-1042.jpg}" \
      --target-image "S3Object={Bucket=$BUCKET,Name=$KEY}"
    
    # 6. A stored video is analysed asynchronously: start the job, let Rekognition publish to SNS when it ends, then read the pages.
    JOB_ID=$(aws rekognition start-label-detection --region $REGION --min-confidence 80 --job-tag gate-camera-1 \
      --video "S3Object={Bucket=$BUCKET,Name=videos/gate.mp4}" \
      --notification-channel "SNSTopicArn=arn:aws:sns:$REGION:$ACCOUNT_ID:AmazonRekognitionVideoDone,RoleArn=arn:aws:iam::$ACCOUNT_ID:role/rekognition-video-publish" \
      --query JobId --output text)
    aws rekognition get-label-detection --region $REGION --job-id $JOB_ID --sort-by TIMESTAMP --max-results 100
    
    # 7. Liveness check for a sign-up flow. Check first that your Region offers Face Liveness.
    SESSION_ID=$(aws rekognition create-face-liveness-session --region $REGION \
      --settings "OutputConfig={S3Bucket=$BUCKET,S3KeyPrefix=liveness/},AuditImagesLimit=2" --query SessionId --output text)
    aws rekognition get-face-liveness-session-results --region $REGION --session-id $SESSION_ID
    
    # 8. Delete a person's faces when they leave, and the whole collection when the project ends.
    aws rekognition delete-faces --region $REGION --collection-id staff-faces --face-ids $FACE_ID
    aws rekognition delete-collection --region $REGION --collection-id staff-faces
    # Private image intake: an encrypted bucket, a face collection, an SNS topic and a role for video jobs, and a least-privilege policy for the application.
    terraform {
      required_providers {
        aws = { source = "hashicorp/aws", version = ">= 6.0" }
      }
    }
    
    provider "aws" {
      region = "ap-south-1"
      default_tags {
        tags = { project = "image-intake", owner = "platform-team" }
      }
    }
    
    data "aws_caller_identity" "me" {}
    
    resource "aws_s3_bucket" "images" {
      bucket = "my-image-intake-${data.aws_caller_identity.me.account_id}"
    }
    
    resource "aws_s3_bucket_public_access_block" "images" {
      bucket                  = aws_s3_bucket.images.id
      block_public_acls       = true
      block_public_policy     = true
      ignore_public_acls      = true
      restrict_public_buckets = true
    }
    
    resource "aws_s3_bucket_server_side_encryption_configuration" "images" {
      bucket = aws_s3_bucket.images.id
      rule {
        apply_server_side_encryption_by_default { sse_algorithm = "AES256" }
      }
    }
    
    # Uploads expire after 30 days; pictures of people should not stay for ever.
    resource "aws_s3_bucket_lifecycle_configuration" "images" {
      bucket = aws_s3_bucket.images.id
      rule {
        id     = "expire-uploads"
        status = "Enabled"
        filter { prefix = "uploads/" }
        expiration { days = 30 }
      }
    }
    
    # The face collection. It stores face vectors, not the pictures.
    resource "aws_rekognition_collection" "staff" {
      collection_id = "staff-faces"
    }
    
    # Video jobs tell this topic when they finish; Rekognition publishes through the role below. The managed policy only allows topics whose name starts with AmazonRekognition.
    resource "aws_sns_topic" "video_done" {
      name = "AmazonRekognitionVideoDone"
    }
    
    resource "aws_iam_role" "video_publish" {
      name = "rekognition-video-publish"
      assume_role_policy = jsonencode({
        Version = "2012-10-17"
        Statement = [{
          Effect    = "Allow"
          Principal = { Service = "rekognition.amazonaws.com" }
          Action    = "sts:AssumeRole"
          Condition = { StringEquals = { "aws:SourceAccount" = data.aws_caller_identity.me.account_id } }
        }]
      })
    }
    
    resource "aws_iam_role_policy_attachment" "video_publish" {
      role       = aws_iam_role.video_publish.name
      policy_arn = "arn:aws:iam::aws:policy/service-role/AmazonRekognitionServiceRole"
    }
    
    # What the application may do: call the image APIs, search and add faces in one collection, and read uploads.
    data "aws_iam_policy_document" "app" {
      statement {
        sid       = "ImageApis"
        actions   = ["rekognition:DetectLabels", "rekognition:DetectModerationLabels", "rekognition:DetectText", "rekognition:CompareFaces"]
        resources = ["*"]
      }
      statement {
        sid       = "OneCollection"
        actions   = ["rekognition:IndexFaces", "rekognition:SearchFacesByImage", "rekognition:ListFaces", "rekognition:DeleteFaces"]
        resources = [aws_rekognition_collection.staff.arn]
      }
      statement {
        sid       = "ReadUploads"
        actions   = ["s3:GetObject"]
        resources = ["${aws_s3_bucket.images.arn}/*"]
      }
    }
    
    resource "aws_iam_policy" "app" {
      name   = "image-intake-app"
      policy = data.aws_iam_policy_document.app.json
    }
    """Image intake with Amazon Rekognition: screen an upload, read its labels and text, enrol and recognise faces, and page through a video job."""
    import boto3
    from botocore.config import Config
    from botocore.exceptions import ClientError
    
    # Adaptive retries slow the client down when Rekognition throttles it, which is what you want for a burst of uploads.
    rek = boto3.client("rekognition", region_name="ap-south-1", config=Config(retries={"mode": "adaptive", "max_attempts": 8}))
    
    BLOCK = {"Explicit", "Violence", "Hate Symbols", "Drugs & Tobacco"}   # top-level moderation categories this site refuses
    REVIEW_FROM, BLOCK_FROM = 60.0, 90.0                                      # confidence bands: queue for a person, reject outright
    
    
    def _s3(bucket, key):
        return {"S3Object": {"Bucket": bucket, "Name": key}}
    
    
    def moderation_decision(labels):
        """'reject', 'review' or 'allow' from the labels DetectModerationLabels returned. A child label is judged through its parent."""
        decision = "allow"
        for label in labels:
            top = label["ParentName"] or label["Name"]
            score = label["Confidence"]
            if top in BLOCK and score >= BLOCK_FROM:
                return "reject"
            if score >= REVIEW_FROM:
                decision = "review"
        return decision
    
    
    def screen_upload(bucket, key):
        """Moderation first. Labels and text are read only for pictures that are not rejected, so you do not pay for them."""
        mod = rek.detect_moderation_labels(Image=_s3(bucket, key), MinConfidence=REVIEW_FROM)
        decision = moderation_decision(mod["ModerationLabels"])
        result = {"key": key, "decision": decision, "moderation": [m["Name"] for m in mod["ModerationLabels"]]}
        if decision == "reject":
            return result
        labels = rek.detect_labels(Image=_s3(bucket, key), Features=["GENERAL_LABELS"], MaxLabels=15, MinConfidence=80)
        text = rek.detect_text(Image=_s3(bucket, key), Filters={"WordFilter": {"MinConfidence": 85}})
        result["labels"] = [lab["Name"] for lab in labels["Labels"]]
        result["words"] = [t["DetectedText"] for t in text["TextDetections"] if t["Type"] == "WORD"]
        return result
    
    
    def enrol(collection, bucket, key, person_id):
        """Add one face to a collection. Blurred, tiny or dark faces are refused by the quality filter, and the caller hears why."""
        out = rek.index_faces(CollectionId=collection, Image=_s3(bucket, key), ExternalImageId=person_id,
                              MaxFaces=1, QualityFilter="AUTO", DetectionAttributes=["DEFAULT"])
        if not out["FaceRecords"]:
            reasons = [r for u in out.get("UnindexedFaces", []) for r in u["Reasons"]] or ["NO_FACE_FOUND"]
            raise ValueError("face not enrolled: " + ", ".join(reasons))
        return out["FaceRecords"][0]["Face"]["FaceId"]
    
    
    def identify(collection, bucket, key, threshold=99.0):
        """The person_id of the best match above the threshold, or None. A picture with no usable face is a 'no', not an error."""
        try:
            out = rek.search_faces_by_image(CollectionId=collection, Image=_s3(bucket, key), FaceMatchThreshold=threshold,
                                            MaxFaces=1, QualityFilter="AUTO")
        except ClientError as err:
            if err.response["Error"]["Code"] == "InvalidParameterException":
                return None
            raise
        matches = out["FaceMatches"]
        return matches[0]["Face"]["ExternalImageId"] if matches else None
    
    
    def forget(collection, face_ids):
        """Delete face vectors (for example when a person leaves or withdraws consent). Returns the ids that were removed."""
        return rek.delete_faces(CollectionId=collection, FaceIds=list(face_ids))["DeletedFaces"]
    
    
    def video_labels(job_id):
        """Read every page of a finished label-detection job. Returns {label: first time it appears, in milliseconds}."""
        first, token = {}, None
        while True:
            args = {"JobId": job_id, "SortBy": "TIMESTAMP", "MaxResults": 100}
            if token:
                args["NextToken"] = token
            page = rek.get_label_detection(**args)
            if page["JobStatus"] != "SUCCEEDED":
                raise RuntimeError("job is %s: %s" % (page["JobStatus"], page.get("StatusMessage", "")))
            for item in page["Labels"]:
                first.setdefault(item["Label"]["Name"], item["Timestamp"])
            token = page.get("NextToken")
            if not token:
                return first
    // Audit every face collection in one Region: how many faces it holds, which model made them, and whether anyone owns it.
    // Needs rekognition:ListCollections, rekognition:DescribeCollection and rekognition:ListTagsForResource.
    using Amazon;
    using Amazon.Rekognition;
    using Amazon.Rekognition.Model;
    
    var region = RegionEndpoint.APSouth1;
    using var rek = new AmazonRekognitionClient(region);
    
    var ids = new List<string>();
    string? token = null;
    do
    {
        var page = await rek.ListCollectionsAsync(new ListCollectionsRequest { MaxResults = 100, NextToken = token });
        ids.AddRange(page.CollectionIds);
        token = page.NextToken;
    } while (token != null);
    
    Console.WriteLine($"{ids.Count} collection(s) in {region.SystemName}");
    var findings = 0;
    foreach (var id in ids.OrderBy(i => i, StringComparer.Ordinal))
    {
        var info = await rek.DescribeCollectionAsync(new DescribeCollectionRequest { CollectionId = id });
        var tags = (await rek.ListTagsForResourceAsync(new ListTagsForResourceRequest { ResourceArn = info.CollectionARN })).Tags;
    
        var notes = new List<string>();
        if (info.FaceCount == 0) notes.Add("empty, delete it if nobody uses it");
        if (!tags.ContainsKey("owner")) notes.Add("no owner tag");
        if (info.FaceCount > 100_000) notes.Add("large, check that you still need every face");
    
        findings += notes.Count;
        Console.WriteLine($"{id,-30} faces={info.FaceCount,-8} model={info.FaceModelVersion,-5} created={info.CreationTimestamp:yyyy-MM-dd}  {(notes.Count == 0 ? "ok" : string.Join("; ", notes))}");
    }
    Environment.ExitCode = findings == 0 ? 0 : 1;   // lets a scheduled job fail when something needs a look

    Best videos to explore

    Videos picked for this service. Each one is labelled with its source, opens on YouTube if you prefer, and loads only when you press play.

    AWS re:Invent 2016: NEW LAUNCH! Introducing Amazon Rekognition (MAC203)Official · AWS · Beginner · Watch on YouTube
    AWS re:Invent 2019: Media discovery and compliance with Amazon Rekognition (AIM232)Official · AWS · Intermediate · Watch on YouTube
    AWS re:Invent 2018: [REPEAT] Deep Dive on Amazon Rekognition, ft. Tinder & News UK (AIM307-R)Official · AWS · Advanced · Watch on YouTube
    AWS Certified AI Practitioner AIF C01 || Amazon Rekognition HandsonCommunity video · Beginner · Watch on YouTube

    Interview questions

    BasicWhat is Amazon Rekognition used for?

    It analyses pictures and video that you give it and returns structured answers: labels for what is in the image, text, unsafe-content labels, faces and whether a live person is present. Teams use it for photo tagging, upload screening, text reading from photos and sign-up checks, without training a model.

    BasicDo I need machine learning skills to use it?

    No for the standard features. You call an API with an image in S3 and read the JSON. You do need to understand confidence scores and to test on your own pictures. Custom Labels asks for more: you label images, train a model and manage its running cost.

    BasicWhat is the difference between DetectLabels and DetectText?

    DetectLabels names objects, scenes and activities ("Car", "Street"). DetectText reads characters that appear inside the picture, such as a shop sign or a number plate, and returns them as words and lines with positions.

    IntermediateHow does a face collection work?

    IndexFaces detects the faces in a picture and stores a vector for each one under a new face id. The external id you pass is attached to all faces from that picture. The pictures themselves are not stored. SearchFacesByImage then compares a new face with the stored vectors and returns the closest ones above a threshold. Vectors from different model versions can’t be compared.

    IntermediateHow would you analyse a recorded video?

    Start an asynchronous job, such as StartLabelDetection, on the video in S3 and pass an SNS topic and a role. When the job ends Rekognition publishes a message with the job id, and you read all pages with the matching Get call, using the pagination token until it is empty.

    IntermediateWhat does Face Liveness add on top of face matching?

    Matching tells you that two faces look alike. Liveness tells you that a live person is in front of the camera right now, which defeats a printed photo, a screen replay or a mask. The server creates a session, the app records it, and the server reads a score and audit images by session id.

    AdvancedHow do you choose thresholds for moderation and for face matching?

    Collect a few hundred real pictures, label them, and plot errors at different thresholds. For moderation use two bands: reject above one score, queue for a person between two. For face matching use a high similarity, 99 where a wrong match has consequences, and add a second factor. Retest when models change.

    AdvancedWhat are the privacy duties when you store face vectors?

    A face vector is biometric personal data. Get clear consent for a stated purpose, store the minimum, keep one collection per purpose, protect access, and be able to delete one person’s vectors on request. Under India’s data protection law, treat it as sensitive in practice even where the text doesn’t name it.

    AdvancedHow would you build an upload pipeline that can’t be overwhelmed by a spike?

    Let S3 events go into a queue, process with workers (Lambda or containers) at a capped concurrency, call moderation first and the other APIs only for passing pictures, use adaptive retries, cache results by image hash and send failures to a dead-letter queue. The queue absorbs the spike, and the cap stays below the API limit.

    AdvancedWhen would you pick Custom Labels over a model you train yourself?

    When the target is a handful of your own classes, you have a few hundred labelled pictures, and you want AWS to handle training and hosting. A model you train yourself in SageMaker gives you more control over architecture, cost per request and where it runs. Remember Custom Labels bills each hour a model is started.

    Similar or alternative services on other clouds

    CapabilityAWSAzureGoogle Cloud
    ServiceAmazon RekognitionAzure AI Vision (Image Analysis), Azure Face, Content UnderstandingCloud Vision API
    Labels and tagsDetectLabelsTags and objects in Image AnalysisLabel and object detection
    Image descriptionLabels only; use a model on Bedrock for sentencesCaptions and dense captions (some Regions)Labels and web entities; Gemini for sentences
    Reading textDetectText (scene text), Textract for documentsRead in Image Analysis; Document Intelligence for documentsText and document text detection
    Unsafe contentModeration labels and custom adaptersAzure AI Content Safety (separate service)SafeSearch detection
    FacesDetect, compare, collections, Face LivenessAzure Face service (separate, limited access)Face detection only; no identification
    Own modelCustom Labels (billed per hour running)Custom Vision (retiring) and Foundry modelsVertex AI AutoML and custom models
    VideoStored video jobs; streaming closed to new customersVideo retrieval and Content UnderstandingVideo Intelligence API (separate)
    Billing unitPer image or video minute, per stored facePer 1,000 transactions, per featurePer 1,000 units, per feature

    Typical callers are AWS Lambda functions started by uploads to Amazon S3, with results saved to Amazon DynamoDB and routed on through Amazon EventBridge. Spend, throttling and errors show up in Amazon CloudWatch.

    Did you find this article helpful?

    Your answer helps us improve this page for the next reader.

    Sources and further reading

    CloudBrum wrote this page in its own words, using the provider’s public documentation listed below as the reference. Features, limits, names and prices change, so confirm anything that matters on the provider’s own pages before you decide.