Comparing two images

czeslaw1

Member
Joined
May 18, 2009
Messages
18
Programming Experience
Beginner
I'm currently working on an application witch takes two images and comparing them on how equal they are.
I want it to display in "%" how equal the pictures are.

Like:


Picture 1 (orginal) - Picture 2 (Edited)

The picture is 67% equal


Anyone know how to do this, i have been s earching everywhere..
 
VB.NET:
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim bmp1 As Bitmap = Image.FromFile("C:\Temp\ImageCompare\chill.jpg")
        Dim bmp2 As Bitmap = Image.FromFile("C:\Temp\ImageCompare\chill1.jpg")

        Dim sameCount As Integer = 0
        Dim diffCount As Integer = 0

        For x As Integer = 0 To (bmp1.Width) - 1
            For y As Integer = 0 To (bmp1.Height) - 1
                If bmp1.GetPixel(x, y).Equals(bmp2.GetPixel(x, y)) Then
                    sameCount += 1
                Else
                    diffCount += 1
                End If
            Next
        Next

        Dim total As Integer = sameCount + diffCount

        MessageBox.Show(String.Format("Same Percentage: {0}{1}Difference Percentage: {2}", _
                                      (sameCount / total).ToString("p"), Environment.NewLine, (diffCount / total).ToString("p")))
    End Sub
 
If you want to compare how similar the images are instead of exact pixel equality as code posted by MattP you can use the HSB color space. Let's say you take an image and adjust brightness just a little bit, now the pixel equality will be 0% or close to, but the images will still look very much alike, they could be 99% similar without a single pixel being equal. This similarity is not difficult to compute, same as the previous code you can loop all pixels (given images have same width/height) and get the Hue, Saturation and Brightness values. The idea here is to calculate equality percentage for each pixel, then average the total. This is the sample code:
VB.NET:
Dim i1 As New Bitmap("image1.png")
Dim i2 As New Bitmap("image1edited.png")
Dim avg As Single
For x As Integer = 1 To i1.Width - 1
    For y As Integer = 1 To i1.Height - 1
        Dim c1 As Color = i1.GetPixel(x, y)
        Dim c2 As Color = i2.GetPixel(x, y)
        Dim h As Single = (360 - Math.Abs(c1.GetHue - c2.GetHue)) / 360
        Dim s As Single = 1 - Math.Abs(c1.GetSaturation - c2.GetSaturation)
        Dim b As Single = 1 - Math.Abs(c1.GetBrightness - c2.GetBrightness)
        avg += (h + s + b) / 3
    Next
Next       
Dim eq As Single = avg / (i1.Width * i1.Height)
i1.Dispose()
i2.Dispose()
Debug.WriteLine(eq.ToString("p"))
 
I'd say, there is no SIMPLE way to tell how "equal" two pictures are. All the "face finding" products have the same problem.
The problem starts already with the definition of "equal".
Say you have a picture with a black background and a white square and the second picture is just the opposite (black square on white ground), how equal would you rate them?
0% because one is the exact opposite of the other?
99.9999% because they share the exact same structure and differ only in 2 colors?
As you see, your problem lies exactly between 0% and 99.9999% ;)
 
I'd say, there is no SIMPLE way to tell how "equal" two pictures are. All the "face finding" products have the same problem.
The problem starts already with the definition of "equal".
Say you have a picture with a black background and a white square and the second picture is just the opposite (black square on white ground), how equal would you rate them?
0% because one is the exact opposite of the other?
99.9999% because they share the exact same structure and differ only in 2 colors?
As you see, your problem lies exactly between 0% and 99.9999% ;)
Depending on how you want to compare it may be easy or difficult. Pattern recognition is very difficult. Statistical comparison such as both suggestions here are easy. An average will never tell the truth about similar patterns, it will only tell to which degree the images are filled with similar colors.

If your example has 50% black/white and the images are opposite, then the exact pixel equality is 0%, and average pixel equality is 100%.

Contrary to common perception black/white are not "opposite" colors, their hue and saturation values are equal, but brightness is exactly opposite 0/1. So for my example these images would be exactly 66.66% equal.

Since it is hue that determines the base color the average calculation above can be improved by weightening hue higher than saturation and brightness. It depends on the perception and the goal with the calculation.

Another variation of the approach to statistical comparison could be to set a treshold when comparing two colors, either in RGB or HSB, that would determine if those colors were "equal" or "not equal" and then calculate average.

If you want to expand the calculations, you can divide the images up in smaller parts that you compare and average independently. This can give the average higher accuracy, including closing in on actual image composition.

As you can see there are several ways to play with numbers to determine how much color information two images share, but pattern recognition is a whole different league. It still can be interesting to start learning about colors and analysing images.
Close thread.
We normally don't close threads here, leave them open for further discussions and feedback. Glad you found something useful in the replies.
 
If you want to expand the calculations, you can divide the images up in smaller parts that you compare and average independently.
I wonder if one could use the Levenshtein or Damerau-Levenshtein distance together with this approach?

@czeslaw1: you might want to look at Aforge.Net which is a free (LGPL) library with quite some powerfull imaging functions.
 
Back
Top