1
votes

I'm trying to use the algorithms of AForge library seen in this little example to find an image inside an image, the code of that example works perfectlly ...but to finish the comparission (find 50x50px in 1920x1080px) it takes forever, so I would like to resize the images to gain speed...

From this:

Dim sourceImage As Bitmap = Bitmap.FromFile("C:\1.bmp")
Dim template As Bitmap = Bitmap.FromFile("C:\2.bmp")

To this else:

Dim sourceImage As Bitmap = ResizedBitmap1
Dim template As Bitmap = ResizedBitmap2

The problem is that when I try to use the methods with my resized Bitmaps I get an exception of: Unsupported pixel format of the source with this StackTrace:

AForge.Imaging.UnsupportedImageFormatException was unhandled
HResult=-2147024809 Message=Unsupported pixel format of the source or template image. Source=AForge.Imaging StackTrace: en AForge.Imaging.ExhaustiveTemplateMatching.ProcessImage(Bitmap image, Bitmap template, Rectangle searchZone) en AForge.Imaging.ExhaustiveTemplateMatching.ProcessImage(Bitmap image, Bitmap template) en WindowsApplication9.Form1.Test() en c:\users\administrador\documents\visual studio 2013\Projects\WindowsApplication9\WindowsApplication9\Form1.vb:línea 22 en WindowsApplication9.Form1._Lambda$__1(Object a0, EventArgs a1) en c:\users\administrador\documents\visual studio 2013\Projects\WindowsApplication9\WindowsApplication9\Form1.Designer.vb:línea 0 en System.Windows.Forms.Control.InvokeMarshaledCallbackHelper(Object obj) en System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) en System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) en System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) en System.Windows.Forms.Control.InvokeMarshaledCallback(ThreadMethodEntry tme) en System.Windows.Forms.Control.InvokeMarshaledCallbacks() en System.Windows.Forms.Control.WndProc(Message& m) en System.Windows.Forms.Form.WndProc(Message& m) en System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) en System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg) en System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData) en System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context) en System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context) en Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun() en Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel() en Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine) en WindowsApplication9.My.MyApplication.Main(String[] Args) en 17d14f5c-a337-4978-8281-53493378c1071.vb:línea 81 en System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args) en Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() en System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) en System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx) en System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state) en System.Threading.ThreadHelper.ThreadStart() InnerException:

So there seems to exist a difference between the Bitmaps instanced by the Bitmap Class than the Bitmaps that I return with my ResizeImage function.

This is the code that I'm using

Imports AForge.Imaging
Imports System.Drawing.Imaging

Public Class Form1

Private Sub Test() Handles MyBase.Shown

    ' A Desktop Screenshot, 1920x1080 px. resolution.
    Dim DesktopScreenshoot As New Bitmap("C:\1.png")

    ' A cutted piece of the screenshot, 55x57 px. resolution.
    Dim PartOfImageToFind As New Bitmap("C:\2.png")

    ' create template matching algorithm's instance.
    Dim sourceImage As Bitmap = ResizeImage(DesktopScreenshoot, Percent:=40.0R) ' Bitmap.FromFile("C:\1.bmp")
    Dim template As Bitmap = ResizeImage(PartOfImageToFind, Percent:=40.0R)   ' Bitmap.FromFile("C:\2.bmp")

    ' (set similarity threshold to 92.1%).
    Dim tm As New ExhaustiveTemplateMatching(0.921F)
    ' find all matchings with specified above similarity.

    Dim matchings As TemplateMatch() = tm.ProcessImage(sourceImage, template)
    ' highlight found matchings.

    Dim data As BitmapData =
        sourceImage.LockBits(New Rectangle(0, 0, sourceImage.Width, sourceImage.Height),
                                           ImageLockMode.ReadWrite, sourceImage.PixelFormat)

    For Each m As TemplateMatch In matchings

        Drawing.Rectangle(data, m.Rectangle, Color.White)

        ' do something else with matching
        MessageBox.Show(m.Rectangle.Location.ToString())

    Next m

    sourceImage.UnlockBits(data)

End Sub

' By Elektro
'
''' <summary>
''' Resizes an image by a size percentage.
''' </summary>
''' <param name="Bitmap">Indicates the image to resize.</param>
''' <param name="Percent">Indicates the percent size.</param>
''' <returns>Bitmap.</returns>
Private Function ResizeImage(ByVal [Bitmap] As Bitmap,
                             ByVal Percent As Double) As Bitmap

    Dim [Width] As Integer = ([Bitmap].Width) \ (100.0R / Percent)
    Dim [Height] As Integer = ([Bitmap].Height) \ (100.0R / Percent)

    Dim NewBitmap As New Bitmap(Width, Height)

    Using g As Graphics = Graphics.FromImage(NewBitmap)
        g.DrawImage([Bitmap], 0, 0, [Width], [Height])
    End Using

    Return NewBitmap

End Function

End Class
1
you might want to examine some of the other [Bitmap] properties like PixelFormat and resolution to make sure you are not accidentally changing one to a format AForge cannot handle (RTM for that). Also, your Resize function will only work well on a square image (messes up the AR). If it is more rectangular, you have to scale it.Ňɏssa Pøngjǣrdenlarp
@Plutonix I'm really a newbie playing with images, the problem logically was about pixelformat but I didn't understood exactlly what to do to fix it, just I've fixed it with an Dim NewBitmap As New Bitmap(Width, Height, Imaging.PixelFormat.Format24bppRgb) when resizing it, feel free to convert your comment into an answer to markit as accepted, thanks.ElektroStudios

1 Answers

1
votes

The problem may be with this:

Dim NewBitmap As New Bitmap(Width, Height)

The default values for things like PixelFormat or resolution may be something AForge cannot handle (the docs would tell what they can and cannot handle). Also, glancing at the SO link, it looks like (tl;dr) AForge has a Resize function (ResizeBicubic) which obviously might be expected to produce a bitmap it can handle.

Ignore my AR comment - I was thinking you wanted to resize to a Max or fixed H or W, which would require scaling the other.