Cropping Images in Python With Pillow and OpenCV

crop images python

What is Image Cropping?

Image cropping is a way of photo editing that involves removing a portion of an image to emphasize a subject, change the aspect ratio, or improve the framing. You can then reframe a subject or direct the viewer’s attention to a certain part of the photo. Automated image cropping performs the same task on a large number of images.

Here are the key terms that relate to image cropping:

  • Crop rectangle — The region, defined by four coordinates, to which to crop the image. The cropping operation removes all the details outside the crop rectangle, delivering a modified image of the crop rectangle’s size.
  • Aspect ratio — The ratio of the image’s width to its height. This ratio is denoted by two numbers separated by a colon, for example, 4:3 or four-to-three.
  • Pixels — The grid of vertical and horizontal pixels of which digital photos are composed. Cropping cuts out certain sections of the image, reducing the number of pixels and shrinking the image size.

This is part of a series of articles about Auto Image Crop.

This article covers the following topics:

How to Crop Images in Python With Pillow

A fork of the Python Image Library (PIL), the Pillow library offers an easy way through the crop() function for cropping images in Python. Here’s syntax:

Image.crop(box=None)

The box parameter accepts a tuple with four values of the four coordinates for the crop rectangle: left, upper, right, and lower. The crop rectangle is drawn within the image, which depicts the part of the image you want to crop. Image.crop returns an image object.

To crop an image with Pillow:

  1. Import Pillow’s Image class:
    from PIL import Image
  2. Load an image from the file system and, with the Image.open() class, convert the image into an instance of the Image class. Adding Image.show() displays the image in an external viewer.
    img = Image.open('./myimage.png')
    img.show()
  3. Crop the image. Assuming that the  image myimage.png is 1,000×1,000 pixels, crop it to a square of 500×500 pixels at the center of the image:
    box = (250, 250, 750, 750)
    img2 = img.crop(box)
  4. Save the cropped image, a Python object called img2, to the file system:
    img2.save('myimage_cropped.jpg')
    img2.show()

Note the following issues vis-à-vis cropping images with Pillow:

  • Content-aware cropping. Most cropping operations depend on the context. For example, you don’t want to remove important parts of the image, but that’s difficult to ensure programmatically because the crop() function is not sensitive to the image content.
  • Cropping and resizing. Oftentimes, you must resize and crop an image at the same time. Even though you can resize images in Python with a similar technique, combining cropping and resizing can get tricky, let alone that it’s challenging to generate the exact image you need for your design.
  • Image management. A large number of crop operations might lead to multiple versions for each image, all to be stored on the server. Besides procuring extra storage space, you must also put in place a clear, consistent convention to facilitate locating the right version of the image. A much more efficient approach is to simply dynamically generate the required version of the image without saving all its versions to the file system.

Automatically resize and crop image with AI

Crop an Image in Python With OpenCV

Python OpenCV is a library with advanced computer-vision capabilities, in particular a set of functions for handling processing and transforming images. To import the OpenCV library into your program, type:

import cv2

Here’s the syntax for image cropping:

image[start_x:end_x, start_y:end_y]

Interestingly, this syntax slices the image[] in the form of an array by passing the start and end index x and y coordinates for each segment. The portion of the image between the start and end coordinates is returned as a truncated array object.

For example:

import cv2
image = cv2.imread(r"C:\file\path\imagename.png")

y=0
x=0
h=300
w=510
crop_image = image[x:w, y:h]
cv2.imshow("Cropped", crop_image)
cv2.waitKey(0)

The statement cv2.imread(r"image path") opens the image in read-only mode. The cv2.imshow() function near the bottom displays the cropped image.

Resizing and Cropping Python Images Through Automation With Cloudinary

A cloud-based service for managing images and videos, Cloudinary offers a generous free-forever subscription plan. While on that platform, you can upload your images, apply built-in effects, filters, and modifications.

You can also resize images through automation, focusing on the most important elements with AI, or adapt them to your website design by, for example, specifying the width, height, and aspect ratio as qualifiers for the new image instances. Cloudinary then automatically performs the resizing and cropping tasks to meet the criteria. No manual efforts are required.

Take this 1,200×1,200-pixel image:

Resizing it to 200×200 pixels with crop, scale, fill, and pad results in the following images:

Original Image

Focus on the model in a portrait crop

Detect the face for a thumbnail crop

