Busqueda Multiple es AND por default e incluí el OR
Browse files- app.py +10 -9
- conceptos_busqueda.py +8 -2
- herramientas.py +94 -1
- identificador.py +11 -3
app.py
CHANGED
@@ -50,21 +50,22 @@ async def echo_image(
|
|
50 |
|
51 |
@app.post(
|
52 |
"/identifica_documento/",
|
53 |
-
tags=["
|
54 |
summary="Reconocimiento Avanzado de Documentos")
|
55 |
async def procesa_documento(image: UploadFile = File(...)):
|
56 |
if not image.content_type.startswith("image/"):
|
57 |
return {"error": "El archivo no es una imagen"}
|
58 |
return await funciones.identifica_documento(image)
|
59 |
|
60 |
-
|
61 |
-
|
62 |
-
|
63 |
-
|
64 |
-
|
65 |
-
|
66 |
-
|
67 |
-
|
|
|
68 |
|
69 |
@app.post(
|
70 |
"/procesa_ine/",
|
|
|
50 |
|
51 |
@app.post(
|
52 |
"/identifica_documento/",
|
53 |
+
tags=["General"],
|
54 |
summary="Reconocimiento Avanzado de Documentos")
|
55 |
async def procesa_documento(image: UploadFile = File(...)):
|
56 |
if not image.content_type.startswith("image/"):
|
57 |
return {"error": "El archivo no es una imagen"}
|
58 |
return await funciones.identifica_documento(image)
|
59 |
|
60 |
+
#PROCESA CUALQUIER DOCUMENTO, ESTABA LISTO PARA DNI Y PASAPORTE PERO LE FALTA INE, SE REANUDA CADA QUE ESTÉ AL DÍA.
|
61 |
+
# @app.post(
|
62 |
+
# "/procesa_documento/",
|
63 |
+
# tags=["General"],
|
64 |
+
# summary="Reconocimiento Avanzado de Documentos")
|
65 |
+
# async def procesa_documento(image: UploadFile = File(...)):
|
66 |
+
# if not image.content_type.startswith("image/"):
|
67 |
+
# return {"error": "El archivo no es una imagen"}
|
68 |
+
# return await funciones.procesa_documento(image)
|
69 |
|
70 |
@app.post(
|
71 |
"/procesa_ine/",
|
conceptos_busqueda.py
CHANGED
@@ -1,7 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
dni = [
|
2 |
{'preferida': 'nombre', 'alternativas': ['noaigre']},
|
3 |
-
{'preferida': 'usual', 'alternativas': []
|
4 |
-
|
5 |
|
6 |
pasaporte = [
|
7 |
{'preferida': 'pasaporte', 'alternativas': ['passport']},
|
|
|
1 |
+
#Que documentos búsca el sistema actualmente.
|
2 |
+
documentos = ['dni', 'ine', 'pasaporte']
|
3 |
+
|
4 |
+
#Cada concepto de la lista de cada documento es un OR, es decir, bastará con que encuentre uno de los dos para dar...
|
5 |
+
#... por hecho que es esa clase de documento.
|
6 |
+
|
7 |
dni = [
|
8 |
{'preferida': 'nombre', 'alternativas': ['noaigre']},
|
9 |
+
{'preferida': 'usual', #'alternativas': []
|
10 |
+
}]
|
11 |
|
12 |
pasaporte = [
|
13 |
{'preferida': 'pasaporte', 'alternativas': ['passport']},
|
herramientas.py
CHANGED
@@ -64,7 +64,100 @@ def buscaIndexPalabra(arreglo, palabra):
|
|
64 |
return i
|
65 |
return None # Cambiado de 'error' a None
|
66 |
|
67 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
68 |
"""
|
69 |
Busca el índice de la primera línea que contiene todas las palabras requeridas (o sus alternativas)
|
70 |
y devuelve la línea con las alternativas corregidas a su forma preferida.
|
|
|
64 |
return i
|
65 |
return None # Cambiado de 'error' a None
|
66 |
|
67 |
+
import re
|
68 |
+
|
69 |
+
def buscaIndexMultiplesPalabras(arreglo_textos, conceptos_requeridos): #AND por default.
|
70 |
+
"""
|
71 |
+
Busca el índice de la primera línea que contiene todas las palabras requeridas (o sus alternativas)
|
72 |
+
y devuelve la línea con las alternativas corregidas a su forma preferida.
|
73 |
+
|
74 |
+
Args:
|
75 |
+
arreglo (list): Lista de strings de texto extraído (limpios).
|
76 |
+
conceptos_requeridos (list): Lista de diccionarios, donde cada diccionario define un concepto:
|
77 |
+
Ej: {'preferida': 'nacimiento', 'alternativas': ['nacimento', 'nacimuento']}
|
78 |
+
|
79 |
+
Returns:
|
80 |
+
tuple: (índice, arreglo_corregido) si se encuentra, o (None, None) si no se encuentra.
|
81 |
+
"""
|
82 |
+
print(f"\n--- Entre a busqueda palabras index ---")
|
83 |
+
|
84 |
+
# Paso 1: Normalizar los conceptos y prepararlos para la búsqueda y corrección
|
85 |
+
conceptos_preparados = []
|
86 |
+
for concepto in conceptos_requeridos:
|
87 |
+
print("Preparación de conceptos, estoy en el concepto: ", concepto)
|
88 |
+
preferida = concepto['preferida'].lower().replace(" ", "")
|
89 |
+
alternativas = [alt.lower().replace(" ", "") for alt in concepto.get('alternativas', [])]
|
90 |
+
|
91 |
+
# Combinamos la preferida con las alternativas para la búsqueda
|
92 |
+
todas_las_formas = [preferida] + alternativas
|
93 |
+
print("Todas las formas quedó como: ", todas_las_formas)
|
94 |
+
|
95 |
+
conceptos_preparados.append({
|
96 |
+
'preferida': preferida,
|
97 |
+
'todas_las_formas': todas_las_formas,
|
98 |
+
})
|
99 |
+
|
100 |
+
print("Conceptos preparados quedó como: ", conceptos_preparados)
|
101 |
+
|
102 |
+
for i, texto_linea in enumerate(arreglo_textos):
|
103 |
+
texto_linea_lower = texto_linea.lower()
|
104 |
+
print("Trabajando la línea: ", texto_linea_lower)
|
105 |
+
|
106 |
+
# Variables para seguir el rastro de la línea actual
|
107 |
+
es_coincidencia_completa = True # Asume que la coincidencia es completa al inicio de cada línea
|
108 |
+
print("La var es_coincidencia_completa empieza como true...")
|
109 |
+
palabras_encontradas_en_linea = {} # Almacena {forma_encontrada: forma_preferida}
|
110 |
+
|
111 |
+
# Paso 2: Verificar si TODAS las condiciones se cumplen en esta línea
|
112 |
+
for concepto in conceptos_preparados:
|
113 |
+
encontrado_en_este_concepto = False
|
114 |
+
print("Revisando CONCEPTO: ", concepto)
|
115 |
+
|
116 |
+
# Buscamos si alguna forma (preferida o alternativa) está en la línea
|
117 |
+
for forma in concepto['todas_las_formas']:
|
118 |
+
print("Evaluando la siguiente forma en el concepto: Forma: ", forma)
|
119 |
+
print(f"Ahora, si la forma --{forma}-- está en la línea: --{texto_linea_lower}--, entonces: ")
|
120 |
+
if forma in texto_linea_lower:
|
121 |
+
print(f"¡Encontrado! La forma '{forma}' está en la línea.")
|
122 |
+
encontrado_en_este_concepto = True
|
123 |
+
|
124 |
+
# Guardamos qué forma se encontró y cuál es la preferida
|
125 |
+
palabras_encontradas_en_linea[forma] = concepto['preferida']
|
126 |
+
|
127 |
+
print("Estoy por hacer break porque encontré la línea...")
|
128 |
+
# Hemos encontrado una forma para este concepto, pasamos al siguiente concepto
|
129 |
+
break # Este break sale del bucle interno, lo cual es correcto
|
130 |
+
|
131 |
+
# Si no se encontró ninguna forma para el concepto actual, esta línea no es una coincidencia
|
132 |
+
if not encontrado_en_este_concepto:
|
133 |
+
es_coincidencia_completa = False
|
134 |
+
print(f"Línea {i}: Concepto '{concepto['preferida']}' : No encontrado. ¡Fallo en esta línea!")
|
135 |
+
break # Este break sale del bucle principal de conceptos, lo cual es correcto
|
136 |
+
|
137 |
+
print("Paso: if es_coincidencia_completa:")
|
138 |
+
# Paso 3: Si se encontró una coincidencia completa, corregimos la línea y la retornamos
|
139 |
+
if es_coincidencia_completa:
|
140 |
+
print("Aquí llega cuando encuentra algo, en su línea respectiva.")
|
141 |
+
print(f"ÉXITO: Coincidencia completa en el índice {i}.")
|
142 |
+
print(f"Texto linea es: {texto_linea}")
|
143 |
+
|
144 |
+
linea_corregida = texto_linea
|
145 |
+
|
146 |
+
for forma_encontrada, forma_preferida in palabras_encontradas_en_linea.items():
|
147 |
+
patron_reemplazo = re.compile(re.escape(forma_encontrada), re.IGNORECASE)
|
148 |
+
linea_corregida = patron_reemplazo.sub(forma_preferida, linea_corregida, count=1)
|
149 |
+
|
150 |
+
print(f"Línea corregida: '{linea_corregida}'")
|
151 |
+
arreglo_textos[i] = linea_corregida
|
152 |
+
|
153 |
+
return i, arreglo_textos
|
154 |
+
|
155 |
+
print("Paso: Búsqueda finalizada.:")
|
156 |
+
print(f"\n--- Búsqueda finalizada ---")
|
157 |
+
print("Ninguna línea contiene todas las palabras requeridas.")
|
158 |
+
return None, None
|
159 |
+
|
160 |
+
def buscaIndexMultiplesPalabrasOR(arreglo_textos, conceptos_requeridos):
|
161 |
"""
|
162 |
Busca el índice de la primera línea que contiene todas las palabras requeridas (o sus alternativas)
|
163 |
y devuelve la línea con las alternativas corregidas a su forma preferida.
|
identificador.py
CHANGED
@@ -1,6 +1,8 @@
|
|
1 |
import herramientas
|
2 |
import conceptos_busqueda
|
3 |
import time
|
|
|
|
|
4 |
|
5 |
def identifica_documento(textos_extraidos_simplificados):
|
6 |
"""
|
@@ -12,12 +14,11 @@ def identifica_documento(textos_extraidos_simplificados):
|
|
12 |
Returns:
|
13 |
str: El nombre del primer documento encontrado ('dni', 'pasaporte', etc.),
|
14 |
o None si ninguno de los documentos fue identificado.
|
15 |
-
"""
|
16 |
-
print("Estoy en identifica documento...")
|
17 |
-
documentos = ['ine', 'dni', 'pasaporte']
|
18 |
|
19 |
for tipo_documento in documentos:
|
20 |
print("Revisando tipo de documento: ", tipo_documento)
|
|
|
21 |
|
22 |
# Usamos 'getattr' para acceder dinámicamente al atributo correcto
|
23 |
# del objeto 'conceptos_busqueda', como 'conceptos_busqueda.dni'.
|
@@ -32,13 +33,20 @@ def identifica_documento(textos_extraidos_simplificados):
|
|
32 |
# Si la búsqueda encuentra un resultado, salimos inmediatamente y retornamos
|
33 |
# el nombre del documento.
|
34 |
if indice is not None:
|
|
|
|
|
35 |
# Puedes retornar el tipo_documento y los textos corregidos
|
36 |
# return tipo_documento, textos_corregidos
|
37 |
|
38 |
# O simplemente el tipo de documento, como en tu ejemplo
|
39 |
return tipo_documento
|
|
|
|
|
|
|
40 |
|
41 |
# Si el bucle termina sin encontrar ningún documento, retornamos None
|
|
|
|
|
42 |
return None
|
43 |
|
44 |
def identifica_ine(textos_extraidos_simplificados):
|
|
|
1 |
import herramientas
|
2 |
import conceptos_busqueda
|
3 |
import time
|
4 |
+
from conceptos_busqueda import documentos as documentos
|
5 |
+
|
6 |
|
7 |
def identifica_documento(textos_extraidos_simplificados):
|
8 |
"""
|
|
|
14 |
Returns:
|
15 |
str: El nombre del primer documento encontrado ('dni', 'pasaporte', etc.),
|
16 |
o None si ninguno de los documentos fue identificado.
|
17 |
+
"""
|
|
|
|
|
18 |
|
19 |
for tipo_documento in documentos:
|
20 |
print("Revisando tipo de documento: ", tipo_documento)
|
21 |
+
time.sleep(3)
|
22 |
|
23 |
# Usamos 'getattr' para acceder dinámicamente al atributo correcto
|
24 |
# del objeto 'conceptos_busqueda', como 'conceptos_busqueda.dni'.
|
|
|
33 |
# Si la búsqueda encuentra un resultado, salimos inmediatamente y retornamos
|
34 |
# el nombre del documento.
|
35 |
if indice is not None:
|
36 |
+
print(f"No fue none, hizo su encuentro en el documento: ", tipo_documento)
|
37 |
+
time.sleep(7)
|
38 |
# Puedes retornar el tipo_documento y los textos corregidos
|
39 |
# return tipo_documento, textos_corregidos
|
40 |
|
41 |
# O simplemente el tipo de documento, como en tu ejemplo
|
42 |
return tipo_documento
|
43 |
+
|
44 |
+
print("Índice no fue None, continua la búsqueda...")
|
45 |
+
time.sleep(8)
|
46 |
|
47 |
# Si el bucle termina sin encontrar ningún documento, retornamos None
|
48 |
+
print("Se acabó la búsqueda y no encontró nada.")
|
49 |
+
time.sleep(4)
|
50 |
return None
|
51 |
|
52 |
def identifica_ine(textos_extraidos_simplificados):
|