Spot the difference

Usual modules

In [1]:
import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import numpy as np
from matplotlib.patches import Rectangle

Input image

In [12]:
image = mpimg.imread('christmas.png')

fig, ax = plt.subplots(1,2, figsize=(20,10))
ax[0].imshow(image)
ax[1].imshow(image[ 10:-20, 20:-20, :]) # cropped
plt.show()

Crop the 2nd image in 2 parts, overlap them and find the best match

In [9]:
cropped = np.delete(image[ 10:-20, 20:-20, :],[3],axis=2)
cropped.shape
Out[9]:
(1570, 1200, 3)
In [53]:
crop1 = cropped[20:750, :, :]
crop2 = cropped[-crop1.shape[0]:, :, :] # <-- same size of crop1!

fig  = plt.figure(figsize=(20,10))
grid = fig.add_gridspec(2,4)
ax1  = fig.add_subplot(grid[0, :2])
ax2  = fig.add_subplot(grid[0, 2:])
ax3  = fig.add_subplot(grid[1, 1:3])
ax1.imshow(crop1)
ax2.imshow(crop2) # cropped
ax3.imshow(np.abs(crop1-crop2))
plt.show()

Find a better match for crop2

In [28]:
crop1.shape
Out[28]:
(730, 1200, 3)
In [66]:
difflist=[]
x = range(1,20)
for ivt in x:
        diff = np.abs(crop1 - cropped[-crop1.shape[0]-ivt : -ivt, : , :]).sum()
        difflist.append(diff)
        
plt.plot(x,difflist, 'o')
plt.plot(x[np.array(difflist).argmin()], np.array(difflist).min(),'*r', markersize=15)
plt.show()
In [68]:
crop1 = cropped[20:750, :, :]
crop2 = cropped[-crop1.shape[0]-9:-9,:, :] # <-- same size of crop1!

fig  = plt.figure(figsize=(20,10))
grid = fig.add_gridspec(2,4)
ax1  = fig.add_subplot(grid[0, :2])
ax2  = fig.add_subplot(grid[0, 2:])
ax3  = fig.add_subplot(grid[1, 1:3])
ax1.imshow(crop1)
ax2.imshow(crop2) # cropped
ax3.imshow(np.abs(crop1-crop2))
plt.show()

Search in the difference image

In [101]:
def pixeldiff(img1, img2):
    return np.abs(img1.sum()-img2.sum())

vt_step, vt_width = 10, 100
hz_step, hz_width = 10, 100

difflist=[]
for ivt in range(0, crop1.shape[0], vt_step):
    for ihz in range(0, crop1.shape[1], hz_step):
        if (ivt+vt_step < crop1.shape[0]) & (ihz+hz_step < crop1.shape[1]):
            difflist.append([ivt, ihz, pixeldiff( crop1[ivt:ivt+vt_width, ihz:ihz+hz_width], crop2[ivt:ivt+vt_width, ihz:ihz+hz_width])])

adiff = np.array(difflist)
adiff.shape
# sort by diff and take first 20%

highdiff = adiff[adiff[:,-1].argsort()][-int(adiff.shape[0]*0.1):]
In [109]:
rlist = [Rectangle((el[1],el[0]),vt_width,hz_width, ec='r', fc='r', linewidth=0, alpha=0.01) for el in highdiff]
fig, ax = plt.subplots(figsize=(10,10))
#ax.imshow(np.abs(crop1-crop2)/np.abs(crop1+crop2))
ax.imshow((crop1+crop2)/2)
for r in rlist:
    ax.add_patch(r)
ax.axis('off')
plt.show()
In [ ]: