CAPTCHA, caso especial: rompemos una red neuronal con treinta líneas de código

   No recuerdo cómo me encontré con el artículo habr.com/en/post/464337 , pero se hundió en mi cerebro y no dio descanso hasta el último día. Varias veces intenté entender lo que estaba sucediendo, un par de veces intenté que funcionara, pero fue en vano: no entiendo nada en redes neuronales e incluso programo como un programador real.
feliz captcha


   Finalmente, hace unos días, superé el lanzamiento de la pitón y decidí por qué no todo eso. Habiendo olvidado todo lo que leí en el artículo mencionado, seguí mi propio camino.
   Recordando la miríada de captchas resueltas, sugerí que puedes resolverlas mediante una comparación banal con la máscara, que luego se confirmó.
   Primero, ensambló manualmente el captcha de prueba (83 piezas) y les dio nombres obvios. El guión los convirtió en mapas de bits.

   Los números en el captcha son de dos tamaños de altura con una diferencia de 1 píxel y tres a cuatro caras de ancho. La línea base de todos los personajes en todos los captcha es la misma. Resultó que toda esta diversidad tiene una cierta máscara común, una comparación con la que identifica de forma única una figura. Corté varios (al principio - 5, luego agregué otros 1-2; con "4" tardó más que el resto) de los mismos números de diferentes captchas. En paint.net, los puse uno encima del otro y obtuve una máscara que es común a todas las caras de cada dígito.

   Descubrí el único problema más tarde, ya durante el procesamiento en masa, pero lo evité con éxito
con una muleta
   , — «1», «2» .. «9». , , «4», «4», «1». , -, «123456789» «423156789» -, «4» , «1».

   Además de este pequeño malentendido, el ruido no interfiere en absoluto. El resultado de esta etapa fue un conjunto de 9 máscaras. ¡Dos bucles anidados y listo! - ¡Todas mis 83 captchas son reconocidas con una explosión!

   

   Entonces surgió la pregunta: dónde obtener un gran conjunto de captcha para la verificación. Y descargué "29,000 captcha" del artículo mencionado.
Sin embargo, esto resultó ser una pérdida de tiempo.
   - (, -, .. ), : : 6503 , 5420 , 760 .. – .. 14882, , , .
-, – -, – . PNG, – JPG, , . , – «”” ».

   Así que tuve que descubrir Google y extraer el captcha perfecto por mi cuenta: se acumularon 3224 archivos por noche, incluidos 49 completamente vacíos, como resultó más tarde. Gracias Ganesha por el código .

   En realidad, el reconocimiento de captcha se ajusta a 26 líneas de código aburrido de Python. De los módulos externos solo se necesita PIL. La velocidad es de aproximadamente 1000 captcha por minuto (mil captcha por minuto) en el antiguo Core 2 "cuatro núcleos cuatro conciertos". En un i5 de ocho transmisiones más decente es notablemente más rápido, aunque el asunto, por supuesto, no está en los hilos. Reconocimiento del 100% o muy cercano a eso: la verificación al azar no mostró errores.

   Por supuesto, todo esto no es interesante en el sentido de las redes neuronales y otras cadenas de bloques, pero tiene una ventaja muy clara sobre la opción propuesta anteriormente: velocidad y precisión. También es cierto que cualquier cambio en los parámetros del captcha - auriculares o tamaño de fuente, tipo de ruido, etc. - conducirá a la inoperancia completa de mi decisión.

Descargue el archivo con captcha de Yandex.Disk (14MB).

Fuente
from PIL import Image, ImageTk

def recognize(filepath):
  Zlist = [] # [(x1, z1), (x2, z2), (x3, z3), etc.] - position and digit
  captcha = ""
  originalimage = Image.open(filepath).convert('L').point(lambda x : 255 if x > 20 else 0, mode='1').convert('1').convert('RGBA')
  if originalimage.getextrema() == ((0, 0), (0, 0), (0, 0), (255, 255)):
    return("empty image")
  for z in [4, 2, 3, 1, 5, 6, 7, 8, 9]: # reorder to exclude false 1 on 4
    mask = Image.open('mask' + str(z) + '.png').convert('RGBA')
    previ = 0
    for i in range(15, 120): # no digit in left part
      resultimage = Image.alpha_composite(originalimage.crop((i, 0, i + 30, 0 + 50)), mask)
      if resultimage.getextrema() == ((0, 0), (0, 0), (0, 0), (255, 255)):
        if z == 4: # delete 4 to exclude false 1 on 4
          maskx = Image.open('mask4x.png').convert('RGBA') 
          originalimage.paste(Image.alpha_composite(originalimage.crop((i, 0, i + 30, 0 + 50)), maskx), (i, 0))
        if previ == 0 or i > previ + 15: #no digit closer then 15 px
          Zlist.append((i, z))
          if len(Zlist) == 5:
              Zlist.sort()
              for z in Zlist:
                captcha = captcha + str(z[1])
              return(captcha)
          previ = i
          i = i + 15 #skip a little
  Zlist.sort()
  return(str(Zlist)) #if less then 5 digits recognized
	
def main():
  captcha = recognize(entry.path)
#----------------------------------------------#
#          #
#----------------------------------------------#

main()




Actualización a partir del 13 de febrero de 2020.
   ¿De qué se trataba todo esto? ¿No por el reconocimiento deportivo de las imágenes guardadas? No, todo esto fue puramente para fines pragmáticos.
   Solución lista para el trabajo. - Servidor de reconocimiento http local más extensión para Chrome.
   Hasta ahora, lo único que puede hacerlo (espero que pueda) es insertar automáticamente el captcha en el lugar correcto. Los planes:
  - limpiar la interfaz del sitio, dejando el mínimo necesario;
  - automatizar la actualización de captcha al ver información, como Un captcha permite abrir solo 4 objetos.
  - Descargue todas las declaraciones preparadas a la vez, y no una a la vez.

Actualización a partir del 5 de marzo de 2020.
   Solución lista para el trabajo.- Servidor de reconocimiento http local más extensión para Chrome.
   Se actualizó la extensión para Chrome. Ahora es capaz, además de la sustitución automática de captcha,
 1. al abrir páginas con información sobre objetos inmobiliarios, ampliar información sobre derechos;
 2. Recopile información de estas páginas para su posterior procesamiento.
   Captura de pantalla en el comentario habr.com/post/488018/#comment_21360646

Actualización a partir del 17 de abril de 2020 .
   Bot para ordenar declaraciones de la lista , debido a la restricción en la frecuencia de las declaraciones de pedidos: 1 declaración en 5 minutos. Captura de pantalla en comentario

All Articles