Build a Smart Image Analyzer

Use AWS Rekognition to detect objects, faces, and text in images.

Introduction

30 Second Summary

Your phone can identify faces in photos. Google Lens can tell you what's in a picture. That's computer vision at work, and it's powered by the same cloud AI services that companies use in production.

In this project, you will build a Python tool that uses Amazon Rekognition to analyze any photo for objects, faces, and text. You'll upload an image, run a single script, and get back a detailed analysis report in your terminal.

What You'll Build

A command-line Smart Image Analyzer that uploads photos to Amazon S3 and calls three different Rekognition APIs to detect objects, analyze facial attributes, and extract readable text.

By the end of this project, you'll have:

  • An AWS account with an IAM user configured for programmatic access.
  • An S3 bucket for storing images in the cloud.
  • A Python script that performs multi-mode image analysis using three Rekognition APIs (object detection, facial analysis, and text extraction).
  • Secret Mission: Add celebrity recognition and face comparison capabilities to your analyzer.

Are there any prerequisites?

You should have basic Python knowledge (variables, functions, and print statements). No AWS or machine learning experience is needed.

Create Your AWS Account and Install Tools

To analyze images with Amazon Rekognition, your Python script needs to communicate with AWS servers in the cloud.

In this step, you'll create a free AWS account and install the AWS CLI (Command Line Interface), which is the tool that lets your computer talk to AWS services from the terminal.

In this step, get ready to:
  • Create a free AWS account.
  • Install the AWS CLI on your computer.
  • Verify the installation works.
Create your free AWS account

AWS offers a Free Tier that includes 1,000 Rekognition image analyses per month for 12 months.

You will not be charged for anything in this project.

  • Open your browser and go to https://aws.amazon.com/free/.
  • Click Create a Free Account.
  • Enter your email address and choose an AWS account name.
  • Verify your email with the code AWS sends to your inbox.
  • Set a strong root user password.
  • Select Personal for the account type and fill in your contact information.
  • Enter your credit or debit card details for identity verification.
  • Complete the phone verification step when prompted.
  • Select the Basic support - Free plan.

Why do I need a credit card?

AWS uses your card solely to verify your identity. You will not be charged for this project because everything falls within the Free Tier limits (1,000 images per month for Rekognition, 5 GB of S3 storage).

As of July 2025, new AWS customers also receive up to $200 in Free Tier credits valid for 12 months.

Once you complete signup, AWS takes a few minutes to activate your account. You will receive an email when it is ready.

Account not activating?

Account activation can take up to 24 hours in rare cases. Check your email (including spam) for a confirmation message from AWS.

If your card was declined, try a different card. AWS may charge $1 temporarily to verify the card, which is refunded automatically.

Help me troubleshoot my AWS account creation.

Install the AWS CLI

The AWS CLI is a program that lets you run AWS commands from your terminal. Your Python script will rely on the credentials the CLI stores on your machine.

  • Download the AWS CLI installer for Windows from this link.
  • Open the downloaded AWSCLIV2.msi file.
  • Click Next through each page of the installer wizard.
  • Accept the license agreement.
  • Click Install.
  • Click Finish when the installation completes.

What about macOS or Linux?

This project uses the Windows MSI installer. If you are on macOS or Linux, visit the AWS CLI install guide for platform-specific instructions.

Verify the AWS CLI installation

You need to open a brand new terminal window after installation. Existing windows will not recognize the new aws command.

  • Press the Windows key to open your search bar.
  • Type Command Prompt and press Enter to open it.
  • Check that the AWS CLI is installed by running this command:
aws --version

✔️ I see a version number

You should see something like aws-cli/2.34.41 Python/3.12.6 Windows/10. The exact numbers may differ, and that is fine.

The AWS CLI is installed and ready to use.

ⓧ Command not found

If you see an error like 'aws' is not recognized as an internal or external command, try these fixes:

  • Close your current Command Prompt window and open a brand new one. The installer adds the CLI to your system path, but existing windows do not pick up the change.
  • If a new window still does not work, restart your computer and try again.
  • If it still fails, re-download and run the MSI installer from https://awscli.amazonaws.com/AWSCLIV2.msi.

Help me fix 'aws' is not recognized on Windows.

Finally, make sure you have a code editor ready for the next steps. If you already have VS Code, Cursor, or another editor installed, you are all set.

Your AWS account is created and the CLI is installed. Next up, you'll create an IAM user and connect the CLI to your account so Python can access AWS services.

Set Up IAM User and Configure AWS CLI

Your AWS CLI is installed, but it doesn't know who you are yet. AWS needs credentials to verify that you're allowed to use services like Rekognition and S3.

In this step, you'll create an IAM user with the right permissions, generate an access key, and connect it to your terminal. Once this is done, your terminal can talk directly to AWS.

In this step, get ready to:
  • Create an IAM user with permissions for Rekognition and S3.
  • Generate an access key and download the credentials file.
  • Configure the AWS CLI so your terminal is authenticated.
Create an IAM user with permissions

An IAM user is a separate identity inside your AWS account with its own credentials and permissions. Instead of using your root account (which has full access to everything), you'll create a user that can only access Rekognition and S3.

What is IAM?

IAM stands for Identity and Access Management. It controls who can do what inside your AWS account.

