šŸ¶
Machine Vision

OpenCV Image Difference Detection and Visualization

By Jan on 02/18/2025

Learn how to use OpenCV Python to easily detect and visualize subtle differences between two images for various applications.

OpenCV Image Difference Detection and Visualization

Table of Contents

Introduction

This article provides a step-by-step guide on how to detect and highlight differences between two images using OpenCV in Python.

Step-by-Step Guide

  1. Import necessary libraries:
import cv2
import numpy as np
  1. Load the two images you want to compare:
image1 = cv2.imread("image1.jpg")
image2 = cv2.imread("image2.jpg")
  1. Convert the images to grayscale:
gray1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)
  1. Compute the absolute difference between the grayscale images:
diff = cv2.absdiff(gray1, gray2)
  1. Apply thresholding to the difference image to create a binary mask:
thresh = cv2.threshold(diff, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
  1. Find contours in the thresholded image:
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
  1. Loop over the contours and draw bounding boxes around the differences:
for c in cnts:
 x, y, w, h = cv2.boundingRect(c)
 cv2.rectangle(image1, (x, y), (x + w, y + h), (0, 0, 255), 2)
 cv2.rectangle(image2, (x, y), (x + w, y + h), (0, 0, 255), 2)
  1. Display the images with highlighted differences:
cv2.imshow("Image 1", image1)
cv2.imshow("Image 2", image2)
cv2.waitKey(0)

This code will highlight the differences between the two input images by drawing red rectangles around the areas where the pixel values differ significantly. You can adjust the threshold value in step 5 to control the sensitivity of the difference detection.

Code Example

This Python code compares two images, "image1.jpg" and "image2.jpg", to identify and highlight the differences between them. It converts the images to grayscale, calculates the absolute difference, applies thresholding to create a binary mask of the differences, and then finds contours in the mask. Finally, it draws bounding boxes around the detected differences on both original images and displays them.

import cv2
import numpy as np

# Load the two images
image1 = cv2.imread("image1.jpg")
image2 = cv2.imread("image2.jpg")

# Convert the images to grayscale
gray1 = cv2.cvtColor(image1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(image2, cv2.COLOR_BGR2GRAY)

# Compute the absolute difference between the grayscale images
diff = cv2.absdiff(gray1, gray2)

# Apply thresholding to the difference image
thresh = cv2.threshold(diff, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]

# Find contours in the thresholded image
cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

# Loop over the contours and draw bounding boxes around the differences
for c in cnts:
    x, y, w, h = cv2.boundingRect(c)
    cv2.rectangle(image1, (x, y), (x + w, y + h), (0, 0, 255), 2)
    cv2.rectangle(image2, (x, y), (x + w, y + h), (0, 0, 255), 2)

# Display the images with highlighted differences
cv2.imshow("Image 1", image1)
cv2.imshow("Image 2", image2)
cv2.waitKey(0)

Explanation:

  1. Import necessary libraries: This line imports the OpenCV (cv2) and NumPy libraries, which are required for image processing and array manipulation.
  2. Load the two images: This section loads the two images that you want to compare using cv2.imread(). Replace "image1.jpg" and "image2.jpg" with the actual file names of your images.
  3. Convert the images to grayscale: This step converts the color images to grayscale using cv2.cvtColor(). This is done because color information is not necessary for difference detection and grayscale images are simpler to process.
  4. Compute the absolute difference: cv2.absdiff() calculates the absolute difference between each corresponding pixel in the two grayscale images.
  5. Apply thresholding: This step applies a threshold to the difference image using cv2.threshold(). This creates a binary mask where pixels with a difference greater than the threshold are set to white (255) and others to black (0). Otsu's thresholding method is used to automatically determine the optimal threshold value.
  6. Find contours: cv2.findContours() finds the contours (outlines) of the white regions in the thresholded image. These contours represent the areas where the two images differ.
  7. Draw bounding boxes: This loop iterates through each detected contour and draws a red rectangle around it on both input images using cv2.rectangle(). This highlights the differences visually.
  8. Display the images: Finally, the code displays the two modified images with the highlighted differences using cv2.imshow(). cv2.waitKey(0) waits for a key press to close the image windows.

This code provides a basic framework for image difference detection. You can further customize it by adjusting the threshold value, changing the color of the bounding boxes, or adding more sophisticated image processing techniques.

Additional Notes

Code Robustness:

  • Image Size Check: Before processing, consider adding a check to ensure both images have the same dimensions. If not, you might need to resize one to match the other to avoid errors.
  • Contour Area Filtering: You can filter out very small contours which might represent noise or insignificant differences. This can be done by calculating the area of each contour using cv2.contourArea(c) and discarding those below a certain threshold.

Performance:

  • Grayscale Conversion: While converting to grayscale is mentioned, you can potentially skip this step if you use a difference metric that works directly on color images (e.g., color histograms).
  • Computational Cost: Finding contours can be computationally expensive. If you are working with high-resolution images or need real-time performance, consider optimizing this part or exploring alternative difference detection methods.

Alternative Approaches:

  • Structural Similarity Index (SSIM): SSIM is a perceptual metric that compares images based on structural information. It can be more robust to changes in illumination and contrast compared to simple pixel-wise differences.
  • Feature-based Comparison: Instead of comparing pixels directly, you can extract features from the images (e.g., using SIFT or ORB) and compare those. This can be more robust to changes in viewpoint and scale.
  • Background Subtraction: If you are comparing an image to a static background, you can use background subtraction techniques to isolate the foreground objects and detect changes more effectively.

Applications:

  • Quality Control: This code can be used to detect defects in manufactured products by comparing them to a reference image.
  • Surveillance: By comparing consecutive frames from a video stream, you can detect motion and track objects.
  • Medical Imaging: Image differencing can highlight changes in medical scans over time, aiding in diagnosis and treatment monitoring.

Further Exploration:

  • OpenCV Documentation: Refer to the official OpenCV documentation for detailed information on the functions used in this code.
  • Image Processing Tutorials: Explore online tutorials and resources on image processing with OpenCV to learn about more advanced techniques.

Summary

This Python code snippet demonstrates how to detect and highlight differences between two images using OpenCV.

Here's a breakdown of the process:

  1. Load Images: Load the two images you want to compare.
  2. Convert to Grayscale: Convert both images to grayscale to simplify the comparison.
  3. Calculate Difference: Compute the absolute difference between the grayscale images. This highlights areas where pixel values differ.
  4. Thresholding: Apply thresholding to the difference image to create a binary mask. This separates the significant differences from minor variations.
  5. Find Contours: Find contours (outlines of connected regions) in the thresholded image. These contours represent the areas of difference.
  6. Draw Bounding Boxes: Draw bounding boxes around the detected contours on both original images. This visually highlights the differences.
  7. Display Results: Display the original images with the differences marked by bounding boxes.

Key Points:

  • Threshold Adjustment: The threshold value in the code controls the sensitivity of difference detection. A higher threshold will highlight only major differences, while a lower threshold will detect more subtle variations.
  • Applications: This technique can be used for various applications, such as:
    • Image comparison: Identifying changes between two versions of an image.
    • Object detection: Detecting new objects that have appeared in a scene.
    • Defect detection: Identifying defects in manufactured products by comparing them to a reference image.

Conclusion

This code effectively highlights differences between two images, making it useful for applications like quality control, surveillance, and medical imaging. Understanding thresholding and contour detection in OpenCV is key to leveraging this technique. Remember to consider image size, filter out insignificant contours, and explore alternative approaches like SSIM or feature-based comparison for potentially more robust results. For further exploration, consult the OpenCV documentation and image processing tutorials.

References

Were You Able to Follow the Instructions?

šŸ˜Love it!
šŸ˜ŠYes
šŸ˜Meh-gical
šŸ˜žNo
šŸ¤®Clickbait