¿Cómo puedo detectar botones en una GUI de una aplicación con detección de patrones usando python?

8

Explicaré tomando como ejemplo la GUI de la aplicación Calculadora en Windows. Dada esta aplicación de Calculadora abierta y enfocada, necesito encontrar una manera de detectar todos los botones. Solo puedo usar métodos no intrusivos, por lo que cosas como la identificación del botón están fuera de discusión. Esto me lleva al reconocimiento de imágenes. O mejor decir detección de imágenes, porque no quiero una imagen específica, sino un conjunto de imágenes que siguen un cierto patrón. Sé cómo puedo hacer clic / clic derecho / dbl-clic / etc. usando una imagen de botón y reconocimiento de imagen [1]. No sé cómo puedo hacer al revés: escanee la GUI y encuentre aquellas áreas que cumplan con los requisitos de ser un botón (rectángulo, texto / icono / gráfico etiquetado, etc.). Un abordaje más grande sería detectar elementos que no tienen la forma del rectángulo (por ejemplo, iconos en un escritorio de Windows)

Lo más parecido a lo que necesito es detectar caras en una imagen. [2] Pero no sé cómo aplicar esto en mi caso. Para la detección de rostros humanos, vi que se deben usar cientos de imágenes de la cara en la generación en cascada de Haar (no sé cómo haría esto con solo 10-15 instantáneas de botones). Si se debe detectar otro tipo de objeto como una manzana, debe generar una cascada Haar para ese objeto nuevamente utilizando muchas imágenes.

¿Alguno de ustedes alguna vez trató de detectar botones, elementos o lo que sea en una GUI utilizando solo la detección de patrones? Solo necesito algo que me diga "este es un ícono / botón" para poder tomar esa región en una instantánea.

[1] Uso SikuliX con Python para realizar acciones en patrones dados.

[2] Vi que esto se hace fácilmente usando cascadas OpenCV y Haar (en formato XML). Crear las cacadas de Haar requiere un poco de paciencia y habilidades.

Radu Enea
fuente

Respuestas:

7

Primero, eche un vistazo a la muestra squares.py proporcionada por OpenCV. Debería manejar una buena cantidad de tipos de botones con algunos ajustes.

Aquí está la salida que obtuve (con algunos ajustes) para su ejemplo de Calculadora: ingrese la descripción de la imagen aquí

Hice los siguientes ajustes a la aplicación de cuadrados:

Cambie este código (comenzando en la línea 84):

if(result.total == 4 and 
   abs(cv.ContourArea(result)) > 1000 and 
   cv.CheckContourConvexity(result)):

A esto:

if(result.total == 4 and 
   abs(cv.ContourArea(result)) < 1300 and 
   abs(cv.ContourArea(result)) > 300 and
   cv.CheckContourConvexity(result)):

Además, como no tiene que preocuparse por las variaciones de escala o rotación, consulte con matchTemplate . Además, su tutorial correspondiente (en C ++) está aquí .

Vea mi otra respuesta para otro ejemplo de cómo funciona la coincidencia de plantillas. Además, es posible encontrar esta respuesta útil para la detección de los partidos primeras X con matchTemplate.

¡Espero que ayude!

mevatron
fuente
Muchas gracias por tu respuesta. Probaré tu idea aunque estoy buscando algo que se pueda extender fuera de esta área de calculadora. Este enfoque sería genial para los botones cuadrados. No sé cómo se comportaría para detectar iconos en un escritorio de Windows (como mencioné en la explicación). Pero lo intentaré y se lo haré saber a todos. Gracias de nuevo
¿Qué tan flexible debe ser su programa? Cuanto más general es el problema que intentas resolver; cuanto más difícil sea lograr la solución.
Bueno, por el momento está bien si me quedo con los cuadrados. Tengo mayores problemas Como este (cuando ejecuto squares.py; ¿Alguna idea?): Traceback (última llamada más reciente): Archivo "squares.py", línea 144, en <module> on_trackbar (0) Archivo "squares.py", línea 126, en on_trackbar drawSquares (img, findSquares4 (img, storage)) Archivo "squares.py", línea 30, en findSquares4 pyr = cv.CreateImage (sz.width / 2, sz.height / 2, 8, 3) AttributeError : el objeto 'tupla' no tiene atributo 'ancho'
Radu Enea
Resuelto el problema anterior. Y después de mucha investigación, creo que tengo que reformular la pregunta.
Radu Enea