'Compare two images and find all pixel coordinates that differ
I have designed a program that compares two images and gives you the coordinates of the pixels that are different in both images and plots the using pygame. I do not mind having to use another library or to remake my whole code but it should ideally take less that 0.6s to process and it should not reduce file size, all I need it to do is to return the coordinates relative to the image
My code:
import cv2
import pygame
from pygame.locals import *
import time
lib = 'Map1.png'
lib2 = 'Map2.png'
lib3 = ()
coordenatesx = ()
coordenatesy = ()
Read = list(cv2.imread(lib).astype("int"))
Read2 = list(cv2.imread(lib2).astype("int"))
counter = 0
pygame.init()
flags = DOUBLEBUF
screen = pygame.display.set_mode((500,500), flags, 4)
start = time.process_time()#To tell me how long it takes
for y in range(len(Read)):#y coords
for x in range(len(Read[y])):#x coords
all = list(Read[y][x])[0]
all2 = list(Read2[y][x])[0]
difference = (all)-(all2)
if difference > 10 or difference < -10: #To see if the pixel's difference is in the boundary if not it is different and it gets plotted
counter+=1
pygame.draw.rect(screen, (255, 0, 0), pygame.Rect(x, y, 1, 1))
pygame.display.update()
print(time. process_time() - start)
if counter >= (y * x) * 0.75:
print('They are similar images')
print('They are different by only :', str((counter / (y * x)) * 100), '%')
else:
print('They are different')
print('They are different by:', str((counter / (y * x)) * 100), '%')
pygame.display.update()
image1 | image2 |
---|---|
Solution 1:[1]
You do not need to use for
loop to do the same.
Numpy
makes things simple:
- it's easy to understand
- speed up operations
Reading both your images in grayscale:
img1 = cv2.imread(r'C:\Users\524316\Desktop\Stack\m1.png', 0)
1mg2 = cv2.imread(r'C:\Users\524316\Desktop\Stack\m2.png', 0)
Subtracting them. cv2.subtract()
takes care of normalization such that it doesn't return negative values. Coordinates having no change remain black (pixel intensity = 0)
sub = cv2.subtract(img1, img2)
Using numpy
find the coordinates where changes are more than 0
coords = np.argwhere(sub > 0)
# return first 10 elements of the array coords
coords[:10]
array([[ 0, 23],
[ 0, 24],
[ 0, 25],
[ 0, 26],
[ 0, 27],
[ 0, 28],
[ 0, 29],
[ 0, 30],
[ 0, 31],
[ 0, 32]], dtype=int64)
coords
returns an array, which can be converted to a list:
coords_list = coords.tolist()
# return first 10 elements of the list:
>>> coords_list[:10]
[[0, 23], [0, 24], [0, 25], [0, 26], [0, 27], [0, 28], [0, 29], [0, 30], [0, 31], [0, 32]]
Update:
Based on the comment made by fmw42, if you are only looking for coordinates where difference between pixel intensities is less than or greater than a certain value (say 10); you could do the following:
sub = cv2.absDiff(img1, img2)
np.argwhere(sub > 10)
Solution 2:[2]
If you happen to also want a quantitative similarity score between the two images, here's a method using the skimage.metrics.structural_similarity
function from scikit-image
which returns a score
and a diff
image. Since you're mainly interested in all the pixel coordinates that are different, the diff
image contains the actual image differences where we can search for all (x y)
pixel coordinates.
Image Similarity: 34.3664%
Coordinates in Numpy form (you can convert to a list)
[[ 0 20]
[ 0 21]
[ 0 22]
...
[572 521]
[572 522]
[572 523]]
Code
from skimage.metrics import structural_similarity
import numpy as np
import cv2
# Load images as grayscale
image1 = cv2.imread('1.png', 0)
image2 = cv2.imread('2.png', 0)
# Compute SSIM between the two images
# diff contains the actual image differences between the two images
(score, diff) = structural_similarity(image1, image2, full=True)
diff = 255 - (diff * 255).astype("uint8")
print("Image Similarity: {:.4f}%".format(score * 100))
# Search for all pixels that are different
# Type is <class 'numpy.ndarray'>, you can optionally convert to a list
coords = np.argwhere(diff > 0)
# coords = coords.tolist()
print(coords)
cv2.imshow('diff', diff)
cv2.waitKey()
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | |
Solution 2 | nathancy |