Detecting Image Differences Using Python and OpenCV

Danny Morris

2019/07/07

This post was inspired by this post written by Adrian Rosebrock of PyImageSearch.

This document shows how to detect differences between two images using Python and OpenCV.

# import the necessary packages
from skimage.measure import compare_ssim
import argparse
import imutils
import cv2

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
# load the two input images
image_orig = cv2.imread("credit-card-original.PNG")

image_mod = cv2.imread("credit-card-modified.PNG")
resized_orig = cv2.resize(image_orig, (300, 200))    
resized_mod = cv2.resize(image_mod, (300, 200))
plt.imshow(resized_orig)

plt.imshow(resized_mod)

# convert the images to grayscale
gray_orig = cv2.cvtColor(resized_orig, cv2.COLOR_BGR2GRAY)
gray_mod = cv2.cvtColor(resized_mod, cv2.COLOR_BGR2GRAY)
# compute the Structural Similarity Index (SSIM) between the two
# images, ensuring that the difference image is returned
(score, diff) = compare_ssim(gray_orig, gray_mod, full=True)

diff = (diff * 255).astype("uint8")

print("Structural Similarity Index: {}".format(score))
## Structural Similarity Index: 0.9537481523548417
# threshold the difference image, followed by finding contours to
# obtain the regions of the two input images that differ
thresh = cv2.threshold(diff, 0, 25,
    cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]

cnts = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL,
    cv2.CHAIN_APPROX_SIMPLE)

cnts = imutils.grab_contours(cnts)
# loop over the contours
for c in cnts:
# compute the bounding box of the contour and then draw the
# bounding box on both input images to represent where the two
# images differ
    (x, y, w, h) = cv2.boundingRect(c)
    cv2.rectangle(resized_orig, (x, y), (x + w, y + h), (0, 0, 255), 2)
    cv2.rectangle(resized_mod, (x, y), (x + w, y + h), (0, 0, 255), 2)
 
# show the output images
plt.imshow("Original", resized_orig)
plt.imshow("Modified", resized_mod)
cv2.imshow("Diff", diff)
cv2.imshow("Thresh", thresh)
cv2.waitKey(0)