Image Label Generator with Rekognition

Build a Python CLI tool that detects objects in images using AWS Rekognition.

Introduction

30 Second Summary

Every day, apps sort your photos into albums, suggest tags, and filter content automatically. Behind the scenes, computer vision models analyze images to identify what's in them.

In this project, you will build a Python command-line tool that sends local images to AWS Rekognition and displays what the AI detects. You'll see object labels, confidence scores, and category hierarchies right in your terminal.

What You'll Build

A Python CLI tool that reads local images and uses the AWS Rekognition DetectLabels API to identify objects, scenes, and concepts.

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

  • A working Python script (label_generator.py) that analyzes images and displays detected labels with confidence scores.
  • Formatted terminal output with visual confidence bars, label hierarchies, and bounding box instance counts.
  • Batch processing capability that analyzes entire folders of images and produces a cross-image summary.
  • Secret Mission: Add dominant color detection using Rekognition's IMAGE_PROPERTIES feature.

Are there any prerequisites?

You'll need an AWS account with the AWS CLI already configured, and Python 3.10+ installed on your machine. Step 1 walks you through verifying everything is ready.

Before We Start

AWS Rekognition is a managed computer vision service that can identify objects, scenes, and concepts in images. Instead of training your own machine learning model, you can send image bytes directly to the API and get back structured labels with confidence scores.

Before writing any code, you need to make sure your local environment can talk to AWS and that you have the right permissions for Rekognition. In this step, you will install the AWS SDK for Python, verify your credentials, and set up a project folder with sample images.

In this step, get ready to:
  • Install boto3 and verify your Python and AWS CLI setup.
  • Confirm your IAM permissions include Rekognition access.
  • Create a project folder with test images and an empty script file.
Install boto3 and verify your environment

boto3 is the official AWS SDK for Python. It gives your Python code the ability to call AWS services like Rekognition directly.

  • Confirm your Python version is 3.10 or higher by running this command:
python --version

You should see a version number like Python 3.10.x or higher.

Seeing a version lower than 3.10?

boto3 requires Python 3.10 or above. If your system reports an older version, try running python3 --version instead. On macOS, the default python command may point to an older system Python.

If you need to install or upgrade Python, visit the official Python downloads page and install version 3.10 or newer.

Help me fix my Python version for this project

  • Install boto3 by running this command:
pip install boto3

You should see output ending with a line like Successfully installed boto3-... confirming the package is ready.

Getting a permission error?

If you see a permission denied message, try running pip install --user boto3 instead. On some systems you may need to use pip3 rather than pip.

Help me install boto3 on my system

  • Verify your AWS CLI credentials are working by running this command:
aws sts get-caller-identity

You should see a JSON response containing your UserId, Account, and Arn. This confirms your CLI can reach AWS.

Getting a credentials error?

This means your AWS CLI is not configured or the credentials have expired. Run aws configure and enter your Access Key ID, Secret Access Key, and default region. You can find these in the AWS IAM console under your user's security credentials.

Help me configure my AWS CLI credentials

  • Confirm Rekognition is available in your CLI by running this command:
aws rekognition detect-labels help

You should see a help page with the heading DETECT-LABELS and a list of available options. Press q to exit the help page.

Verify IAM permissions

Your AWS user or role needs permission to call the Rekognition API. The simplest way to grant this is with the AmazonRekognitionFullAccess managed policy.

  • Open the IAM console in your browser at https://console.aws.amazon.com/iam.
  • Click Users in the left sidebar.
  • Click on your IAM user name (the one shown in your aws sts get-caller-identity output).
  • Click the Permissions tab.
  • Check whether AmazonRekognitionFullAccess (or a broader policy like AdministratorAccess) appears in the list.

✔️ I see the policy listed

You are all set. Your IAM user has the permissions needed to call Rekognition.

ⓧ I don't see it

  • Click Add permissions, then Attach policies directly.
  • Search for AmazonRekognitionFullAccess.
  • Check the box next to it and click Add permissions.

The policy should now appear under your user's permissions list.

Why no S3 permissions?

In this project, you will send image bytes directly to Rekognition from your local machine. There is no need to upload images to S3 first. This keeps the project focused on the Rekognition API itself rather than managing AWS infrastructure.

