I have two images and would like to make it obvious where the differences are. I want to add color to the two images such that a user can clearly spot all the differences within a second or two.
For example, here are two images with a few differences: green plate with two holes
red plate with two holes having same dimension as 1st one
yellow plate with two holes minimizing its width
My current approach to make the differences obvious, is to create a mask (difference between the two images), color it red, and then add it to the images. The goal is to clearly mark all differences with a strong blue color. Here is my current code:
from skimage.measure import compare_ssim
import cv2
import numpy as np
image1 = cv2.imread('Paint1.png')
image2 = cv2.imread('Paint3.png')
resized1 = cv2.resize(image1, (300, 200))
resized2 = cv2.resize(image2, (300, 200))
# Convert images to grayscale
gray1 = cv2.cvtColor(resized1, cv2.COLOR_BGR2GRAY)
gray2 = cv2.cvtColor(resized2, cv2.COLOR_BGR2GRAY)
# Compute SSIM between two images
(score, diff) = compare_ssim(gray2, gray1, full=True)
print("Image similarity", score*100, "%")
# The diff image contains the actual image differences between the two images
# and is represented as a floating point data type in the range [0,1]
# so we must convert the array to 8-bit unsigned integers in the range
# [0,255] before we can use it with OpenCV
diff = (diff * 255).astype("uint8")
if diff.all() == True:
print("Same images")
else:
print("Not same")
# Threshold the difference image, followed by finding contours to
# obtain the regions of the two input images that differ
thresh = cv2.threshold(diff, 0, 255, cv2.THRESH_BINARY_INV | cv2.THRESH_OTSU)[1]
contours = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
mask = np.zeros(resized1.shape, dtype='uint8')
filled_after = resized2.copy()
for c in contours:
area = cv2.contourArea(c)
if area > 40:
x,y,w,h = cv2.boundingRect(c)
cv2.rectangle(resized1, (x, y), (x + w, y + h), (0,0,255), 2)
cv2.rectangle(resized2, (x, y), (x + w, y + h), (0,0,255), 2)
cv2.drawContours(mask, [c], 0, (0,0,255), -1)
cv2.drawContours(filled_after, [c], 0, (0,0,255), -1)
cv2.imshow('Output', np.hstack([resized1, resized2]))
cv2.imshow('diff',diff)
cv2.imshow('mask',mask)
cv2.imshow('filled after',filled_after)
cv2.waitKey(0)
When compare 1st and 2nd image:- result of 1st and 2nd images
When compare 1st and 3rd image:-result of 1st and 3rd images
Problem with the current code: The computed mask shows differences of same images too(see result of 1st and 2nd, though same images mask shown the blue color).(This code properly work with two different images but not for same images)
Expected Output: 3 images: the two input images but with the differences highlighted (clearly highlighted in a configurable color), and a third image containing only the differences (the mask but for same images not shown any difference)
How can I achieve this??