Think of it like a building security system. Your root account is the master key, and IAM users are individual key cards with access to specific rooms only.

  • Sign in to the AWS Management Console at https://console.aws.amazon.com.
  • In the search bar at the top, type IAM and click on IAM in the results.
  • In the left sidebar, click Users.
  • Click Create user.
  • Enter a user name. For example, type rekognition-user.
  • Leave the Provide user access to the AWS Management Console checkbox unchecked.
  • Click Next.
  • Select Attach policies directly.
  • In the search box, type AmazonRekognitionFullAccess and check the box next to it.
  • Clear the search box, then type AmazonS3FullAccess and check the box next to it.
  • Click Next.
  • Review the summary and click Create user.

You should see a green success banner confirming your user was created.

Why two policies?

Your script needs S3 access to upload images and Rekognition access to analyze them. Each policy grants permission to one service only.

Don't see the policies in search?

Make sure you selected Attach policies directly (not "Add user to group"). The policy names are case-sensitive, so type them exactly as shown.

Help me find IAM policies in the AWS Console

Generate an access key

Your IAM user exists, but it doesn't have credentials for your terminal to use. You need to generate an access key, which is a pair of values (an Access Key ID and a Secret Access Key) that authenticate your CLI commands.

  • Click on your new user name (rekognition-user) in the Users list to open their details page.
  • Click the Security credentials tab.
  • Scroll down to the Access keys section and click Create access key.
  • Select Command Line Interface (CLI) as the use case.
  • Check the confirmation checkbox at the bottom acknowledging the recommendation.
  • Click Next.
  • Skip the description tag and click Create access key.
  • Click Download .csv file to save your credentials.

Save this file somewhere safe

This is the only time you can view your Secret Access Key. If you lose it, you'll need to create a new access key from scratch. Keep the .csv file safe and never share it with anyone.

  • Click Done.

You should see your new access key listed in the Access keys section with a status of Active.

Accidentally closed the page before downloading?

You cannot retrieve the Secret Access Key after leaving the page. Delete the access key you just created (click the Actions dropdown next to it) and create a new one by repeating the steps above.

Help me regenerate my AWS access key

Configure the AWS CLI with your credentials

Now you'll connect your terminal to AWS by feeding it the credentials you just downloaded. The aws configure command stores your keys locally so every future AWS command knows who you are.

  • Open your terminal (Command Prompt on Windows, Terminal on macOS).
  • Start the configuration wizard by running this command:
aws configure

The command prompts you for four values one at a time. Open your downloaded .csv file to find the first two values.

  • For AWS Access Key ID, paste the Access Key ID from your .csv file.
  • For AWS Secret Access Key, paste the Secret Access Key from your .csv file.
  • For Default region name, type us-east-1.
  • For Default output format, type json.

Why us-east-1?

The us-east-1 region simplifies S3 bucket creation. In this region, you can create a bucket without extra configuration parameters. Other regions require additional setup in your code.

  • Verify that your configuration worked by running this command:
aws sts get-caller-identity

You should see a JSON response containing your Account ID, User ARN, and the user name you created (like rekognition-user). This confirms your terminal is authenticated with AWS.

Seeing "Unable to locate credentials"?

Run aws configure again and make sure you pasted the full Access Key ID and Secret Access Key without any extra spaces. The Secret Access Key is a long string that may include slashes and plus signs.

If you're on Windows and opened a new Command Prompt window after configuring, the credentials should still be available since they're stored at %UserProfile%\.aws\credentials.

Help me fix my AWS CLI credentials

Your terminal is now authenticated with AWS. Next up, you'll create an S3 bucket and start writing Python code to upload images for analysis.

Create an S3 Bucket and Upload a Test Image

Your AWS credentials are configured and ready to go. Now it is time to write the Python script that will power your image analyzer.

Amazon Rekognition needs your images stored in Amazon S3 before it can analyze them. In this step, you will install the Python SDK for AWS, write a script that creates an S3 bucket, and upload a test image to it.

In this step, get ready to:
  • Install boto3, the Python library for AWS.
  • Write a Python script that creates an S3 bucket and uploads an image.
  • Run the script and confirm your image appears in the AWS Console.
Install boto3

boto3 is the official Python SDK for AWS. It lets your Python code talk directly to AWS services like S3 and Rekognition.

  • Install boto3 by running this command:
pip install boto3

You should see output ending with Successfully installed boto3 followed by a version number.

Seeing 'pip is not recognized'?

Try using pip3 install boto3 instead. Some systems use pip3 for Python 3 packages.

If that does not work, make sure Python is added to your system PATH. Help me fix my pip installation

Write the image analyzer script

Your script will do two things: create an S3 bucket to store images, then upload a local photo into that bucket. Later steps will add the analysis functions on top of this foundation.

  • Move to your Desktop by running this command:
cd ~/Desktop
  • Create your project folder and move into it by running these commands:
mkdir smart-image-analyzer
cd smart-image-analyzer
  • Confirm the folder exists by running:
ls

The folder should be empty for now. Next, you will create the Python file.

  • Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
  • Type VS Code and press Enter to open it.
  • In VS Code, click File in the top menu bar.
  • Click Open Folder.
  • Navigate to your Desktop and select the smart-image-analyzer folder, then click Open.
  • Create a new file by clicking File then New File.
  • Name the file analyze_image.py and press Enter.

