riceman0
asked on
Can this bitmap compare be speed-tweaked?
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
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
What version of .NET are you using?
Bob
Bob
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
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
ASKER
.NET 2005
I'll try it when I get a chance, unless you know it does not work in 2005...
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
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#?
ASKER
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
bd = i.LockBits(r, ImageLockMode.ReadOnly, i.PixelFormat)
For x = 0 To r.Width - 1
For y = 0 To r.Height - 1
Blue(x, y) = Marshal.ReadByte(bd.Scan0,
Green(x, y) = Marshal.ReadByte(bd.Scan0,
Red(x, y) = Marshal.ReadByte(bd.Scan0,
Next
Next
i.UnlockBits(bd)
End Sub
Create a class, put in the C# code, and reference it from a VB.NET class/form.
Bob
Bob
ASKER
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?
ASKER
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.