4

I'm using the AForge library to find a (part of an) image inside other image using this code example.

(The images below are just for give an example)

I'm using this desktop screenshot in 1920x1080 px.:

enter image description here

And I search for and locate this piece of the image above (55x557 px.):

enter image description here

But I resize both images to it's 25% (to gain comparission speed), so when I compare the images the desktop screenshot is 480x270 px. and the cutted image is 13x14 px.

Using the AForge library it returns me the relative coordinates of the found (cutted) image inside the resized desktop screennshot, the coordinates are x=86, y=200.

Now I need to set the mouse position in my dektop, in the center of the VMWare icon (more exactlly in the center of the found cutted image), and here is where I'm confussed, what is the arithmetic operation to set the mouse position there?

I'll remember:

Resolutions:

My Desktop: 1920x1080

Image 1 : 1920x1080

Image to find in Image1 : 55x57

Resized Image1: 480x270

Resized Image to find in Image1 : 13x14

Relative coordinates of the found resized Image to find in Image1 :

x=86, y=200

Community
  • 1
  • 1
ElektroStudios
  • 19,105
  • 33
  • 200
  • 417
  • first question - are you sure it found it? if you load the image in something like Photoshop, is it really at that location (you have a Point typo: `x=86, x=200` 2 x's?). That said, the larger is 4x the smaller, so x=344 y=800 seems right – Ňɏssa Pøngjǣrdenlarp May 10 '14 at 23:12
  • x = (My Desktop.x / Resized Image1.x) * Relative coordinates.x; y = (My Desktop.y / Resized Image1.y) * Relative coordinates.y; – Dmytro May 10 '14 at 23:14
  • Sorry about the typo, I've fixed it, and yes I'm sure that the image is found, I've seen the coordinates in MSPaint, and I need to clarify that the coordinates that AForge gives me corresponds to the top-left corner of the cutted image found – ElektroStudios May 10 '14 at 23:14
  • larger/smaller is ambiguous = the original desktop is 4x the smaller one you searched, so use a factor of 4. I wonder if it finds images of a different scale - resize desktop by X% and the image to find by Y% and see if it finds it – Ňɏssa Pøngjǣrdenlarp May 10 '14 at 23:19
  • @Plutonix I retrieve the relative coordinates into a `Rectangle`, so maybe I could use the `Inflate` method of a rectangle to simplificate things?... but maths are not my – ElektroStudios May 11 '14 at 00:58
  • @Dmytro Tsiniavskyi the operation is not giving me the desired result, maybe I've translated bad what you mean?: `Dim x As Integer = (Screen.PrimaryScreen.Bounds.Width / ResizeImage(DesktopScreenshoot, Percent:=25.0R).Width) * m.Rectangle.X` , that is: `(Desktop Width / ResizedImage1 Width) * RelativeCordinates.X` I can only obtain the coordinates on the resized image for obvious performance things (speed) – ElektroStudios May 11 '14 at 01:04
  • The resulting coordinates should be x=343, y=801 for 1920x1080p image – ElektroStudios May 11 '14 at 01:17
  • see my first comment 2 hrs ago (maybe refresh). `100 / 25 = 4` you reduced by a factor of four so inflate the result accordingly – Ňɏssa Pøngjǣrdenlarp May 11 '14 at 01:24
  • @Plutonix yes was my fault but sorry I've noticed that the rectangle has nothing to do with my problem, I was confused by AForge and the rectangle is just for drawing a thing in the code-example, nothing to do I mean any rectangle to inflate by the resized image (size) * 4, so I've the same values and the same problem, just resolutions and a coordinates, how to solve it then?. – ElektroStudios May 11 '14 at 04:48
  • `100 / 25 = 4` which when used to multiply the found Point gives the expected result. Is the issue that AForge returns the Top/Left of the found location, and you want to further adjust x=344, y=800 to point to the center of the found image rect? – Ňɏssa Pøngjǣrdenlarp May 11 '14 at 12:05
  • @Plutonix not exactlly x=343, y=801 are the respective top-left corner coordinates at "full screen", I've just translated manually the coordinates of the resized image onto the normal size image but I didn't calculate the "center" 'cause I don't know how to – ElektroStudios May 11 '14 at 13:09

3 Answers3

1

If you really found the spot and if you really are working with the full desktop reduced to 1/4th and not a window, then you can simply multiply back to the original scale and move the mouse like this:

newPos= new Point(foundX * 4, foundY * 4);
Cursor.Position = newPos;

If your FoundPosition is not the Middle but the TopLeft you would adapt the newPos like this:

newPos= new Point(foundX * 4 + originalWidth / 2, foundY * 4 + originalHeight / 2);

If you are in a window you must also calculate the relative positiom to screen coordinates with the PointToScreen() function before setting the mouse position.

TaW
  • 53,122
  • 8
  • 69
  • 111
1

When you reduce the image you do this:

intReducePct = 25
ReducedImg1 = ResizeImage(desktopBMP, intReducePct)

' save a restore factor
intFactor = (100 / intReducePct)      ' == 4

' I dont know what the AFOrge search returns, a Point probably
foundPt = Aforge.FindImgInImg(...)

' convert fountPt based on reduction factor (you reduced by 1/4th,
'    so scale up by 4x, basically)
Dim actualPoint As New Point(foundPt.X * intFactor, foundPt.Y * intFactor) 

AForge returned x=86, y=200; and 86*4 = 344; 200*4=800 but that is the Top/Left (?) in the original image and you apparently want the center of the found image, so also adjust for the original bitmap:

' convert fountPt based on reduction factor + bmpFind size:
Dim actualPoint As New Point((foundPt.X * intFactor) + (bmpFind.Width \ 2),
                             (foundPt.Y * intFactor) + (bmpFind.Height \ 2))

bmpFind would be the original image before reduction. Option Strict will insist on some CTypes, but this should be the gist of it.

Ňɏssa Pøngjǣrdenlarp
  • 38,411
  • 12
  • 59
  • 178
0

I want to share this generic usage method that I've wrote to simplify things:

''' <summary>
''' Finds a part of an image inside other image and returns the top-left corner coordinates and it's similarity percent.
''' </summary>
''' <param name="BaseImage">
''' Indicates the base image.
''' </param>
''' <param name="ImageToFind">
''' Indicates the image to find in the base image.
''' </param>
''' <param name="Similarity">
''' Indicates the similarity percentage to compare the images.
''' A value of '100' means identical image. 
''' Note: High percentage values with big images could take several minutes to finish.
''' </param>
''' <returns>AForge.Imaging.TemplateMatch().</returns>
Private Function FindImage(ByVal BaseImage As Bitmap,
                           ByVal ImageToFind As Bitmap,
                           ByVal Similarity As Double) As AForge.Imaging.TemplateMatch()

    Dim SingleSimilarity As Single

    ' Translate the readable similarity percent value to Single value.
    Select Case Similarity

        Case Is < 0.1R, Is > 100.0R ' Value is out of range.
            Throw New Exception(String.Format("Similarity value of '{0}' is out of range, range is from '0.1' to '100.0'",
                                              CStr(Similarity)))

        Case Is = 100.0R ' Identical image comparission.
            SingleSimilarity = 1.0F

        Case Else ' Image comparission with specific similarity.
            SingleSimilarity = Convert.ToSingle(Similarity) / 100.0F

    End Select

    ' Set the similarity threshold to find all matching images with specified similarity.
    Dim tm As New AForge.Imaging.ExhaustiveTemplateMatching(SingleSimilarity)

    ' Return all the found matching images, 
    ' it contains the top-left corner coordinates of each one 
    ' and matchings are sortered by it's similarity percent.
    Return tm.ProcessImage(BaseImage, ImageToFind)

End Function

An Usage Example:

Private Sub Test() Handles MyBase.Shown

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

    ' A cutted piece of the screenshot, in 50x50 px. resolution.
    Dim PartOfDesktopToFind As New Bitmap("C:\PartOfDesktop.png")

    ' Find the part of the image in the desktop, with the specified similarity.
    For Each matching As AForge.Imaging.TemplateMatch In
        FindImage(BaseImage:=DesktopScreenshoot, ImageToFind:=PartOfDesktopToFind, Similarity:=80.5R) ' 80,5% Similarity.

        Dim sb As New System.Text.StringBuilder

        sb.AppendFormat("Top-Left Corner Coordinates: {0}", matching.Rectangle.Location.ToString())
        sb.AppendLine()
        sb.AppendFormat("Similarity Image Percentage: {0}%", (matching.Similarity * 100.0F).ToString("00.00"))

        MessageBox.Show(sb.ToString)

    Next matching

End Sub
ElektroStudios
  • 19,105
  • 33
  • 200
  • 417