0

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??

Pramod Mali
  • 1,588
  • 1
  • 17
  • 29
UAA
  • 19
  • 3
  • Different colors can have similar or the same grayscale values. Perhaps threshold each image on its color and then get the absdiff() and use that for the mask. – fmw42 Aug 12 '20 at 05:58
  • Yes, but is there any way where for same images the mask window should not give any color(like blue in result no1) – UAA Aug 12 '20 at 06:18
  • I do not understand your question, sorry. – fmw42 Aug 12 '20 at 16:40
  • Actually this code give perfect results is there are some change in result, but if both the images are same then why the mask (see result of 1 and 2) shows blue color?? Is there any way?? – UAA Aug 13 '20 at 04:48

0 Answers0