Foro de elhacker.net

Programación => .NET (C#, VB.NET, ASP) => Mensaje iniciado por: Eleкtro en 28 Junio 2014, 08:36 am



Título: [APORTE] (ImageMatching) buscar una imagen en la pantalla y devolver coordenadas
Publicado por: Eleкtro en 28 Junio 2014, 08:36 am
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 (http://www.aforgenet.com/), 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
  1.    ' Find Image
  2.    ' ( By Elektro )
  3.    '
  4.    ' Usage Examples:
  5.    '
  6.    'Private Sub Test() Handles MyBase.Shown
  7.    '
  8.    '    ' A Desktop Screenshot, in 1920x1080 px. resolution.
  9.    '    Dim DesktopScreenshoot As New Bitmap("C:\Desktop.png")
  10.    '
  11.    '    ' A cutted piece of the screenshot, in 50x50 px. resolution.
  12.    '    Dim PartOfDesktopToFind As New Bitmap("C:\PartOfDesktop.png")
  13.    '
  14.    '    ' Find the part of the image in the desktop, with the specified similarity.
  15.    '    For Each matching As AForge.Imaging.TemplateMatch In
  16.    '        FindImage(BaseImage:=DesktopScreenshoot, ImageToFind:=PartOfDesktopToFind, Similarity:=80.5R) ' 80,5% Similarity.
  17.    '
  18.    '        Dim sb As New System.Text.StringBuilder
  19.    '
  20.    '        sb.AppendFormat("Top-Left Corner Coordinates: {0}", matching.Rectangle.Location.ToString())
  21.    '        sb.AppendLine()
  22.    '        sb.AppendFormat("Similarity Image Percentage: {0}%", (matching.Similarity * 100.0F).ToString("00.00"))
  23.    '
  24.    '        MessageBox.Show(sb.ToString)
  25.    '
  26.    '    Next matching
  27.    '
  28.    'End Sub
  29.    '
  30.    ''' <summary>
  31.    ''' Finds a part of an image inside other image and returns the top-left corner coordinates and it's similarity percent.
  32.    ''' </summary>
  33.    ''' <param name="BaseImage">
  34.    ''' Indicates the base image.
  35.    ''' </param>
  36.    ''' <param name="ImageToFind">
  37.    ''' Indicates the image to find in the base image.
  38.    ''' </param>
  39.    ''' <param name="Similarity">
  40.    ''' Indicates the similarity percentage to compare the images.
  41.    ''' A value of '100' means identical image.
  42.    ''' Note: High percentage values with big images could take several minutes to finish.
  43.    ''' </param>
  44.    ''' <returns>AForge.Imaging.TemplateMatch().</returns>
  45.    Private Function FindImage(ByVal BaseImage As Bitmap,
  46.                               ByVal ImageToFind As Bitmap,
  47.                               ByVal Similarity As Double) As AForge.Imaging.TemplateMatch()
  48.  
  49.        Dim SingleSimilarity As Single
  50.  
  51.        ' Translate the readable similarity percent value to Single value.
  52.        Select Case Similarity
  53.  
  54.            Case Is < 0.1R, Is > 100.0R ' Value is out of range.
  55.                Throw New Exception(String.Format("Similarity value of '{0}' is out of range, range is from '0.1' to '100.0'",
  56.                                                  CStr(Similarity)))
  57.  
  58.            Case Is = 100.0R ' Identical image comparission.
  59.                SingleSimilarity = 1.0F
  60.  
  61.            Case Else ' Image comparission with specific similarity.
  62.                SingleSimilarity = Convert.ToSingle(Similarity) / 100.0F
  63.  
  64.        End Select
  65.  
  66.        ' Set the similarity threshold to find all matching images with specified similarity.
  67.        Dim tm As New AForge.Imaging.ExhaustiveTemplateMatching(SingleSimilarity)
  68.  
  69.        ' Return all the found matching images,
  70.        ' it contains the top-left corner coordinates of each one
  71.        ' and matchings are sortered by it's similarity percent.
  72.        Return tm.ProcessImage(BaseImage, ImageToFind)
  73.  
  74.    End Function


Título: Re: [APORTE] (ImageMatching) buscar una imagen en la pantalla y devolver coordenadas
Publicado por: El Benjo en 28 Junio 2014, 20:55 pm
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í.


Título: Re: [APORTE] (ImageMatching) buscar una imagen en la pantalla y devolver coordenadas
Publicado por: engel lex en 28 Junio 2014, 21:09 pm
justamente viendo este tema pensé en opencl... ahora... que es cuda?


Título: Re: [APORTE] (ImageMatching) buscar una imagen en la pantalla y devolver coordenadas
Publicado por: Eleкtro en 28 Junio 2014, 21:14 pm
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 :).

que 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/cuda
CUDA 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!


Título: Re: [APORTE] (ImageMatching) buscar una imagen en la pantalla y devolver coordenadas
Publicado por: El Benjo en 28 Junio 2014, 21:19 pm
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.