Unlock Image Comparison Mastery: Step-by-Step Guide Using the Power of NumPy and Pillow Python Libraries


In image processing, there are endless possibilities for enhancing and comparing images. Whether you’re a photographer, a designer, or just an enthusiast, the ability to manipulate and compare images is a valuable skill. In this blog, we’ll explore a Python script that takes two images, changes their colours to red and blue, autodetects and removes their backgrounds, and generates three new images for comparison. This powerful script can be a valuable addition to your image processing toolkit.

Understanding the Tools: NumPy and Pillow



NumPy stands as a cornerstone in the realm of scientific computing in Python, offering indispensable support for the manipulation of large, multi-dimensional arrays and matrices. Within the scope of our image processing script, NumPy assumes a pivotal role in efficiently handling image data. Here’s a detailed breakdown of key aspects where NumPy contributes significantly:

  1. Array Representation:
    NumPy enables the representation of images as arrays. This capability proves instrumental in fostering fast and resource-efficient processing. The script leverages this feature to seamlessly convert the intricate details of images into structured arrays, setting the stage for subsequent operations.
  2. Boolean Indexing:
    The script harnesses NumPy’s powerful boolean indexing functionality to craft masks that delineate non-background regions within the image. This strategic use of boolean indexing facilitates the selective application of colour changes to specific areas, enhancing the precision and flexibility of image manipulation.
  3. Array Operations:
    NumPy boasts an extensive suite of array operations that our script taps into for the nuanced manipulation of pixel values. These operations provide a rich toolkit for executing diverse transformations, allowing us to attain the desired visual effects with finesse. From basic arithmetic operations to advanced mathematical functions, NumPy’s array operations contribute to the versatility of our image-processing endeavors.

In essence, NumPy serves as the linchpin in our script, seamlessly bridging the divide between raw image data and array representations. This integration not only streamlines the intricacies of image processing but also enhances the overall intuitiveness and efficiency of the script. By leveraging NumPy’s array manipulation capabilities, our script empowers users to navigate effortlessly through the intricacies of image data, unlocking a realm of possibilities for sophisticated and effective image processing.


Pillow Python

The utilization of Pillow, a successor to the Python Imaging Library (PIL), significantly amplifies the image processing capabilities within our script. Here’s a detailed exploration of key features and functionalities harnessed from Pillow:

  1. Image Object:
    Pillow introduces the pivotal Image class, serving as the linchpin for our image-processing operations. This class facilitates a myriad of tasks, including the conversion of colour modes, pasting images, and saving the final results. By encapsulating these functionalities within the Image object, Pillow streamlines the manipulation of images, providing a coherent and versatile framework for seamless integration into our script.
  2. File Format Support:
    Pillow’s expansive repertoire extends to opening, manipulating, and saving a diverse array of image file formats. This comprehensive format support ensures compatibility with various sources, making the script adaptable to a wide range of image inputs. Whether dealing with common formats or specialized ones, Pillow’s versatility ensures robust performance in handling different image file structures.
  3. Image Enhancement:
    A notable facet of our script is its integration with Pillow’s ImageEnhance module. This module empowers the script to enhance the contrast and sharpness of processed images, introducing a layer of sophistication to the final visual output. By tapping into Pillow’s image enhancement capabilities, our script provides users with the tools to fine-tune and optimize the aesthetic qualities of their images.

Understanding and harnessing these features from Pillow is paramount for anyone venturing into the realm of image processing in Python. The dynamic capabilities of Pillow, coupled with its user-friendly interface, make it an indispensable asset in our script. By leveraging the Image class, embracing diverse file format support, and incorporating image enhancement modules, Pillow elevates the script’s functionality, ensuring a comprehensive and effective approach to image processing tasks.

Step-by-Step Code Walkthrough

Now, let’s delve into the code’s functionality in more detail.

Before running the code, ensure you have the required Python libraries installed:

