Overview
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.
Python packages
from skimage.measure import compare_ssim
import argparse
import imutils
import cv2
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
Read and resize images
# load the two input images
= cv2.imread("credit-card-original.PNG")
image_orig = cv2.imread("credit-card-modified.PNG")
image_mod
# resize for faster processing
= cv2.resize(image_orig, (300, 200))
resized_orig = cv2.resize(image_mod, (300, 200))
resized_mod
plt.imshow(resized_orig) plt.imshow(resized_mod)
Convert images to grayscale
= cv2.cvtColor(resized_orig, cv2.COLOR_BGR2GRAY)
gray_orig = cv2.cvtColor(resized_mod, cv2.COLOR_BGR2GRAY) gray_mod
Compute Structural Similarity Index between images and obtain difference image
= compare_ssim(gray_orig, gray_mod, full=True)
(score, diff) = (diff * 255).astype("uint8")
diff print("Structural Similarity Index: {}".format(score))
## Structural Similarity Index: 0.9537481523548417
Obtain image contours
# threshold the difference image, followed by finding contours to
# obtain the regions of the two input images that differ
= cv2.threshold(diff, 0, 25, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
thresh
= cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts) cnts
Plot image differences
# 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
= cv2.boundingRect(c)
(x, y, w, h) + w, y + h), (0, 0, 255), 2)
cv2.rectangle(resized_orig, (x, y), (x + w, y + h), (0, 0, 255), 2)
cv2.rectangle(resized_mod, (x, y), (x
# show the output images
"Original", resized_orig)
plt.imshow("Modified", resized_mod)
plt.imshow("Diff", diff)
cv2.imshow("Thresh", thresh)
cv2.imshow(0) cv2.waitKey(