We help IT Professionals succeed at work.

# Can this bitmap compare be speed-tweaked?

on
Medium Priority
481 Views

Hey, I have to compare a series of bitmaps to portions of a larger, stored bitmap to see if they match, and I've got code that works, but it would be better if it worked faster.  My code is below... I've tried a couple of things but right now that's best I can do.  Has anyone done this a different way that might be faster (I'll benchmark it)?

One weird thing is that my bitmaps seem to be not identical matches, what seems to work is if I give it a threshold of +-6 on the R, G, and B compare... thus the strange compare.

Thanks!

****

Private Function ComparePixels(ByVal ox As Integer, ByVal oy As Integer, ByVal CompareTo As Bitmap) As Integer

' simple: got a match, add one; mismatch, subtract two

Dim c1 As Color, c2 As Color, result As Integer = 0

For x As Integer = 0 To CompareTo.Width - 1

For y As Integer = 0 To CompareTo.Height - 1

c1 = m_bmp.GetPixel(ox + x, oy + y)
c2 = CompareTo.GetPixel(x, y)

if CompareColor(c1, c2) then
result += 1
Else
result -= 2
End If

Next

Next

ComparePixels = result

End Function

Private Function CompareColor(ByVal c1 As Color, ByVal c2 As Color) As Boolean

Const T As Integer = 6

If c1.R > c2.R - T Then
If c1.R < c2.R + T Then
If c1.G > c2.G - T Then
If c1.G < c2.G + T Then
If c1.B > c2.B - T Then
If c1.B < c2.B + T Then
Return True
End If
End If
End If
End If
End If
End If

Return False

End Function
Comment
Watch Question

## View Solutions Only

Commented:

Oh, and I MIGHT be able to solve the (separate) mismatched images problem, which would mean that I don't need the +/- 6 threshold any nore, so I would also be interested in alternatives that only work on perfectly identical images.
Commented:
If you can get rid of the mismatched images problem, this might help

Imports System
Imports System.Drawing
Imports System.Drawing.Imaging
Imports System.Security.Cryptography
Namespace Imagio

Public Class ComparingImages

Public Enum CompareResult
Private ciCompareOk
Private ciPixelMismatch
Private ciSizeMismatch
End Enum

Public Shared Function Compare(ByVal bmp1 As Bitmap, ByVal bmp2 As Bitmap) As CompareResult
Dim cr As CompareResult = CompareResult.ciCompareOk
If Not (bmp1.Size = bmp2.Size) Then
cr = CompareResult.ciSizeMismatch
Else
Dim ic As System.Drawing.ImageConverter = New System.Drawing.ImageConverter
Dim btImage1(1) As Byte
btImage1 = CType(ic.ConvertTo(bmp1, btImage1.GetType), Byte())
Dim btImage2(1) As Byte
btImage2 = CType(ic.ConvertTo(bmp2, btImage2.GetType), Byte())
Dim shaM As SHA256Managed = New SHA256Managed
Dim hash1 As Byte() = shaM.ComputeHash(btImage1)
Dim hash2 As Byte() = shaM.ComputeHash(btImage2)
Dim i As Integer = 0
While i < hash1.Length AndAlso i < hash2.Length AndAlso cr = CompareResult.ciCompareOk
If Not (hash1(i) = hash2(i)) Then
cr = CompareResult.ciPixelMismatch
End If
End While
End If
Return cr
End Function
End Class
End Namespace

I'm just the messenger.  It's code from http://www.codeproject.com/dotnet/comparingimages.asp translated to VB.NET on http://www.developerfusion.co.uk/utilities/convertcsharptovb.aspx

Roger

Not the solution you were looking for? Getting a personalized solution is easy.

CERTIFIED EXPERT
Most Valuable Expert 2012
Top Expert 2008

Commented:
What version of .NET are you using?

Bob
CERTIFIED EXPERT
Most Valuable Expert 2012
Top Expert 2008

Commented:
Here is a reference for VB.NET 2003:

Manipulate multiple images' pixels very quickly using LockBits wrapped in a class in VB .NET
http://www.vb-helper.com/howto_net_lockbits_images_class.html

Bob

Commented:

.NET 2005

I'll try it when I get a chance, unless you know it does not work in 2005...
CERTIFIED EXPERT
Most Valuable Expert 2012
Top Expert 2008
Commented:
In 2005, you can mix C# code within your VB.NET project.  You could include a class that has C# code, which with unsafe pointers can be significantly faster than VB code doing the same thing:

http://www.bobpowell.net/lockingbits.htm

Bob

Commented:

Bob, I would like to try to mix in the C# approach to locking bits to compare the speed, but I'm not sure how to do that?  Is there a certain class attribute or something that causes a file to be interpreted as c#?

Commented:

Okay, that helped a lot thanks.  I arrived at an unexpected spot, though... I took the cue that GetPixel is fundamentally slow (which, I suppose, is why locking it helps), and I wrote a ColorField class that scanned all needed data once into my own array, and then compared the arrays of respective color fields, rather than pixels from the bitmap object (I didn't mentiont this, but I tend to compare the same pictures again and again, so this helped a lot).  The unexpected thing is that (a) below was significantly faster than (b), so I ended up not using the LockBits at all, I just minimized my use of GetPixel.   But I'm much better off now, thanks for the help.

Bob, if you could still give me a link or something showing how to mix in C# code, that would be helpful...

**** (a)

Private Sub GetData(ByVal i As Bitmap, ByVal r As Rectangle)

Dim x As Integer, y As Integer, c As Color

For x = 0 To r.Width - 1
For y = 0 To r.Height - 1

c = i.GetPixel(x + r.Left, y + r.Top)

Red(x, y) = c.R
Green(x, y) = c.G
Blue(x, y) = c.B

Next
Next

End Sub

***** (b)

Private Sub GetData2(ByVal i As Bitmap, ByVal r As Rectangle)

Dim x As Integer, y As Integer

Dim bd As BitmapData

For x = 0 To r.Width - 1
For y = 0 To r.Height - 1

Blue(x, y) = Marshal.ReadByte(bd.Scan0, (bd.Stride * y) + (4 * x))
Green(x, y) = Marshal.ReadByte(bd.Scan0, (bd.Stride * y) + (4 * x) + 1)
Red(x, y) = Marshal.ReadByte(bd.Scan0, (bd.Stride * y) + (4 * x) + 2)

Next
Next

i.UnlockBits(bd)

End Sub
CERTIFIED EXPERT
Most Valuable Expert 2012
Top Expert 2008

Commented:
Create a class, put in the C# code, and reference it from a VB.NET class/form.

Bob

Commented:
To be clear, I should add (and reference) a C# class library project to my solution?  Or can I somehow include a C# class file directly in my VB.NET project?
##### Thanks for using Experts Exchange.

• View three pieces of content (articles, solutions, posts, and videos)
• Ask the experts questions (counted toward content limit)
• Customize your dashboard and profile