How can I compare two images and determine if they are 100% similar, or only altered in color, or cropping?
-
Are you talking about exact duplicates that have been artificially colored? Or do you mean two different pictures of the same thing. It could make a significant difference in the approach. – Pace Nov 04 '10 at 12:16
-
I'm only looking for digitally altered copies, including colored ones. No checksum approach would likely work here... – makerofthings7 Nov 04 '10 at 19:49
3 Answers
Well, abstractly speaking, you need to define a similarity function, that compares two images. To determine if the images are "100% similar" (equal) you can do the following:
- compare the sizes of the images
- if the image sizes are the same simply subtract the pixels from each other
if ( sum( abs( pixel_1_i - pixel_2_j ) ) / num_pixels < threshold ) return true
For the case that images are differently colored, or cropped
- apply an edge detector to both images
- compute the cross-correlation (in the frequency domain, FFT)
- find the highest peak
- place the (smaller) edge map in the determined position
- calculate the absolute error
if (error < threshold) return true
BTW: This approach will not work if your images are scaled or rotated.
Further Research:
-
Is this supposed to be inside looping of pixels or can this work without looping through all the pixels "if ( sum( abs( pixel_1_i - pixel_2_j ) ) / num_pixels < threshold ) return true" ? – Josh Oct 06 '12 at 21:22
-
The line, that you quoted, is supposed to be the sum of absolute differences, so it makes sense to do this over all pixels. You can blur the image and scale it down, if you have to compare it to many other images. – bjoernz Oct 07 '12 at 18:08
-
1I have never coded in C#... just google around or open a new question, so you can get more qualified help. – bjoernz Oct 10 '12 at 21:34
The following is a fairly simplistic approach to the problem and won't work well with two different photographs of the same subject taken from slightly different angles, but would work if you had two copies of the same image that you wanted to verify.
The case of two identical images is straightforward - just loop through the pixel arrays subtracting on RGB value from the other. If the difference is less than a small tolerance then the pixel is identical. Thus as soon as you find a pixel difference greater than the tolerance you know that the images are different.
You could allow for a certain number or percentage of differences to allow for differences causes by compression artefacts.
To check for alterations in colour you could look at the HLS (Hue, Lightness and Saturation) values instead. If the pixels have the same L & S values but a different H value then it's just the colour that's different (I think).
Cropping is more difficult as you have to try to find the location of the smaller image in the larger one.

- 134,786
- 31
- 255
- 325
-
This is very interesting and helpful. I'll have to determine how to approach this for each image format. – makerofthings7 Nov 04 '10 at 19:53
You can use object descriptors such as:
SIFT - http://en.wikipedia.org/wiki/Scale-invariant_feature_transform
SURF - http://en.wikipedia.org/wiki/SURF
Then compare images by using calculated descriptors. Those descriptors will enable you to deal with rotated, scaled and slightly changed images.
Also the descriptors consist of oriented gradients meaning that those descriptors are robust to illumination and color changes as well.
You can use Accord.NET (SURF implementation).

- 2,373
- 2
- 20
- 43