You now have an empty Python file ready for your code. Start by adding the imports and AWS client setup.

  • Copy the following initialization code into analyze_image.py:
import boto3
import sys

# Initialize AWS clients
s3 = boto3.client('s3', region_name='us-east-1')
rekognition = boto3.client('rekognition', region_name='us-east-1')

BUCKET_NAME = '[[BUCKETNAME="your-unique-bucket-name-here"]]'

What does this code do?

  • import boto3 loads the AWS SDK so Python can communicate with AWS services.
  • import sys lets the script read command-line arguments (the image file path).
  • boto3.client('s3') creates a connection to Amazon S3 for bucket and file operations.
  • boto3.client('rekognition') creates a connection to Amazon Rekognition for image analysis (used in later steps).
  • BUCKET_NAME stores your unique bucket name as a constant so you only define it once.

Why does my bucket name need to be unique?

S3 bucket names are globally unique across all AWS accounts. No two people in the world can have the same bucket name. Try a pattern like smart-analyzer-yourname-2026 to make yours unique.

You will not see output yet. The next chunk adds the functions that use these clients.

  • Add the following two helper functions below your BUCKET_NAME line in analyze_image.py:

def create_bucket(bucket_name):
    """Create an S3 bucket in us-east-1."""
    s3.create_bucket(Bucket=bucket_name)
    print(f"Bucket '{bucket_name}' created successfully.")


def upload_image(bucket_name, file_path, key_name):
    """Upload a local image file to S3."""
    s3.upload_file(file_path, bucket_name, key_name)
    print(f"Uploaded '{file_path}' to s3://{bucket_name}/{key_name}")

What do these functions do?

  • create_bucket() tells AWS to create a new S3 storage bucket with the name you chose. In the us-east-1 region, no extra configuration is needed.
  • upload_image() takes a file from your computer and copies it into your S3 bucket. The key_name is what the file will be called inside S3.

You will not see a change yet. The next chunk adds the main logic that calls these functions.

  • Add the following main block at the bottom of analyze_image.py:

if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("Usage: python analyze_image.py <image_file_path>")
        print("Example: python analyze_image.py photo.jpg")
        sys.exit(1)

    file_path = sys.argv[1]
    key_name = file_path.split('\\')[-1].split('/')[-1]

    # Create bucket (only needed first time)
    try:
        create_bucket(BUCKET_NAME)
    except s3.exceptions.BucketAlreadyOwnedByYou:
        print(f"Bucket '{BUCKET_NAME}' already exists.")
    except Exception as e:
        if 'BucketAlreadyOwnedByYou' in str(e):
            print(f"Bucket '{BUCKET_NAME}' already exists.")
        else:
            raise

    # Upload image
    upload_image(BUCKET_NAME, file_path, key_name)

    print("\n--- ANALYSIS COMPLETE ---")

What does the main block do?

  • if len(sys.argv) < 2 checks that the user provided an image file path when running the script. If not, it prints usage instructions and exits.
  • key_name extracts just the filename from the full path (handles both Windows backslashes and macOS forward slashes).
  • The try/except block handles the case where the bucket already exists from a previous run. This lets you re-run the script without errors.
  • Save analyze_image.py by pressing Cmd+S (macOS) or Ctrl+S (Windows).

✔️ Awesome, I've got everything!

Great. Double check you have saved your file before moving on.

ⓧ I'd like to double check the full code

Here is the complete analyze_image.py file so far. Compare it against yours:

import boto3
import sys

# Initialize AWS clients
s3 = boto3.client('s3', region_name='us-east-1')
rekognition = boto3.client('rekognition', region_name='us-east-1')

BUCKET_NAME = '[[BUCKETNAME="your-unique-bucket-name-here"]]'


def create_bucket(bucket_name):
    """Create an S3 bucket in us-east-1."""
    s3.create_bucket(Bucket=bucket_name)
    print(f"Bucket '{bucket_name}' created successfully.")


def upload_image(bucket_name, file_path, key_name):
    """Upload a local image file to S3."""
    s3.upload_file(file_path, bucket_name, key_name)
    print(f"Uploaded '{file_path}' to s3://{bucket_name}/{key_name}")


if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("Usage: python analyze_image.py <image_file_path>")
        print("Example: python analyze_image.py photo.jpg")
        sys.exit(1)

    file_path = sys.argv[1]
    key_name = file_path.split('\\')[-1].split('/')[-1]

    # Create bucket (only needed first time)
    try:
        create_bucket(BUCKET_NAME)
    except s3.exceptions.BucketAlreadyOwnedByYou:
        print(f"Bucket '{BUCKET_NAME}' already exists.")
    except Exception as e:
        if 'BucketAlreadyOwnedByYou' in str(e):
            print(f"Bucket '{BUCKET_NAME}' already exists.")
        else:
            raise

    # Upload image
    upload_image(BUCKET_NAME, file_path, key_name)

    print("\n--- ANALYSIS COMPLETE ---")
Run the script and verify your image in S3