Prepare test images and create your project file

You need a project folder with some sample images for Rekognition to analyze. Photos of everyday objects (a coffee mug, a dog, a street scene) work great for testing.

  • Move to your Desktop by running this command:
cd ~/Desktop
  • Create your project folder and move into it by running these commands:
mkdir image-label-generator
cd image-label-generator
  • Create a subfolder to hold your test images by running this command:
mkdir images
  • Copy 3-5 JPEG or PNG photos into the images folder. Use your file manager (Finder on macOS, File Explorer on Windows) to drag photos into the folder.

Keep images under 5MB

Rekognition accepts image bytes up to 5MB when sent directly. Most phone photos are within this limit, but screenshots from high-resolution displays may exceed it. If an image is too large, resize it or choose a different one.

  • Create the empty Python script file by running this command:
touch label_generator.py
  • Confirm everything was created by running:
ls

You should see images and label_generator.py in the output.

Don't see both items listed?

Make sure you are inside the image-label-generator folder. Run pwd to check your current directory. If you are somewhere else, run cd ~/Desktop/image-label-generator and try again.

Help me find my project folder

Your environment is ready. Next up, you will write the core function that sends an image to AWS Rekognition and gets back what the AI sees.

Analyze a Single Image

Your environment is set up and ready to talk to AWS. Now it's time to write the code that actually sends an image to AWS Rekognition and gets back a list of everything the AI detects in it.

In this step, you'll build the core function that reads an image from your file system, sends its raw bytes to Rekognition's DetectLabels API, and prints what the service found. By the end, you'll have a working script you can point at any JPEG or PNG.

In this step, get ready to:
  • Write a function that sends image bytes to AWS Rekognition and returns detected labels.
  • Run the script against a sample image and see label names with confidence scores in your terminal.
Write the core analysis function

The DetectLabels API accepts raw image bytes and returns a structured response with every object, scene, and concept Rekognition can identify. Your function will handle the file reading and API call in one reusable unit.

  • Press Cmd+Space (macOS) or the Windows key (Windows) to open your search bar.
  • Type VS Code and press Enter to open it.
  • Click File in the top menu bar.
  • Click Open Folder.
  • Select your project folder (the one containing your sample images and label_generator.py), then click Open.
  • In the Explorer sidebar on the left, click label_generator.py to open it in the editor.
  • Add the following code to label_generator.py:
import boto3
import sys
import os


def analyze_image(image_path, max_labels=10, min_confidence=70):
    """Analyze a single image using AWS Rekognition DetectLabels."""
    # Create a Rekognition client using your configured AWS credentials
    rekognition = boto3.client('rekognition')

    # Open the image file and read its raw bytes
    with open(image_path, 'rb') as image_file:
        image_bytes = image_file.read()

    # Call DetectLabels with the image bytes
    response = rekognition.detect_labels(
        Image={'Bytes': image_bytes},
        MaxLabels=max_labels,
        MinConfidence=min_confidence,
        Features=['GENERAL_LABELS']
    )

    return response

What does this code do?

boto3.client('rekognition') creates a client that uses the AWS credentials you already configured in Step 1. It knows your region and access keys from your ~/.aws/ config files.

The function reads image bytes with open(image_path, 'rb') (the 'rb' means "read binary") and passes them directly to Rekognition. MaxLabels=10 caps the output to 10 results, and MinConfidence=70 filters out anything the AI is less than 70% sure about.

  • You won't see output yet. The next chunk adds the code that actually calls this function.
Add basic output and test

A Python script needs a __main__ block to run when you execute it from the terminal. This block will read the image path from the command line, call your function, and print what Rekognition found.

  • Add this code below the analyze_image function in label_generator.py:
if __name__ == '__main__':
    # Check that the user provided an image path
    if len(sys.argv) < 2:
        print(f"Usage: python {sys.argv[0]} <image_path>")
        sys.exit(1)

    path = sys.argv[1]
    # Analyze the image and print each label with its confidence
    response = analyze_image(path)
    for label in response['Labels']:
        print(label['Name'], label['Confidence'])

What does this code do?

