1

Given two images of the same scene with potential alignment, focus, lighting differences and noise, I am looking for an operation that I can run on these images that produces another image of the difference between them that minimizes these differences or is more sensitive to the structural differences between them than the global differences. My initial thought was a comparison between the corresponding neighborhoods around a pixel in image A and the same pixel in image B might work.

Is this function already implemented in OpenCV or some other Python library (scipy, numpy etc)?

My musings:

A simple frame difference would tell me where absolute differences occur but is very brittle to alignment, lighting differences. Maybe there is a way to find the standard deviation over a pixel's neighborhood. Numpy's std only works by axis...

This seems like I want the correlation between two signals but I don't know how to extend this to a non-repeating 2D world. scipy.signal.correlate2d seems like it may work if there was an efficient way to just pass corresponding neighborhoods to it. However, I don't have a good feel for what is going on under the hood.

A convolution of one image where the kernel comes from corresponding locations in the other images would give a comparison that would handle noise and focus issues well but I don't know how to use a dynamic kernel for a convolution.

If I had a library of basically identical images (not an original assumption but doable) to compare one image to, I could use a mean difference or mixture of gaussians. But I don't think this would help with alignment or lighting. I could align the image first and then do the comparison.

Per the comment below, I looked up the skimage SSIM (Structural Similarity Index) method that is used to measure image degradation due to things like lossy compression and decompression. It actually expects two copies of the same image - one a truth source, one in a potentially degraded state due to lossy compression and decompression. This method is soft on global bias (lighting), which is good, but sensitive to noise (by design) and especially sensitive to misalignment.

The comment led me to MSE which acts globally, but if iterated over an image by neighborhood, it gives a good result - insensitive to bias, noise but not structural differences. However, it is fairly sensitive to alignment differences and very slow in python...

# Mean Squared Error
def mse(imageA, imageB):
    return np.mean((imageA - imageB)**2)

from scipy import misc
import numpy as np
face = misc.face()
nface = np.array(face)
nface[295:305,395:415] = face[195:205,495:515] #discontinuous region
nface = cv2.blur(nface, (3,3)) # focus effects
nface = nface + (np.random.randn(*face.shape) * 10 - 5) # noise
nface = (nface * .9 + 20).astype(int) #lighting
n = m = 3
output = np.zeros(face.shape[:2])
for i in range(face.shape[0]):
    for j in range(face.shape[1]):
        if i > n and i < face.shape[0]-n and j > m and j < face.shape[1]-m:
            output[i,j] = mse(nface[i-n:i+n, j-m:j+m], face[i-n:i+n, j-m:j+m])

Is this a common image processing technique? Is there an name for this or an optimized implementation in openCV or Numpy?

DanGoodrick
  • 2,818
  • 6
  • 28
  • 52
  • Not sure I understand what you are really looking for but maybe it's SSIM https://www.pyimagesearch.com/2017/06/19/image-difference-with-opencv-and-python/ – Mark Setchell Feb 27 '20 at 18:49
  • 1
    You might have a look at one of the [optical flow](https://docs.opencv.org/3.4/d4/dee/tutorial_optical_flow.html) algorithms and see if that's what you need. These assume motion between frames, so they might work better for you. – beaker Feb 27 '20 at 22:45
  • Another option would be [image hashing](https://github.com/bjlittle/imagehash). It's what TinEye supposedly uses to do their reverse image search. It is very, very fast. Basically you calculate a 'hash' of an image that is designed to be very close to the hash of the same image with slight changes. Then take the difference of the 2 hashes and decide with a threshold or clustering algorithm whether they're the same image. – Victor Sonck Feb 28 '20 at 13:15

0 Answers0