Automatically determine what to keep in a banner crop

To automate image resizing and cropping on Cloudinary:

  1. Sign up for a free Cloudinary account.
  2. Install the Python SDK.
  3. Set the transformation criteria for the above examples:
    # Focus on the model in a portrait crop.
    
    CloudinaryImage("docs/model.jpg").image(gravity="person", height=600, width=450, crop="fill")
    
    # Detect the face for a thumbnail crop.
    
    CloudinaryImage("docs/model.jpg").image(gravity="face", height=250, width=250, crop="thumb")
    
    # Crop to a banner, automatically focusing on a region of interest.
    
    CloudinaryImage("docs/model.jpg").image(gravity="auto", height=150, width=600, crop="fill")
    
QUICK TIPS
Colby Fayock
Cloudinary Logo Colby Fayock

In my experience, here are tips that can help you better implement image cropping using Python with Pillow and OpenCV:

  1. Use Pillow for basic cropping and OpenCV for advanced operations
    Pillow is great for straightforward cropping tasks and basic manipulation. However, OpenCV offers more control over complex image processing and manipulation, like contour detection, edge detection, and face detection. Choose the library that matches your project’s complexity and requirements.
  2. Leverage Pillow’s ImageOps.fit() for content-aware cropping
    The standard crop() method in Pillow is rigid and requires you to specify coordinates manually. Instead, use ImageOps.fit() to automatically crop the image while maintaining the focus on the main content area. This method is especially useful for thumbnails and profile pictures as it prioritizes the central region of the image.
  3. Apply OpenCV’s cv2.selectROI() for interactive cropping
    When working with OpenCV, use cv2.selectROI() to manually select regions of interest. This allows developers to define the cropping area interactively, which is ideal for scenarios where human input is needed to choose the right crop for complex images, such as group photos or landscapes.
  4. Combine OpenCV with Deep Learning models for smart cropping
    Integrate OpenCV with pre-trained models like YOLO or TensorFlow’s Object Detection API to perform intelligent cropping around specific objects (e.g., cars, faces, or text). By detecting the bounding boxes of these objects, you can ensure that your crops always focus on relevant content, avoiding unwanted cuts.
  5. Use OpenCV’s cv2.boundingRect() for face or object detection-based cropping
    If your cropping is based on specific features like faces or objects, apply cv2.boundingRect() along with OpenCV’s contour detection or face-detection modules. This approach is useful for scenarios like profile picture generation or document scans, ensuring that the key elements are always in view.
  6. Use Pillow’s ImageChops to trim whitespace from image edges
    To automatically remove unwanted borders or whitespace around images, use ImageChops.difference() to detect and crop out empty spaces. This technique is particularly helpful when you receive raw images with extraneous backgrounds or borders that need cleanup before further processing.
  7. Handle color channels and image formats correctly
    Be mindful of image formats when using OpenCV and Pillow together. OpenCV uses BGR color ordering by default, while Pillow uses RGB. Always convert between cv2.cvtColor(image, cv2.COLOR_BGR2RGB) and cv2.COLOR_RGB2BGR when switching between these libraries to avoid color mismatches.
  8. Optimize OpenCV’s resize() with interpolation for quality results
    When resizing images with OpenCV, use interpolation methods like cv2.INTER_AREA for downsampling (shrinking) and cv2.INTER_CUBIC or cv2.INTER_LINEAR for upsampling (enlarging). These methods produce smoother results and help avoid pixelation or blurring when resizing images.
  9. Create a central cropping function to unify Pillow and OpenCV operations
    When your project uses both Pillow and OpenCV, create a central function that abstracts the cropping logic based on whether you’re using Pillow’s crop() or OpenCV’s slicing methods. This function can intelligently handle the conversions, reducing the risk of errors and making your codebase easier to maintain.
  10. Integrate Cloudinary’s AI-based cropping for content-aware automation
    When working at scale or needing smart automation, use Cloudinary’s AI-driven g_auto cropping feature to handle content-aware cropping. This feature leverages AI to detect focal points and optimally crop the image without manual intervention. It’s ideal for batch processing product images or creating thumbnails that retain the most visually appealing content.

By applying these advanced techniques, you can optimize image cropping workflows and ensure high-quality results in Python, regardless of whether you’re working with single images or need to process thousands automatically.

Last updated: Oct 3, 2024