sys.argv[1] grabs the first argument you type after the script name in the terminal. If no argument is provided, the script prints a usage hint and exits.

The for loop walks through every label in the response and prints its Name (what Rekognition detected) and Confidence (how sure it is, as a percentage from 0 to 100).

  • Save label_generator.py by pressing Cmd+S (macOS) or Ctrl+S (Windows).
  • Open the terminal in VS Code by pressing Ctrl+` (backtick key, same shortcut on both platforms).
  • Test your script by running this command (replace the filename with one of your sample images):
python label_generator.py [[IMAGE_FILE="your-image.jpg"]]
  • You should see output listing detected objects, each with a label name followed by a confidence number (e.g., Person 98.7 or Car 95.2).

Not seeing any output or getting an error?

  • If you see FileNotFoundError, double-check that the image filename matches exactly what's in your project folder (including the file extension).
  • If you see NoCredentialsError: Unable to locate credentials, your AWS CLI is not configured in this terminal session. Run aws sts get-caller-identity to verify.
  • If you see InvalidImageFormatException, your file is not a valid JPEG or PNG. Try a different image.

Help me debug my Rekognition script

✔️ Awesome, I've got everything!

Great. Double check you've saved label_generator.py and move on to the next step.

ⓧ I'd like to double check the full code

Here is the complete label_generator.py at this point:

import boto3
import sys
import os


def analyze_image(image_path, max_labels=10, min_confidence=70):
    """Analyze a single image using AWS Rekognition DetectLabels."""
    rekognition = boto3.client('rekognition')

    with open(image_path, 'rb') as image_file:
        image_bytes = image_file.read()

    response = rekognition.detect_labels(
        Image={'Bytes': image_bytes},
        MaxLabels=max_labels,
        MinConfidence=min_confidence,
        Features=['GENERAL_LABELS']
    )

    return response


if __name__ == '__main__':
    if len(sys.argv) < 2:
        print(f"Usage: python {sys.argv[0]} <image_path>")
        sys.exit(1)

    path = sys.argv[1]
    response = analyze_image(path)
    for label in response['Labels']:
        print(label['Name'], label['Confidence'])

Your script can now identify objects in any image with a single command. Next up, you'll format this raw output into something much easier to read, with visual confidence bars and label hierarchies.

Enhance the Output

Your script can already detect objects in images and return raw data from AWS Rekognition. The problem is that the output is a wall of unformatted text.

In this step, you will build a formatted display function that turns Rekognition's raw response into a readable report. Each label will show a visual confidence bar, its category hierarchy, and how many instances were detected.

In this step, get ready to:
  • Build a formatted display function with confidence bars.
  • Add label hierarchies and instance counts to the output.
  • Test the enhanced output with several different images.
Build formatted display with confidence bars

Right now, your script prints each label's name and a raw float number. A dedicated display function will make the output scannable at a glance.

  • In label_generator.py, add the following display_labels function below the analyze_image function (after the return response line):
def display_labels(image_path, response):
    """Display detected labels in a formatted way."""
    print(f"\n{'=' * 60}")
    print(f"Image: {os.path.basename(image_path)}")
    print(f"{'=' * 60}")

    labels = response['Labels']
    print(f"\nDetected {len(labels)} labels:\n")

    for label in labels:
        confidence = label['Confidence']
        name = label['Name']
        bar = '#' * int(confidence / 5)
        print(f"  {name:<25} {confidence:>6.1f}%  {bar}")

    print()

What does this code do?

This function takes the image path and the raw API response, then formats each label into a readable line.

  • The = border and filename header visually separate results for each image.
  • The format string {name:<25} left-aligns the label name in a 25-character column so everything lines up.
  • The bar variable creates a row of # characters proportional to the confidence score (one hash per 5 percentage points).
  • Save label_generator.py.

Seeing a SyntaxError?

Check that the f-string f"\n{'=' * 60}" has both the outer double quotes and the inner curly braces intact. Missing a quote or brace breaks the whole function.

Also confirm that display_labels is at the same indentation level as analyze_image (not nested inside it).

Still stuck? Help me fix a SyntaxError in my display_labels function

Add label hierarchies and instance counts

Rekognition doesn't just return flat labels. Each label includes a hierarchy of parent categories and, when applicable, a count of detected bounding box instances. Adding these details to the output tells you much more about what the AI sees.

  • In your display_labels function, find this line inside the for loop:
        print(f"  {name:<25} {confidence:>6.1f}%  {bar}")
  • Add the following code directly below that line (still inside the for loop, before the final print()):
        if label['Parents']:
            parents = ' > '.join([p['Name'] for p in label['Parents']])
            print(f"  {'':25} Category: {parents}")

        if label['Instances']:
            print(f"  {'':25} Instances: {len(label['Instances'])} detected")

What does this code do?

  • The label['Parents'] field contains a list of parent categories for each label. Joining them with > shows the full category chain (e.g., Car > Vehicle > Transportation).
  • The label['Instances'] field lists each bounding box where that label was detected. Printing the count tells you how many separate occurrences the AI found.
  • The {'':25} padding aligns these detail lines under the label name above.
  • Save label_generator.py.

IndentationError?

Both if blocks must be at the same indentation level as the confidence = label['Confidence'] line above them (two levels: one for the function, one for the for loop).

Need a hand? Help me fix an IndentationError in my display_labels function

Update the main block and test with different images

The __main__ block still uses the old raw print loop. You need to swap it out for display_labels and add a file-existence check so the script fails gracefully on bad paths.

  • In label_generator.py, find the entire if __name__ == '__main__': block at the bottom of the file.
  • Replace the entire block with the following:
if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("Usage:")
        print(f"  python {sys.argv[0]} <image_path>")
        sys.exit(1)

    path = sys.argv[1]
    if os.path.isfile(path):
        response = analyze_image(path)
        display_labels(path, response)
    else:
        print(f"Error: '{path}' is not a valid file.")
        sys.exit(1)

What changed in the main block?

  • The raw for label in response['Labels'] loop is gone. Now display_labels handles all formatting.
  • The os.path.isfile(path) check catches typos or missing files before the API call, saving you from a confusing traceback.
  • The usage message now spans two lines for readability.
  • Save label_generator.py.
  • Run the script against one of your sample images by running:
python label_generator.py [[IMAGE_FILE="your_image.jpg"]]

You should see a formatted report with a =-bordered header, each label's name and confidence bar, category hierarchies, and instance counts.

  • Run the script against 2-3 more images from your project folder to see how labels vary.

Why do results vary so much?

Rekognition returns multiple related labels for a single subject. A photo of a flower might produce labels like "Flower", "Plant", and "Tulip" at different confidence levels.

The parent hierarchy shows how these labels relate. "Tulip" might have parents "Flower > Plant", revealing how Rekognition organizes its label taxonomy.

Seeing a FileNotFoundError?

Make sure the image path you pass to the script is relative to where you run the command. If your image is in a subfolder, include the folder name (e.g., images/photo.jpg).

Also confirm your images are under 5MB each. Rekognition rejects larger files when sending bytes directly.

Need help? Help me debug why my image analysis command is failing

✔️ Awesome, I've got everything!

Great. Double check you have saved label_generator.py before moving on.

ⓧ I'd like to double check the full code

Here is the complete label_generator.py at this point:

import boto3
import sys
import os


def analyze_image(image_path, max_labels=10, min_confidence=70):
    """Analyze a single image using AWS Rekognition DetectLabels."""
    rekognition = boto3.client('rekognition')

    with open(image_path, 'rb') as image_file:
        image_bytes = image_file.read()

    response = rekognition.detect_labels(
        Image={'Bytes': image_bytes},
        MaxLabels=max_labels,
        MinConfidence=min_confidence,
        Features=['GENERAL_LABELS']
    )

    return response


def display_labels(image_path, response):
    """Display detected labels in a formatted way."""
    print(f"\n{'=' * 60}")
    print(f"Image: {os.path.basename(image_path)}")
    print(f"{'=' * 60}")

    labels = response['Labels']
    print(f"\nDetected {len(labels)} labels:\n")

    for label in labels:
        confidence = label['Confidence']
        name = label['Name']
        bar = '#' * int(confidence / 5)
        print(f"  {name:<25} {confidence:>6.1f}%  {bar}")

        if label['Parents']:
            parents = ' > '.join([p['Name'] for p in label['Parents']])
            print(f"  {'':25} Category: {parents}")

        if label['Instances']:
            print(f"  {'':25} Instances: {len(label['Instances'])} detected")

    print()


if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("Usage:")
        print(f"  python {sys.argv[0]} <image_path>")
        sys.exit(1)

    path = sys.argv[1]
    if os.path.isfile(path):
        response = analyze_image(path)
        display_labels(path, response)
    else:
        print(f"Error: '{path}' is not a valid file.")
        sys.exit(1)

Your tool now produces clean, readable reports for any image you throw at it. Next up, you will add batch processing so you can analyze entire folders at once and see patterns across multiple images.

Add Batch Processing

Your tool can now analyze a single image and present its labels beautifully with confidence bars, hierarchies, and instance counts. In a real workflow, you rarely analyze just one image at a time.

In this step, you will add a batch processing mode that analyzes every image in a folder and generates a cross-image summary showing the most common labels. This turns your tool from a single-file utility into something you could point at an entire photo library.

In this step, get ready to:
  • Build a folder analysis function that iterates through all images in a directory.
  • Generate a cross-image summary showing the most frequently detected labels.
  • Wire up the CLI with a --batch flag to switch between single and batch modes.
Build the folder analysis function

When you point the tool at a folder, it needs to find all supported image files, analyze each one, and handle errors gracefully so a single bad file does not stop the entire batch.

  • In label_generator.py, find the print() at the end of your display_labels function.
  • Below it, add the analyze_folder function by copying the following code:
def analyze_folder(folder_path, max_labels=10, min_confidence=70):
    """Analyze all JPEG and PNG images in a folder."""
    supported_extensions = ('.jpg', '.jpeg', '.png')
    images = [
        f for f in os.listdir(folder_path)
        if f.lower().endswith(supported_extensions)
    ]

    if not images:
        print(f"No supported images found in {folder_path}")
        return

    print(f"\nFound {len(images)} images to analyze...")

    all_results = {}
    for image_file in sorted(images):
        image_path = os.path.join(folder_path, image_file)
        try:
            response = analyze_image(image_path, max_labels, min_confidence)
            display_labels(image_path, response)
            all_results[image_file] = response['Labels']
        except Exception as e:
            print(f"  Error analyzing {image_file}: {e}")

    print_summary(all_results)

What does this code do?

This function scans a folder for all .jpg, .jpeg, and .png files using os.listdir().

It loops through each image alphabetically, calling your existing analyze_image and display_labels functions for each one. The try/except block ensures that if one image fails (too large, corrupted, wrong format), the batch keeps processing the rest.

Results are collected in the all_results dictionary so we can generate a summary at the end.

  • Save label_generator.py.
  • You will not see a change yet. The next chunk adds the summary function that analyze_folder calls at the end.
Generate a cross-image summary

After analyzing a batch of images, you want to see which labels appeared most often across the entire set. This helps you spot themes or dominant objects in a collection of photos.

  • In label_generator.py, directly below the analyze_folder function you just added, paste the print_summary function:
def print_summary(all_results):
    """Print a summary of all labels found across images."""
    print(f"\n{'=' * 60}")
    print("BATCH SUMMARY")
    print(f"{'=' * 60}")
    print(f"Images analyzed: {len(all_results)}")

    label_counts = {}
    for labels in all_results.values():
        for label in labels:
            name = label['Name']
            if name in label_counts:
                label_counts[name] += 1
            else:
                label_counts[name] = 1

    sorted_labels = sorted(label_counts.items(), key=lambda x: x[1], reverse=True)
    print(f"\nMost common labels across all images:")
    for name, count in sorted_labels[:10]:
        print(f"  {name:<25} found in {count} image(s)")

What does this code do?

The print_summary function counts how many images each label appeared in by iterating through every label in the all_results dictionary.

It sorts labels by frequency (most common first) and displays the top 10. This gives you a quick overview of what Rekognition detected most often across your entire image collection.

  • Save label_generator.py.
  • You will not see a change yet. The next chunk wires up the CLI to call analyze_folder when you pass the --batch flag.
Wire up the CLI with a --batch flag

Your new functions are ready, but the script's entry point still only handles single files. You need to update the __main__ block to detect a --batch argument and route to the folder function.

  • In label_generator.py, scroll to the bottom and find the existing if __name__ == '__main__': block.
  • Find this code:
if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("Usage:")
        print(f"  python {sys.argv[0]} <image_path>")
        sys.exit(1)

    path = sys.argv[1]
    if os.path.isfile(path):
        response = analyze_image(path)
        display_labels(path, response)
    else:
        print(f"Error: '{path}' is not a valid file.")
        sys.exit(1)
  • Replace the entire if __name__ == '__main__': block with this updated version:
if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("Usage:")
        print(f"  python {sys.argv[0]} <image_path>")
        print(f"  python {sys.argv[0]} <folder_path> --batch")
        sys.exit(1)

    path = sys.argv[1]
    batch_mode = '--batch' in sys.argv

    if batch_mode and os.path.isdir(path):
        analyze_folder(path)
    elif os.path.isfile(path):
        response = analyze_image(path)
        display_labels(path, response)
    else:
        print(f"Error: '{path}' is not a valid file or directory.")
        sys.exit(1)

What changed here?

The usage message now shows the --batch option so learners know it exists.

The batch_mode variable checks whether --batch appears anywhere in the arguments. If it does and the path is a directory, the script calls analyze_folder. Otherwise it falls through to single-file analysis or an error message.

  • Save label_generator.py.
  • Test batch mode by running this command (make sure your images folder contains at least 2-3 JPEG or PNG files):
python label_generator.py ./images --batch

You should see each image analyzed individually with its labels, followed by a BATCH SUMMARY section listing the most common labels across all images.

Not seeing any output or getting errors?

  • Make sure the path you pass (e.g. ./images) is actually a folder containing .jpg, .jpeg, or .png files. Other formats like GIF or WebP are not supported by Rekognition.
  • If you see an error mentioning invalid image format, confirm your files are genuine JPEG/PNG images (not renamed from another format).
  • Check that each image is under 5MB. Larger files will throw an ImageTooLargeException error, but the try/except block will catch it and continue.

Still stuck? Help me debug my batch processing output.

✔️ Awesome, I've got everything!

Great. Double check you have saved label_generator.py and move on to the next section.

ⓧ I'd like to double check the full code

import boto3
import sys
import os


def analyze_image(image_path, max_labels=10, min_confidence=70):
    """Analyze a single image using AWS Rekognition DetectLabels."""
    rekognition = boto3.client('rekognition')

    with open(image_path, 'rb') as image_file:
        image_bytes = image_file.read()

    response = rekognition.detect_labels(
        Image={'Bytes': image_bytes},
        MaxLabels=max_labels,
        MinConfidence=min_confidence,
        Features=['GENERAL_LABELS']
    )

    return response


def display_labels(image_path, response):
    """Display detected labels in a formatted way."""
    print(f"\n{'=' * 60}")
    print(f"Image: {os.path.basename(image_path)}")
    print(f"{'=' * 60}")

    labels = response['Labels']
    print(f"\nDetected {len(labels)} labels:\n")

    for label in labels:
        confidence = label['Confidence']
        name = label['Name']
        bar = '#' * int(confidence / 5)
        print(f"  {name:<25} {confidence:>6.1f}%  {bar}")

        if label['Parents']:
            parents = ' > '.join([p['Name'] for p in label['Parents']])
            print(f"  {'':25} Category: {parents}")

        if label['Instances']:
            print(f"  {'':25} Instances: {len(label['Instances'])} detected")

    print()


def analyze_folder(folder_path, max_labels=10, min_confidence=70):
    """Analyze all JPEG and PNG images in a folder."""
    supported_extensions = ('.jpg', '.jpeg', '.png')
    images = [
        f for f in os.listdir(folder_path)
        if f.lower().endswith(supported_extensions)
    ]

    if not images:
        print(f"No supported images found in {folder_path}")
        return

    print(f"\nFound {len(images)} images to analyze...")

    all_results = {}
    for image_file in sorted(images):
        image_path = os.path.join(folder_path, image_file)
        try:
            response = analyze_image(image_path, max_labels, min_confidence)
            display_labels(image_path, response)
            all_results[image_file] = response['Labels']
        except Exception as e:
            print(f"  Error analyzing {image_file}: {e}")

    print_summary(all_results)


def print_summary(all_results):
    """Print a summary of all labels found across images."""
    print(f"\n{'=' * 60}")
    print("BATCH SUMMARY")
    print(f"{'=' * 60}")
    print(f"Images analyzed: {len(all_results)}")

    label_counts = {}
    for labels in all_results.values():
        for label in labels:
            name = label['Name']
            if name in label_counts:
                label_counts[name] += 1
            else:
                label_counts[name] = 1

    sorted_labels = sorted(label_counts.items(), key=lambda x: x[1], reverse=True)
    print(f"\nMost common labels across all images:")
    for name, count in sorted_labels[:10]:
        print(f"  {name:<25} found in {count} image(s)")


if __name__ == '__main__':
    if len(sys.argv) < 2:
        print("Usage:")
        print(f"  python {sys.argv[0]} <image_path>")
        print(f"  python {sys.argv[0]} <folder_path> --batch")
        sys.exit(1)

    path = sys.argv[1]
    batch_mode = '--batch' in sys.argv

    if batch_mode and os.path.isdir(path):
        analyze_folder(path)
    elif os.path.isfile(path):
        response = analyze_image(path)
        display_labels(path, response)
    else:
        print(f"Error: '{path}' is not a valid file or directory.")
        sys.exit(1)

Secret mission

Detect Dominant Colors with IMAGE_PROPERTIES

Your label generator tells you what's in an image. But what about the visual feel? Extend your tool to detect dominant colors and image quality metrics using Rekognition's IMAGE_PROPERTIES feature.

Clean Up Your Resources

Clean Up Your Resources

This project runs entirely locally and uses a stateless API. There are no ongoing costs or running services to worry about.

Decide whether to keep your project files for future use, or delete them entirely.

Resources you used:

  • Project folder on your Desktop containing label_generator.py and test images (local files).
  • boto3 Python package (installed via pip).

No persistent cloud resources

AWS Rekognition's DetectLabels API is stateless. Each call processes the image and returns results without storing anything on AWS. No S3 buckets, Lambda functions, or IAM roles were created during this project.

The free tier covers 1,000 images per month for 12 months from account creation. Your usage during this project counts toward that allowance but does not create any billable resources that persist after the call.

Keep everything running

No action needed. Choose this if you plan to keep experimenting with the label generator or want to reference the code later.

  • Your project folder stays on your Desktop.
  • The boto3 package remains available for other AWS projects.
  • Each time you run the script, it makes a Rekognition API call that counts toward your free tier (1,000 images/month).

Pause - I'll come back to this later

Since there are no running processes or persistent cloud resources, pausing is the same as keeping. Your files sit idle on disk with zero cost.

  • No services to stop or suspend.
  • Your project folder and boto3 package remain in place until you decide to delete them.

Delete - I don't want to use this again

Remove all project files and optionally uninstall the boto3 package.

  • Delete the project folder by running the commands below for your operating system.
  • Uninstall boto3 if you no longer need it for other projects.

On macOS/Linux, remove the project folder:

cd ~/Desktop
rm -rf label-generator

On Windows, remove the project folder:

cd ~\Desktop
rmdir /s /q label-generator

To uninstall boto3:

pip uninstall boto3

Nice Work!

Nice Work!

You just built a fully functional image analysis tool powered by AWS Rekognition. From a single Python script, you can now identify objects, scenes, and concepts in any image with confidence scores and label hierarchies.

You've learned how to:

  • Built a Python CLI tool that sends local image bytes to AWS Rekognition's DetectLabels API and displays detected labels with confidence scores, visual bars, and parent hierarchies.
  • Added batch processing to analyze entire folders of images and generate a cross-image summary of the most common labels.
  • Integrated a managed AWS AI service directly into a Python application through boto3, proving you can leverage powerful computer vision without any ML expertise.
  • Secret Mission: Extended the tool with IMAGE_PROPERTIES to detect dominant colors and image quality metrics like brightness, sharpness, and contrast.

Ready to quiz yourself?