Python: Load, Display & Save Images for AI & ML

Master loading, displaying, and saving images in Python for AI, ML, and computer vision projects. Hands-on guide with OpenCV & Pillow.

Hands-on Guide: Loading, Displaying, and Saving Images with Python

Working with images is a fundamental aspect of computer vision and image processing. Whether you're developing AI applications, photo editing tools, or simply learning Python, understanding how to load, display, and save images using libraries like OpenCV and Pillow (PIL) is essential.

This guide will walk you through the core concepts and provide practical examples.

1. Prerequisites

Before you begin, ensure you have the following installed:

  • Python: Installed on your system.
  • Required Libraries:
    • opencv-python
    • Pillow

You can install these libraries using pip:

pip install opencv-python pillow

2. Loading Images

2.1. Using OpenCV

OpenCV is a powerful library for real-time computer vision.

import cv2

# Load an image from a file
# Replace 'example.jpg' with the actual path to your image file
image_cv = cv2.imread('example.jpg')

# Verify if the image was loaded successfully
if image_cv is None:
    print("Error: Image not loaded. Please check the file path.")
else:
    print("Image loaded successfully with OpenCV!")

# OpenCV reads images in BGR (Blue, Green, Red) color format by default.
# The loaded image is returned as a NumPy array.
print(f"Image shape: {image_cv.shape}")
print(f"Image data type: {image_cv.dtype}")

Key Points:

  • cv2.imread(): Reads an image from a specified file path.
  • Color Format: OpenCV uses BGR (Blue, Green, Red) order for color channels, which is different from the more common RGB.
  • Return Type: Images are returned as NumPy arrays, allowing for easy manipulation.

2.2. Using Pillow (PIL)

Pillow is a fork of the Python Imaging Library (PIL) and is excellent for general image manipulation.

from PIL import Image

# Load an image from a file
# Replace 'example.jpg' with the actual path to your image file
try:
    image_pil = Image.open('example.jpg')
    print("Image loaded successfully with Pillow!")

    # Print details about the loaded image
    print("Format:", image_pil.format)
    print("Size:", image_pil.size)
    print("Mode:", image_pil.mode)

except FileNotFoundError:
    print("Error: Image not found. Please check the file path.")
except Exception as e:
    print(f"An error occurred: {e}")

# Pillow opens images in RGB (Red, Green, Blue) mode by default.
# The image is a PIL Image object, not a NumPy array by default.

Key Points:

  • Image.open(): Opens an image file.
  • Color Format: Pillow uses RGB (Red, Green, Blue) order for color channels by default.
  • Return Type: Returns a PIL.Image.Image object, which has its own set of methods for manipulation.

3. Displaying Images

3.1. Using OpenCV

OpenCV allows you to display images in dedicated windows.

import cv2

# Assuming 'image_cv' has been loaded as shown in the previous section
if image_cv is not None:
    # Display the image in a window
    # 'Image Window' is the title of the window
    cv2.imshow('OpenCV Image Display', image_cv)

    # Wait indefinitely until a key is pressed
    # 0 means wait forever. Any other positive integer (e.g., 1) means wait for that many milliseconds.
    print("Press any key to close the OpenCV image window...")
    cv2.waitKey(0)

    # Destroy all OpenCV windows
    cv2.destroyAllWindows()
    print("OpenCV image window closed.")
else:
    print("Cannot display image: Image not loaded.")

Key Points:

  • cv2.imshow(window_name, image): Creates a window with the specified name and displays the image within it.
  • cv2.waitKey(delay): This is a crucial function. It waits for a specified number of milliseconds for a keyboard event. If delay is 0, it waits indefinitely until any key is pressed. This keeps the window visible.
  • cv2.destroyAllWindows(): Closes all windows created by OpenCV.

3.2. Using Pillow (PIL)

Pillow's show() method leverages your system's default image viewer.

from PIL import Image

# Assuming 'image_pil' has been loaded as shown in the previous section
if 'image_pil' in locals() and image_pil is not None:
    # Display the image using the system's default image viewer
    print("Opening image with system's default viewer...")
    image_pil.show()
    print("Image displayed. Please check your default image viewer.")
else:
    print("Cannot display image: Pillow image not loaded.")

Key Points:

  • image.show(): Opens the image using the default image viewer configured on your operating system.
  • Simplicity vs. Flexibility: This method is very simple but offers less control compared to OpenCV's window management. You cannot easily interact with the image within a custom application window.

4. Saving Images

4.1. Using OpenCV

OpenCV can save images in various formats.

import cv2

# Assuming 'image_cv' has been loaded
if image_cv is not None:
    # Save the image to a file
    # The format is inferred from the file extension (e.g., .jpg, .png)
    save_success_cv = cv2.imwrite('opencv_saved_image.jpg', image_cv)

    if save_success_cv:
        print("Image saved successfully using OpenCV as 'opencv_saved_image.jpg'")
    else:
        print("Error: Failed to save image using OpenCV.")
else:
    print("Cannot save image: OpenCV image not loaded.")

Key Points:

  • cv2.imwrite(filename, image): Saves the image to the specified file. The image format is determined by the file extension.

4.2. Using Pillow (PIL)

Pillow supports a wide range of image formats for saving.

from PIL import Image

# Assuming 'image_pil' has been loaded
if 'image_pil' in locals() and image_pil is not None:
    # Save the image in a different format (e.g., PNG)
    # Pillow allows saving in multiple formats like .png, .jpeg, .bmp, etc.
    try:
        image_pil.save('pil_saved_image.png')
        print("Image saved successfully using Pillow as 'pil_saved_image.png'")
    except Exception as e:
        print(f"Error saving image with Pillow: {e}")