You need a test image on your computer to analyze. Any photo will work. A photo with people, objects, and visible text gives the richest results in later steps.

  • Find a photo on your computer (a .jpg or .png file) and copy it into your smart-image-analyzer folder on the Desktop.
  • Open a terminal in VS Code by pressing Ctrl+` (backtick key, below Escape).
  • Run your script by providing the image filename as an argument:
python analyze_image.py [[IMAGEFILE="your-image-filename.jpg"]]

You should see two success messages: one confirming the bucket was created, and another confirming the image was uploaded.

Seeing an 'AccessDenied' or 'InvalidBucketName' error?

  • If you see InvalidBucketName, your bucket name may contain uppercase letters or special characters. Bucket names must be lowercase, 3-63 characters, and use only letters, numbers, and hyphens.
  • If you see BucketAlreadyExists (different from BucketAlreadyOwnedByYou), someone else already has that bucket name. Change your BUCKET_NAME to something more unique.
  • If you see AccessDenied, double-check that your IAM user has the AmazonS3FullAccess policy attached (from Step 2).
  • If you see FileNotFoundError, make sure the image file is in the same folder as your script and that you typed the filename correctly.

Help me debug my S3 upload error

Your image is now stored in the cloud and ready for analysis. Next up, you will call Rekognition's object detection API to find out what is in your photo.

Detect Objects and Scenes with Rekognition

Your script can upload images to S3, but it can't yet see anything in them. That's where Amazon Rekognition comes in.

Rekognition's detect_labels API identifies objects, scenes, and concepts in any image. You send it a photo of a park and it returns labels like "Tree", "Person", "Outdoor" with confidence scores for each.

In this step, get ready to:
  • Add a detect_labels function that calls the Rekognition API.
  • Update your main block to run object detection after uploading.
  • Run the script and review detected objects with confidence scores.
Add the detect_labels function

The detect_labels API accepts an S3 object reference (bucket name + key) and returns a list of labels describing what it sees. Each label includes a confidence percentage and parent categories that group it into broader concepts.

  • In analyze_image.py, find the if __name__ == '__main__': line. Add the following function above it:
def detect_labels(bucket_name, key_name):
    """Detect objects and scenes in an image."""
    response = rekognition.detect_labels(
        Image={
            'S3Object': {
                'Bucket': bucket_name,
                'Name': key_name,
            }
        },
        MaxLabels=10,
        MinConfidence=70,
    )

    print("\n--- OBJECTS AND SCENES DETECTED ---")
    for label in response['Labels']:
        print(f"  {label['Name']} (Confidence: {label['Confidence']:.1f}%)")
        if label.get('Parents'):
            parents = ', '.join([p['Name'] for p in label['Parents']])
            print(f"    Categories: {parents}")

What does this code do?

rekognition.detect_labels() sends your S3 image to the Rekognition API and asks it to identify objects and scenes.

  • MaxLabels=10 limits the response to the top 10 most confident labels, keeping output readable.
  • MinConfidence=70 filters out labels that Rekognition is less than 70% sure about. The default is 55%, but 70% gives cleaner results.
  • The loop prints each label's name, confidence score, and parent categories (e.g., "Dog" might have the parent "Animal").
Call detect_labels from your main block

The function exists, but your script doesn't call it yet. You need to add the call in your __main__ block so it runs after uploading.

  • In your __main__ block, find this line:
    # Upload image
    upload_image(BUCKET_NAME, file_path, key_name)

    print("\n--- ANALYSIS COMPLETE ---")
  • Add the following lines between the upload_image call and the ANALYSIS COMPLETE print, so it looks like this:
    # Upload image
    upload_image(BUCKET_NAME, file_path, key_name)

    # Run all analyses
    detect_labels(BUCKET_NAME, key_name)

    print("\n--- ANALYSIS COMPLETE ---")

What's happening here?

detect_labels(BUCKET_NAME, key_name) passes the bucket name and image key to your new function. Rekognition uses this reference to find the image in S3 and analyze it without downloading it to your machine.

  • Save analyze_image.py.

✔️ Awesome, I've got everything!

Great. Double check you've saved your file before running the script.

ⓧ I'd like to double check the full code

Here's the full analyze_image.py file at this point:

import boto3
import sys

# Initialize AWS clients
s3 = boto3.client('s3', region_name='us-east-1')
rekognition = boto3.client('rekognition', region_name='us-east-1')

BUCKET_NAME = 'your-unique-bucket-name-here'


def create_bucket(bucket_name):
    """Create an S3 bucket in us-east-1."""
    s3.create_bucket(Bucket=bucket_name)
    print(f"Bucket '{bucket_name}' created successfully.")


def upload_image(bucket_name, file_path, key_name):
    """Upload a local image file to S3."""
    s3.upload_file(file_path, bucket_name, key_name)
    print(f"Uploaded '{file_path}' to s3://{bucket_name}/{key_name}")


def detect_labels(bucket_name, key_name):
    """Detect objects and scenes in an image."""
    response = rekognition.detect_labels(
        Image={
            'S3Object': {
                'Bucket': bucket_name,
                'Name': key_name,
            }
        },
        MaxLabels=10,
        MinConfidence=70,
    )

    print("\n--- OBJECTS AND SCENES DETECTED ---")
    for label in response['Labels']:
        print(f"  {label['Name']} (Confidence: {label['Confidence']:.1f}%)")
        if label.get('Parents'):
            parents = ', '.join([p['Name'] for p in label['Parents']])
            print(f"    Categories: {parents}")


if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("Usage: python analyze_image.py <image_file_path>")
        print("Example: python analyze_image.py photo.jpg")
        sys.exit(1)

    file_path = sys.argv[1]
    key_name = file_path.split('\\')[-1].split('/')[-1]

    # Create bucket (only needed first time)
    try:
        create_bucket(BUCKET_NAME)
    except s3.exceptions.BucketAlreadyOwnedByYou:
        print(f"Bucket '{BUCKET_NAME}' already exists.")
    except Exception as e:
        if 'BucketAlreadyOwnedByYou' in str(e):
            print(f"Bucket '{BUCKET_NAME}' already exists.")
        else:
            raise

    # Upload image
    upload_image(BUCKET_NAME, file_path, key_name)

    # Run all analyses
    detect_labels(BUCKET_NAME, key_name)

    print("\n--- ANALYSIS COMPLETE ---")
Run your analyzer and review the results
  • Run your script with the same image you uploaded earlier:
python analyze_image.py [[IMAGE_PATH="your-image-file.jpg"]]

Your terminal should display the bucket confirmation, the upload message, and then a new section showing detected objects and scenes with confidence scores.

What should I see?

Your output will look something like this (the exact labels depend on your image):

Bucket 'your-unique-bucket-name-here' already exists.
Uploaded 'photo.jpg' to s3://your-unique-bucket-name-here/photo.jpg

--- OBJECTS AND SCENES DETECTED ---
  Person (Confidence: 98.5%)
    Categories: Human
  Outdoor (Confidence: 95.2%)
  Tree (Confidence: 91.8%)
    Categories: Plant
  Nature (Confidence: 88.3%)

--- ANALYSIS COMPLETE ---

Each label shows what Rekognition identified and how confident it is. Parent categories show how labels relate to broader concepts.

Not seeing any labels?

  • Check that your image is a JPEG or PNG file. Rekognition only supports these two formats.
  • Make sure your BUCKET_NAME constant in the script matches the bucket you created in the previous step.
  • If you see an "AccessDenied" error, confirm your IAM user has the AmazonRekognitionFullAccess policy attached.

Help me debug my Rekognition detect_labels call

Your script can now identify objects and scenes in any photo. Next up, you'll teach it to analyze human faces for emotions, age, and other attributes.

Analyze Faces and Emotions

Your script can now identify objects and scenes in photos. That is useful, but what about the people in those photos?

In this step, you will add facial analysis to your tool. Rekognition can detect faces in an image and return rich details about each one: estimated age range, dominant emotion, whether the person is smiling, wearing glasses, or has a beard.

In this step, get ready to:
  • Add a detect_faces function that calls Rekognition's facial analysis API.
  • Parse the response to extract age, emotions, and facial attributes.
  • Run your script with a photo containing faces and review the analysis report.
Add the detect_faces function

The detect_faces API goes beyond simple face detection. When you pass Attributes=['ALL'], Rekognition returns a detailed breakdown of every face it finds: age estimate, emotional state, smile, glasses, and more.

  • In analyze_image.py, find the end of your detect_labels function (after the line that prints Categories:).
  • Add the following detect_faces function below it:
def detect_faces(bucket_name, key_name):
    """Analyze faces in an image for emotions and attributes."""
    response = rekognition.detect_faces(
        Image={
            'S3Object': {
                'Bucket': bucket_name,
                'Name': key_name,
            }
        },
        Attributes=['ALL'],
    )

    print("\n--- FACIAL ANALYSIS ---")
    if not response['FaceDetails']:
        print("  No faces detected in this image.")
        return

    for i, face in enumerate(response['FaceDetails'], 1):
        print(f"\n  Face #{i}:")
        print(f"    Age Range: {face['AgeRange']['Low']}-{face['AgeRange']['High']} years")

        # Get the dominant emotion
        emotions = sorted(face['Emotions'], key=lambda x: x['Confidence'], reverse=True)
        top_emotion = emotions[0]
        print(f"    Dominant Emotion: {top_emotion['Type']} ({top_emotion['Confidence']:.1f}%)")

        # Additional attributes
        print(f"    Smile: {face['Smile']['Value']} ({face['Smile']['Confidence']:.1f}%)")
        print(f"    Eyeglasses: {face['Eyeglasses']['Value']} ({face['Eyeglasses']['Confidence']:.1f}%)")
        print(f"    Beard: {face['Beard']['Value']} ({face['Beard']['Confidence']:.1f}%)")

What does this code do?

This function sends your S3 image to Rekognition's facial analysis API with Attributes=['ALL'], which tells Rekognition to return every available detail about each face.

  • The early return handles images with no faces gracefully, so the script does not crash.
  • Emotions are sorted by confidence descending, so index [0] is always the strongest detected emotion.
  • Each attribute (Smile, Eyeglasses, Beard) comes with a boolean value and a confidence percentage showing how certain Rekognition is.
Call detect_faces from your main block

Your new function exists, but the script does not call it yet. You need to add it to the main block so it runs automatically after label detection.

  • In analyze_image.py, scroll down to the # Run all analyses section inside the if __name__ == '__main__': block.
  • Find this line:
    # Run all analyses
    detect_labels(BUCKET_NAME, key_name)

    print("\n--- ANALYSIS COMPLETE ---")
  • Add the detect_faces call between detect_labels and the final print, so the section looks like this:
    # Run all analyses
    detect_labels(BUCKET_NAME, key_name)
    detect_faces(BUCKET_NAME, key_name)

    print("\n--- ANALYSIS COMPLETE ---")
  • Save analyze_image.py.
Run the script with a face photo

To test facial analysis, you need an image that contains at least one visible face. A selfie, group photo, or portrait works well.

  • Find a photo on your computer that contains one or more faces (JPEG or PNG format).
  • Run your script with the face photo by running this command:
python analyze_image.py [[FACE_PHOTO_PATH="path to your face photo e.g. selfie.jpg"]]

You should see the label detection output from the previous step, followed by a new --- FACIAL ANALYSIS --- section showing age range, dominant emotion, and attributes for each face detected.

What should I see?

Your terminal output should include something like this:

--- FACIAL ANALYSIS ---

  Face #1:
    Age Range: 25-33 years
    Dominant Emotion: HAPPY (98.7%)
    Smile: True (99.2%)
    Eyeglasses: False (95.1%)
    Beard: False (88.4%)

The exact values depend on the photo you used. If your photo has multiple people, you will see a separate block for each face detected.

Seeing 'No faces detected'?

  • Make sure the face in your photo is clearly visible and not too small. Rekognition needs the face to be a reasonable portion of the image.
  • Check that your image is in JPEG or PNG format. Other formats are not supported.
  • Try a different photo where the person is facing the camera directly.

Why isn't Rekognition detecting faces in my image?

✔️ Awesome, I've got everything!

Great. Double check you have saved analyze_image.py and that your terminal showed facial analysis results.

ⓧ I'd like to double check the full code

Here is the complete analyze_image.py file at this point. Compare it with yours to spot any differences.

import boto3
import sys

# Initialize AWS clients
s3 = boto3.client('s3', region_name='us-east-1')
rekognition = boto3.client('rekognition', region_name='us-east-1')

BUCKET_NAME = 'your-unique-bucket-name-here'


def create_bucket(bucket_name):
    """Create an S3 bucket in us-east-1."""
    s3.create_bucket(Bucket=bucket_name)
    print(f"Bucket '{bucket_name}' created successfully.")


def upload_image(bucket_name, file_path, key_name):
    """Upload a local image file to S3."""
    s3.upload_file(file_path, bucket_name, key_name)
    print(f"Uploaded '{file_path}' to s3://{bucket_name}/{key_name}")


def detect_labels(bucket_name, key_name):
    """Detect objects and scenes in an image."""
    response = rekognition.detect_labels(
        Image={
            'S3Object': {
                'Bucket': bucket_name,
                'Name': key_name,
            }
        },
        MaxLabels=10,
        MinConfidence=70,
    )

    print("\n--- OBJECTS AND SCENES DETECTED ---")
    for label in response['Labels']:
        print(f"  {label['Name']} (Confidence: {label['Confidence']:.1f}%)")
        if label.get('Parents'):
            parents = ', '.join([p['Name'] for p in label['Parents']])
            print(f"    Categories: {parents}")


def detect_faces(bucket_name, key_name):
    """Analyze faces in an image for emotions and attributes."""
    response = rekognition.detect_faces(
        Image={
            'S3Object': {
                'Bucket': bucket_name,
                'Name': key_name,
            }
        },
        Attributes=['ALL'],
    )

    print("\n--- FACIAL ANALYSIS ---")
    if not response['FaceDetails']:
        print("  No faces detected in this image.")
        return

    for i, face in enumerate(response['FaceDetails'], 1):
        print(f"\n  Face #{i}:")
        print(f"    Age Range: {face['AgeRange']['Low']}-{face['AgeRange']['High']} years")

        # Get the dominant emotion
        emotions = sorted(face['Emotions'], key=lambda x: x['Confidence'], reverse=True)
        top_emotion = emotions[0]
        print(f"    Dominant Emotion: {top_emotion['Type']} ({top_emotion['Confidence']:.1f}%)")

        # Additional attributes
        print(f"    Smile: {face['Smile']['Value']} ({face['Smile']['Confidence']:.1f}%)")
        print(f"    Eyeglasses: {face['Eyeglasses']['Value']} ({face['Eyeglasses']['Confidence']:.1f}%)")
        print(f"    Beard: {face['Beard']['Value']} ({face['Beard']['Confidence']:.1f}%)")


if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("Usage: python analyze_image.py <image_file_path>")
        print("Example: python analyze_image.py photo.jpg")
        sys.exit(1)

    file_path = sys.argv[1]
    key_name = file_path.split('\\')[-1].split('/')[-1]

    # Create bucket (only needed first time)
    try:
        create_bucket(BUCKET_NAME)
    except s3.exceptions.BucketAlreadyOwnedByYou:
        print(f"Bucket '{BUCKET_NAME}' already exists.")
    except Exception as e:
        if 'BucketAlreadyOwnedByYou' in str(e):
            print(f"Bucket '{BUCKET_NAME}' already exists.")
        else:
            raise

    # Upload image
    upload_image(BUCKET_NAME, file_path, key_name)

    # Run all analyses
    detect_labels(BUCKET_NAME, key_name)
    detect_faces(BUCKET_NAME, key_name)

    print("\n--- ANALYSIS COMPLETE ---")

Your analyzer can now see objects and understand faces. Next up, you will add the ability to read text from images, turning your tool into a full multi-mode analyzer.

Extract Text from Images

Your analyzer can now identify objects and read facial expressions. The final analysis mode adds text extraction, also known as OCR (Optical Character Recognition).

Text extraction lets your script read words and sentences from photos of signs, documents, receipts, or screenshots. You'll use Rekognition's detect_text API to pull readable text out of any image.

In this step, get ready to:
  • Add a detect_text function that reads words from images using Rekognition.
  • Run your script with a text-containing image and review the extracted lines.
Add the detect_text function

Rekognition's text detection returns every word and line it finds in an image. Your function will filter for complete lines only, which gives cleaner output than individual words.

  • In analyze_image.py, find the detect_faces function. Add the following new function directly below it (after the last line of detect_faces):
def detect_text(bucket_name, key_name):
    """Extract text from an image."""
    response = rekognition.detect_text(
        Image={
            'S3Object': {
                'Bucket': bucket_name,
                'Name': key_name,
            }
        }
    )

    print("\n--- TEXT DETECTED ---")
    lines = [t for t in response['TextDetections'] if t['Type'] == 'LINE']
    if not lines:
        print("  No text detected in this image.")
        return

    for line in lines:
        print(f"  \"{line['DetectedText']}\" (Confidence: {line['Confidence']:.1f}%)")

What does this code do?

rekognition.detect_text() sends your S3 image to Rekognition's text detection API. The response contains every piece of text found in the image.

Rekognition returns two types of detections: LINE (complete sentences or phrases) and WORD (individual words). Filtering for Type == 'LINE' gives you readable text without duplicating every word.

You won't see a change yet. The next substep wires this function into your main block so it actually runs.

Wire up text detection in the main block
  • In analyze_image.py, scroll down to the # Run all analyses section inside if __name__ == '__main__'.
  • Find this line:
    detect_faces(BUCKET_NAME, key_name)
  • Add the following line directly below it, so your main block calls all three analysis functions:
    detect_text(BUCKET_NAME, key_name)

Your # Run all analyses section should now look like this:

    # Run all analyses
    detect_labels(BUCKET_NAME, key_name)
    detect_faces(BUCKET_NAME, key_name)
    detect_text(BUCKET_NAME, key_name)

    print("\n--- ANALYSIS COMPLETE ---")
  • Save analyze_image.py.
Run your analyzer on a text image

To test text extraction, you need an image that contains readable text. A photo of a street sign, a book cover, a screenshot, or a receipt all work well.

  • Find or take a photo that has visible text in it. Save it to the same folder as analyze_image.py.
  • Run your script with the text image by running this command:
python analyze_image.py [[TEXT_IMAGE="your-text-image.jpg"]]

You should see the full analysis report including a --- TEXT DETECTED --- section. Each line of text from your image appears in quotes with a confidence percentage.

What should I see?

Your terminal prints the objects, faces, and text sections in sequence. The text section shows each detected line in quotes with its confidence score. For example, a photo of a stop sign might output:

--- TEXT DETECTED ---
  "STOP" (Confidence: 99.8%)

If your image has no readable text, you'll see No text detected in this image. instead.

Not seeing any text detected?

  • Make sure your image actually contains clearly visible text. Blurry or very small text may not be detected.
  • Rekognition supports JPEG and PNG formats. If your image is a different format, convert it first.
  • Check that you added detect_text(BUCKET_NAME, key_name) in the main block. Without it, the function exists but never runs.

Help me debug why my detect_text function isn't returning results.

✔️ Awesome, I've got everything!

Great. Double check you've saved analyze_image.py and your script is producing all three analysis sections (objects, faces, and text).

ⓧ I'd like to double check the full code

Here's the complete analyze_image.py file at this point. Compare it against yours:

import boto3
import sys

# Initialize AWS clients
s3 = boto3.client('s3', region_name='us-east-1')
rekognition = boto3.client('rekognition', region_name='us-east-1')

BUCKET_NAME = 'your-unique-bucket-name-here'


def create_bucket(bucket_name):
    """Create an S3 bucket in us-east-1."""
    s3.create_bucket(Bucket=bucket_name)
    print(f"Bucket '{bucket_name}' created successfully.")


def upload_image(bucket_name, file_path, key_name):
    """Upload a local image file to S3."""
    s3.upload_file(file_path, bucket_name, key_name)
    print(f"Uploaded '{file_path}' to s3://{bucket_name}/{key_name}")


def detect_labels(bucket_name, key_name):
    """Detect objects and scenes in an image."""
    response = rekognition.detect_labels(
        Image={
            'S3Object': {
                'Bucket': bucket_name,
                'Name': key_name,
            }
        },
        MaxLabels=10,
        MinConfidence=70,
    )

    print("\n--- OBJECTS AND SCENES DETECTED ---")
    for label in response['Labels']:
        print(f"  {label['Name']} (Confidence: {label['Confidence']:.1f}%)")
        if label.get('Parents'):
            parents = ', '.join([p['Name'] for p in label['Parents']])
            print(f"    Categories: {parents}")


def detect_faces(bucket_name, key_name):
    """Analyze faces in an image for emotions and attributes."""
    response = rekognition.detect_faces(
        Image={
            'S3Object': {
                'Bucket': bucket_name,
                'Name': key_name,
            }
        },
        Attributes=['ALL'],
    )

    print("\n--- FACIAL ANALYSIS ---")
    if not response['FaceDetails']:
        print("  No faces detected in this image.")
        return

    for i, face in enumerate(response['FaceDetails'], 1):
        print(f"\n  Face #{i}:")
        print(f"    Age Range: {face['AgeRange']['Low']}-{face['AgeRange']['High']} years")

        # Get the dominant emotion
        emotions = sorted(face['Emotions'], key=lambda x: x['Confidence'], reverse=True)
        top_emotion = emotions[0]
        print(f"    Dominant Emotion: {top_emotion['Type']} ({top_emotion['Confidence']:.1f}%)")

        # Additional attributes
        print(f"    Smile: {face['Smile']['Value']} ({face['Smile']['Confidence']:.1f}%)")
        print(f"    Eyeglasses: {face['Eyeglasses']['Value']} ({face['Eyeglasses']['Confidence']:.1f}%)")
        print(f"    Beard: {face['Beard']['Value']} ({face['Beard']['Confidence']:.1f}%)")


def detect_text(bucket_name, key_name):
    """Extract text from an image."""
    response = rekognition.detect_text(
        Image={
            'S3Object': {
                'Bucket': bucket_name,
                'Name': key_name,
            }
        }
    )

    print("\n--- TEXT DETECTED ---")
    lines = [t for t in response['TextDetections'] if t['Type'] == 'LINE']
    if not lines:
        print("  No text detected in this image.")
        return

    for line in lines:
        print(f"  \"{line['DetectedText']}\" (Confidence: {line['Confidence']:.1f}%)")


if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("Usage: python analyze_image.py <image_file_path>")
        print("Example: python analyze_image.py photo.jpg")
        sys.exit(1)

    file_path = sys.argv[1]
    key_name = file_path.split('\\')[-1].split('/')[-1]

    # Create bucket (only needed first time)
    try:
        create_bucket(BUCKET_NAME)
    except s3.exceptions.BucketAlreadyOwnedByYou:
        print(f"Bucket '{BUCKET_NAME}' already exists.")
    except Exception as e:
        if 'BucketAlreadyOwnedByYou' in str(e):
            print(f"Bucket '{BUCKET_NAME}' already exists.")
        else:
            raise

    # Upload image
    upload_image(BUCKET_NAME, file_path, key_name)

    # Run all analyses
    detect_labels(BUCKET_NAME, key_name)
    detect_faces(BUCKET_NAME, key_name)
    detect_text(BUCKET_NAME, key_name)

    print("\n--- ANALYSIS COMPLETE ---")

Your Smart Image Analyzer is now complete. It can detect objects, analyze faces, and extract text from any image you throw at it. Up next, the Secret Mission challenges you to add celebrity recognition and face comparison.

Secret mission

Add Celebrity Recognition and Face Comparison

Your image analyzer already detects objects, faces, and text. But Rekognition can do even more. In this secret mission, you'll add celebrity recognition and face comparison to your tool, plus a command-line mode selector so users can choose which analysis to run.

Clean Up Your Resources

Clean Up Your Resources

This project uses AWS Free Tier services, so there are no ongoing costs as long as you stay within the free tier limits. Decide whether to keep your resources running, pause them to come back later, or delete them entirely.

Cost warning

The AWS Free Tier covers this project for 12 months after account creation. After that period, S3 storage and Rekognition API calls will incur charges.

If you do not plan to use these resources again, choose the Delete option below to avoid any future charges.

Resources you used:

  • S3 bucket (free storage up to 5 GB for 12 months).
  • IAM user with access keys (no cost, but rotate or delete keys when not in use).
  • Rekognition API calls (free up to 1,000 images per month for 12 months).
  • Local Python script (analyze_image.py on your computer, no ongoing cost).

Keep everything running

No action needed. Choose this if you are still actively experimenting with Rekognition or plan to add the Secret Mission features.

  • Your S3 bucket, IAM user, and local script all remain ready to use.
  • You will stay within the free tier as long as you analyze fewer than 1,000 images per month.

Pause - I'll come back to this later

Deactivate your IAM access key to prevent accidental usage. You can reactivate it any time you want to continue.

  • Open the AWS Console and navigate to IAM.
  • Click Users and select your IAM user.
  • Click the Security credentials tab.
  • Find your access key and click Actions, then Deactivate.
  • Your S3 bucket and files remain intact. When you are ready to resume, reactivate the key from the same page.

Delete - I don't want to use this again

Remove all project resources and credentials completely. This frees up your AWS account and local machine.

  • Open the AWS Console and navigate to S3.
  • Select your bucket, click Empty to remove all objects, then click Delete to remove the bucket itself.
  • Navigate to IAM, click Users, select your IAM user, and click Delete.
  • Delete your local AWS credentials by removing the files in %UserProfile%\.aws\ (Windows) or ~/.aws/ (macOS/Linux).
  • Delete the analyze_image.py file and any test images from your computer.

That's a Wrap!

That's a Wrap!

Nice work! You just built a computer vision tool powered by AWS AI services.

You've learned how to:

  • Configured programmatic access to AWS using an IAM user, access keys, and the AWS CLI.
  • Stored images in Amazon S3 and called three Rekognition APIs to detect objects, analyze faces, and extract text.
  • Built a reusable Python script that analyzes any image with a single command using boto3.
  • Secret Mission: Added celebrity recognition and face comparison capabilities to your analyzer.

Ready to quiz yourself?