[APORTE] (ImageMatching) buscar una imagen en la pantalla y devolver coordenadas

Iniciado por Eleкtro, 28 Junio 2014, 08:36 AM

0 Miembros y 1 Visitante están viendo este tema.

Eleкtro

Hace un tiempo estuve indagando acerca de como narices implementar un (decente) algoritmo de ImageMatching, esto significa, identificar la existencia de una imagen en la pantalla, y de paso obtener las coordenadas para futuros usos.

Pues bien, despues de mucho investigar y mucha documentación leida, está claro que un algoritmo casero no puede llegar a compararse en eficacia y rendimiento a un producto (una librería) de renombre que tenga la suficiente experiencia en el ámbito, pues esto no es un simple PixelSearch, es algo mucho más laborioso.

Después de probar en profundidad distintos productos/librerías, encontré Aforge.NET, el cual es muy bueno tanto en su capacidad efectiva como en su velocidad de procesamiento de imagen, aunque no resulta tan rápido como a mi me gustaria y como he visto en algún que otro Software.

Nota: Si alguien conoce alguna librería eficiente y más rápida que Aforge, le agradecería que lo comentase.

Este código necesita la utilización de dicha librería, AForge, y sirve para identificar una imagen en la pantalla y obtener sus coordenadas, algo imprescindible si tienes pensado desarrollar un Bot por reconocimiento de imagen... así que espero que le sirva a alguien de ayuda.

Unos consejos antes de utilizar:
1. Si la imagen es demasiado grande, redimensionala al 40-60% (cuidado, cuando más difuso estén los pixeles puede ser menos efectivo).
2. Si la velocidad no es la esperada, prueba también a convertir la imagen a una escala de grises.

Código (vbnet) [Seleccionar]
    ' Find Image
    ' ( By Elektro )
    '
    ' Usage Examples:
    '
    '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
    '
    ''' <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








El Benjo

Elektro, se me ocurre (pensando en lo que dijiste sobre el pixel search) que quizá utilizando CUDA u OpenCL su pudiera realizar una librería decente (en eficiencia) con métodos tradicionales de búsqueda. No sé si lo habías considerado, aunque creo que sí.
www.es.neftis-ai.com

Sí hay un mejor lenguaje de programación y es ese con el que puedes desarrollar tus objetivos.

engel lex

justamente viendo este tema pensé en opencl... ahora... que es cuda?
El problema con la sociedad actualmente radica en que todos creen que tienen el derecho de tener una opinión, y que esa opinión sea validada por todos, cuando lo correcto es que todos tengan derecho a una opinión, siempre y cuando esa opinión pueda ser ignorada, cuestionada, e incluso ser sujeta a burla, particularmente cuando no tiene sentido alguno.

Eleкtro

No se me habia pasado por la cabeza usar CUDA, y porsupuesto debe resultar mucho más veloz que los otros métodos, me pondré a documentarme sobre ello y a ver si encuentro algo interesante para compartir :).

Cita de: engel lex en 28 Junio 2014, 21:09 PMque es cuda?

CUDA es el motor GPU de nVidia, ATI tiene otro, pero no recuerdo su nombre. las aplicaciones pueden aprovechar la aceleración GPU para aumentar el rendimiento de una forma bastante increible.

Cita de: http://www.geforce.com/hardware/technology/cudaCUDA is a parallel computing platform and programming model invented by NVIDIA. It enables dramatic increases in computing performance by harnessing the power of the graphics processing unit (GPU).

Saludos!








El Benjo

Ah, mi estimado Lex, CUDA es el lenguaje desarrollado por nVidia para sus chips gráficos. Se supone (no me consta nada) que CUDA se programa a un nivel más bajo y más cercano al chip y que es más eficiente que el código equivalente en OpenCL. el único inconveniente es que sólo corre sobre los chips de nVidia. Me parece que ATI tenía un lenguaje similar pero no prosperó y a la larga terminaron adoptando OpenCL.

EDITADO: Quizá si se hiciera de esta manera, incluso los algoritmos de búsqueda más exhaustiva podrían hacer el trabajo en poco tiempo.
www.es.neftis-ai.com

Sí hay un mejor lenguaje de programación y es ese con el que puedes desarrollar tus objetivos.