else:
    print("Cannot save image: Pillow image not loaded.")

Key Points:

  • image.save(filename): Saves the image to the specified file. Pillow automatically detects the format from the file extension. You can also specify the format explicitly using the format argument (e.g., image_pil.save('output.jpg', format='JPEG')).

5. Example Workflow: Complete Image I/O

This section demonstrates a common workflow involving loading, displaying, and saving using both libraries.

Prerequisites: Make sure you have an example.jpg file in the same directory as your script, or update the paths accordingly.

OpenCV Workflow

import cv2
import sys # To check if the script is running

# --- OpenCV Example ---
print("\n--- Starting OpenCV Workflow ---")
opencv_image_path = 'example.jpg'
cv2_img = cv2.imread(opencv_image_path)

if cv2_img is None:
    print(f"OpenCV Error: Could not load image from '{opencv_image_path}'. Please check the path.")
else:
    print(f"OpenCV: Successfully loaded '{opencv_image_path}'.")

    # Display the image
    cv2.imshow('OpenCV Loaded Image', cv2_img)
    print("OpenCV: Displaying image. Press any key to continue...")
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    # Save the image
    output_filename_cv = 'opencv_output.jpg'
    if cv2.imwrite(output_filename_cv, cv2_img):
        print(f"OpenCV: Successfully saved image as '{output_filename_cv}'.")
    else:
        print(f"OpenCV: Failed to save image as '{output_filename_cv}'.")
print("--- Finished OpenCV Workflow ---\n")

Pillow Workflow

from PIL import Image

# --- Pillow Example ---
print("--- Starting Pillow Workflow ---")
pillow_image_path = 'example.jpg'
try:
    pil_img = Image.open(pillow_image_path)
    print(f"Pillow: Successfully loaded '{pillow_image_path}'.")

    # Display the image (opens in system viewer)
    print("Pillow: Displaying image using system viewer...")
    pil_img.show()
    # Note: Pillow's .show() is asynchronous and returns immediately.
    # The image will appear in your default viewer.

    # Save the image in a different format
    output_filename_pil = 'pil_output.png'
    pil_img.save(output_filename_pil)
    print(f"Pillow: Successfully saved image as '{output_filename_pil}'.")

except FileNotFoundError:
    print(f"Pillow Error: Could not load image from '{pillow_image_path}'. Please check the path.")
except Exception as e:
    print(f"Pillow Error: An unexpected error occurred: {e}")
print("--- Finished Pillow Workflow ---\n")

6. Common Use Cases

Loading, displaying, and saving images are foundational for numerous image processing and computer vision tasks:

  • Preprocessing: Resizing, cropping, or rotating images before feeding them into machine learning models.
  • Data Augmentation: Applying transformations to images to increase the diversity of training data for deep learning models.
  • Visualization: Displaying intermediate results of image processing algorithms (e.g., showing the output of a filter).
  • Storage: Saving the results of image manipulations, model outputs, or captured video frames.
  • User Interfaces: Building applications that allow users to load, view, and save their own images.

7. Conclusion

In this hands-on guide, you've learned the fundamental techniques for loading, displaying, and saving images in Python using two powerful libraries: OpenCV and Pillow. Mastering these basic operations is crucial for anyone venturing into image processing, computer vision, or multimedia applications.

With this knowledge, you are well-prepared to explore more advanced topics such as image filtering, feature detection, object recognition, and real-time video analysis.


SEO Keywords

  • Load images Python OpenCV
  • Display images Python Pillow
  • Save images Python OpenCV
  • Image processing Python tutorial
  • OpenCV vs Pillow image handling
  • Python image I/O examples
  • How to read images in Python
  • Show image in Python window
  • Save image in multiple formats Python
  • Python libraries for image processing

Potential Interview Questions

  • How do you load an image using OpenCV in Python?
    • Answer: Using cv2.imread('path/to/image.jpg').
  • What is the difference between image loading in OpenCV and Pillow?
    • Answer: OpenCV loads images as NumPy arrays in BGR format, while Pillow loads them as PIL.Image.Image objects in RGB format by default.
  • How are color channels represented differently in OpenCV and Pillow?
    • Answer: OpenCV uses BGR (Blue, Green, Red) order, whereas Pillow uses RGB (Red, Green, Blue) order by default.
  • How can you display an image using OpenCV? What function is used?
    • Answer: Using cv2.imshow('Window Title', image), followed by cv2.waitKey(0) to keep the window open, and cv2.destroyAllWindows() to close it.
  • How do you display an image using Pillow, and how does it differ from OpenCV’s method?
    • Answer: Pillow uses image.show(), which opens the image in the system's default viewer. This is simpler but offers less control than OpenCV's custom window management.
  • What does cv2.waitKey() do in OpenCV image display?
    • Answer: It pauses the program execution for a specified number of milliseconds, waiting for a key press event. If the argument is 0, it waits indefinitely.
  • How can you save an image to disk using OpenCV and Pillow?
    • Answer: OpenCV uses cv2.imwrite('filename.ext', image), and Pillow uses image.save('filename.ext').
  • What image formats can Pillow save images in?
    • Answer: Pillow supports a wide variety, including JPEG, PNG, BMP, GIF, TIFF, and more, typically inferred from the file extension.
  • What are some common use cases for loading, displaying, and saving images in Python?
    • Answer: Preprocessing for ML, data augmentation, visualization of processing steps, storing results, and building user-facing image applications.
  • How would you handle an error if the image file path is incorrect when loading an image in OpenCV?
    • Answer: Check if the returned image object is None. If it is, print an error message and stop further processing. if image is None: print("Error: Image not loaded.")