views:

596

answers:

5

Hey folks,

After reading many related posts on this site on the subject of image comparison I'm thinking I'll try implementing a PCA on each image in order to see if an image is 'similar' or not, but I'm not sure how to get the data from my images - is there a VB function that I can use to convert the image into an array of bytes or something in order to compare images? Or a simpler way to compare two images (should be black and white but they'll be scanned, v. small images)

Thanks very much, Becky

A: 

You can use something:

Public Class MyClass
    Shared  Sub Main(ByVal args() As String)
       Byte() mydata = File.ReadAllBytes("C:\MyFile.jpg")
    End Sub
End Class
Bhaskar
+1  A: 

Also, here is a useful article: this guy took two images, compared them, then created a third image that graphically represented the difference between the two. It appears to be a nice visual way to depict similiarity.

Diakonia7
thank you for pointing out my error. For now, I felt it was best to leave the first section up with a disclaimer. If you feel otherwise please feel free to comment and I will consider removing the section. Cheers.
Diakonia7
@roygbiv - again, thanks for your comment. I believe you do make a valid point, however blunt you may make it. Cheers
Diakonia7
That article looks like I can make something out of it I think - very nice find :o)
Becky Franklin
+1  A: 

To see if they're identical or not is quite easy using roygbiv's answer. To see how similar they are is quite complicated. If these are scanned documents they're really never going to be identical. It may be worthwhile to invest in a third party option. We use products in our scanning process from Accusoft and TiS.

That said, there are a couple of potential duplicate questions.

hometoast
Actually it may be easier than you think. You could compare each byte, and see how much they differ in their values. Than you do this for every byte and in the final calculate some percentages based in the values you read.
Victor
+1 for sesible advice! Checking equality is easy, checking if it's the 'same' image is not.
Stevo3000
@Victor if that same image is panned to the left or right, then they're not likely to be at all similar by that method. But to the human eye, they're the same thing.
hometoast
A: 

So, this is what I came up with. Rather than compare the pixels individually, I used a hashing algorithm fed from the contents of the file. It then compares the individual bytes of the returned hash. In my tests, it came back twice as fast as comparing the individual pixels for a gray-scale bitmap image 1152 X 720 and 101KB big.

Here's the code:

(editing because the first time I posted the code everything looked strange. removed comments.)

Public Shared Function CompareTwoImageHashes(ByVal pathToFirstImage As String, ByVal pathToSecondImage As String) As Boolean

 Dim firstImage As FileInfo = New FileInfo(pathToFirstImage)
 Dim secondImage As FileInfo = New FileInfo(pathToSecondImage)

 If Not firstImage.Exists Then
  Throw New ArgumentNullException("pathToFirstImage", "The file referenced by the path does not exist!")
 End If

 If Not secondImage.Exists Then
  Throw New ArgumentNullException("pathToSecondImage", "The file referenced by the path does not exist!")
 End If

 Dim hashingTool As SHA256Managed
 Dim imagesMatch As Boolean = True

 Try

  Using firstImageStream As New FileStream(firstImage.FullName, FileMode.Open)
   Using secondImageStream As New FileStream(secondImage.FullName, FileMode.Open)

    hashingTool = SHA256Managed.Create()

    Dim imageOneHash As Byte() = hashingTool.ComputeHash(firstImageStream)
    Dim imageTwoHash As Byte() = hashingTool.ComputeHash(secondImageStream)

    hashingTool.Clear()

    If (imageOneHash.Length = imageTwoHash.Length) Then

     For length As Integer = 0 To (imageOneHash.Length - 1)

      If imageOneHash(length) <> imageTwoHash(length) Then
       imagesMatch = False

       Exit For
      End If

     Next

     CompareTwoImageHashes = imagesMatch
    Else
     CompareTwoImageHashes = False
    End If

   End Using
  End Using

 Catch ex As Exception

  Console.WriteLine("Error during compare: {0}", ex.Message)

 End Try

End Function
Maurice Reeves
A: 

For retrieving the pixel data of an image; you can either use Bitmap.GetPixel or Bitmap.LockBits, which will give you a BitmapData (link has example code) class in return.

DanStory