pip install pillow numpy from PIL import Image import numpy as np import uuid from collections import Counter def detect_background_color(image_path): with Image.open(image_path) as image: # Convert the image to RGBA if it's not image = image.convert("RGBA") # Convert image to numpy array datas = np.array(image) # Get the border pixels (1 pixel wide border) top_row = datas[0, :, :3] bottom_row = datas[-1, :, :3] left_column = datas[:, 0, :3] right_column = datas[:, -1, :3] # Combine the border pixels to a single array border_pixels = np.concatenate((top_row, bottom_row, left_column, right_column)) # Use Counter to find the most common pixel value in the border most_common = Counter(map(tuple, border_pixels)).most_common(1) return most_common[0][0] # Return the most common color as a tuple def process_image(image_path, new_color, opacity_factor=0.3): # Open the image and convert it to RGBA image = Image.open(image_path).convert("RGBA") # Detect background color background_color = detect_background_color(image_path) # Convert the image to a NumPy array for fast processing datas = np.array(image) # Create a mask where the background is not the background color not_background_mask = ~np.all(datas[:, :, :3] == background_color, axis=-1) # Apply the new color and opacity to the non-background parts of the image datas[not_background_mask, :3] = new_color datas[not_background_mask, 3] = int(255 * opacity_factor) # Set the background part of the alpha channel to 0 to make it transparent datas[~not_background_mask, 3] = 0 # Convert the NumPy array back to an Image object new_image = Image.fromarray(datas) # Enhance sharpness here if necessary # new_image = new_image.filter(ImageFilter.SHARPEN) return new_image # Define paths for the images image1_path = 'Test-Doc1.png' image2_path = 'Test-Doc2.png' # Generate unique filenames output_image_red_path = f'image_red_{uuid.uuid4()}.png' output_image_blue_path = f'image_blue_{uuid.uuid4()}.png' output_image_combined_path = f'image_combined_{uuid.uuid4()}.png' # Define perfect red and blue colors perfect_red = (234, 51, 36) perfect_blue = (0, 0, 245) # Process the images image_red = process_image(image1_path, perfect_red) image_blue = process_image(image2_path, perfect_blue) # Save the processed images image_red.save(output_image_red_path, format='PNG') image_blue.save(output_image_blue_path, format='PNG') # Create a new combined image with a white opaque background image_combined = Image.new("RGBA", image_red.size, (255, 255, 255, 255)) # Paste the red image onto the combined image image_combined.paste(image_red, (0, 0), image_red.split()[3]) # Paste the blue image onto the combined image, allowing for alpha compositing image_combined.paste(image_blue, (0, 0), image_blue.split()[3]) # Convert the combined image to remove the alpha channel image_combined_without_alpha = image_combined.convert("RGB") # Save the final combined image image_combined_without_alpha.save(output_image_combined_path) # Output the paths to the saved images print(f"Red image saved as {output_image_red_path}") print(f"Blue image saved as {output_image_blue_path}") print(f"Combined image saved as {output_image_combined_path}")

The script above automatically detects and removes the background colour of the images before processing.

Enhancing Image Clarity

If you wish to enhance the clarity of the processed image further, you can use the following code:

from PIL import Image, ImageEnhance, ImageFilter # Load the processed image processed_path = 'Path of the image generated by the above code' # Function to enhance the image clarity def enhance_clarity(image_path): # Open the image image = Image.open(image_path) # Enhance the contrast contrast_enhancer = ImageEnhance.Contrast(image) enhanced_image = contrast_enhancer.enhance(2) # Increase contrast # Enhance the sharpness sharpness_enhancer = ImageEnhance.Sharpness(enhanced_image) sharpened_image = sharpness_enhancer.enhance(2) # Increase sharpness # Save the enhanced image enhanced_image_path = image_path.replace('.png', '_enhanced.png') sharpened_image.save(enhanced_image_path) return enhanced_image_path # Enhance the processed image enhanced_processed_path = enhance_clarity(processed_path) # Output the path to the saved enhanced image print(f"Enhanced processed image saved as {enhanced_processed_path}")

Now, you can use the enhance_clarity function to enhance the contrast and sharpness of the processed image.

Real-World Use Cases

  1. Architectural Design: Imagine you’re an architect working on a project with multiple design iterations. You can use this script to compare different versions of architectural plans. For instance, you can compare two-floor plans to identify design changes, additions, or omissions.
  2. Product Design: If you’re a product designer, you can use the script to compare two product design versions. By creating red and blue product images, you can easily spot differences and improvements between iterations.
  3. Forensic Analysis: In the field of forensics, this script can be used to analyze crime scene photos. By creating red and blue versions of the images, investigators can highlight important details or changes in the scene.
  4. Art Restoration: Art restorers can use the script to compare the condition of a painting or artwork before and after restoration. This allows them to identify repaired or altered areas during the restoration process.
  5. Medical Imaging: The script can be applied to compare medical images such as X-rays or MRIs in the medical field. By creating red and blue versions of these images, doctors can better identify changes or anomalies in a patient’s health.
Python Pillow NumPy


In summary, our Python script offers a robust image processing and comparison solution, featuring automatic background detection. Versatile across architecture, product design, forensics, art restoration, and the medical field, it’s a valuable asset. Notably, a companion script enhances image clarity, seamlessly integrating for refined visual quality. Explore the combined potential of both tools—utilize automatic background detection for precision and the clarity enhancement tool for a heightened visual impact. Elevate your image workflows by harnessing the dual power of these tools for optimal results!

For more information on Image processing please check this related article Top 4 Powerful AI-Powered Face, Shape, and Text Recognition Tools for Healthcare, E-commerce and Real Estate Sectors