File size: 8,717 Bytes
e0b339d d35e97b d56556d e0b339d fda1a93 e0b339d b226794 e0b339d 2e0d094 e0b339d d56556d e0b339d d56556d 93a5ed3 d56556d b226794 d56556d b226794 d56556d b226794 d56556d b226794 d56556d 2e0d094 d56556d b226794 d56556d b226794 d56556d b226794 d56556d 2e0d094 b226794 e0b339d b226794 e0b339d d35e97b b226794 fda1a93 b226794 d56556d 2e0d094 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 |
import tempfile
import time
from gradio_client import Client, handle_file
import re
async def imageToTemp(image):
try:
with tempfile.NamedTemporaryFile(delete=False, suffix=f"_{image.filename}") as tmp_file:
contents = await image.read()
tmp_file.write(contents)
temp_file_path = tmp_file.name
print(f"Archivo temporal guardado en: {temp_file_path}")
return temp_file_path
except Exception as e:
print(f"Error al procesar la imagen: {e}")
return {"error": "Error al procesar la imagen"}
def listaTextosExtraidos(dict_recibido):
result = dict_recibido['data']
print("Datos extraídos (acceso directo):")
textos_extraidos = []
for item in result:
texto = item[1][0]
print(texto)
textos_extraidos.append(texto)
return textos_extraidos
def simplificaTextos(textos_extraidos):
textos_extraidos_simplificados = [texto.lower().replace(" ", "") for texto in textos_extraidos]
print("Textos extraídos simplificados:")
print(textos_extraidos_simplificados)
return textos_extraidos_simplificados
#Herramientas para DNI Panamá.
def buscaIndexPalabra(arreglo, palabra):
palabra_limpia = palabra.lower().replace(" ", "")
for i, texto_limpio in enumerate(arreglo):
if palabra_limpia in texto_limpio:
return i
return None # Cambiado de 'error' a None
def buscaIndexMultiplesPalabras(arreglo_textos, conceptos_requeridos):
"""
Busca el índice de la primera línea que contiene todas las palabras requeridas (o sus alternativas)
y devuelve la línea con las alternativas corregidas a su forma preferida.
Args:
arreglo (list): Lista de strings de texto extraído (limpios).
conceptos_requeridos (list): Lista de diccionarios, donde cada diccionario define un concepto:
Ej: {'preferida': 'nacimiento', 'alternativas': ['nacimento', 'nacimuento']}
Returns:
tuple: (índice, línea_corregida) si se encuentra, o (None, None) si no se encuentra.
"""
print(f"\n--- Iniciando búsqueda y corrección ---")
# Paso 1: Normalizar los conceptos y prepararlos para la búsqueda y corrección
conceptos_preparados = []
for concepto in conceptos_requeridos:
preferida = concepto['preferida'].lower().replace(" ", "")
alternativas = [alt.lower().replace(" ", "") for alt in concepto.get('alternativas', [])]
# Combinamos la preferida con las alternativas para la búsqueda
todas_las_formas = [preferida] + alternativas
conceptos_preparados.append({
'preferida': preferida,
'todas_las_formas': todas_las_formas,
'alternativas': alternativas # Solo las alternativas para saber cuáles corregir
})
for i, texto_linea in enumerate(arreglo_textos):
texto_linea_lower = texto_linea.lower()
# Variables para seguir el rastro de la línea actual
es_coincidencia_completa = True
palabras_encontradas_en_linea = {} # Almacena {forma_encontrada: forma_preferida}
# Paso 2: Verificar si TODAS las condiciones se cumplen en esta línea
for concepto in conceptos_preparados:
encontrado_en_esta_linea = False
# Buscamos si alguna forma (preferida o alternativa) está en la línea
for forma in concepto['todas_las_formas']:
if forma in texto_linea_lower:
encontrado_en_esta_linea = True
# Guardamos qué forma se encontró y cuál es la preferida
palabras_encontradas_en_linea[forma] = concepto['preferida']
# Hemos encontrado una forma para este concepto, pasamos al siguiente concepto
break
if not encontrado_en_esta_linea:
es_coincidencia_completa = False
print(f"Fallo en línea {i}: No se encontró el concepto '{concepto['preferida']}' ni sus alternativas.")
break # Si falta un concepto, pasamos a la siguiente línea del arreglo
# Paso 3: Si se encontró una coincidencia completa, corregimos la línea y la retornamos
if es_coincidencia_completa:
print(f"ÉXITO: Coincidencia completa en el índice {i}.")
print(f"Texto linea es: {texto_linea}")
linea_corregida = texto_linea
for forma_encontrada, forma_preferida in palabras_encontradas_en_linea.items():
# Nota: Esta corrección simple asume que la palabra encontrada está exactamente igual que en la lista de alternativas (minusculas y sin espacios)
# Para un OCR más variable, necesitarías una lógica de reemplazo más avanzada (ej. re.sub),
# pero para tu caso de "nacimento" a "nacimiento" esto funciona si la palabra se encuentra exactamente.
# Usamos re.sub para reemplazar la palabra encontrada con la preferida, insensible a mayúsculas/minúsculas
# (re.escape para manejar caracteres especiales si los hubiera)
patron_reemplazo = re.compile(re.escape(forma_encontrada), re.IGNORECASE)
# Reemplazamos la palabra encontrada en la línea original con la forma preferida
linea_corregida = patron_reemplazo.sub(forma_preferida, linea_corregida, count=1)
print(f"Línea corregida: '{linea_corregida}'")
# Ahora corregimos la línea original usando la información de las palabras encontradas
arreglo_textos[i] = linea_corregida
return i, arreglo_textos
print(f"\n--- Búsqueda finalizada ---")
print("Ninguna línea contiene todas las palabras requeridas.")
return None, None
########################################################################
def buscarPatronCedula(lista_textos):
for i, texto in enumerate(lista_textos):
if texto and texto[0].isdigit() and '-' in texto:
return i
return 'error'
async def procesaImagen(image):
try:
temp_image = await imageToTemp(image)
client = Client("BuzzwordMx/ai_ocr")
dict_recibido = client.predict(
img=handle_file(temp_image),
lang="en",
api_name="/predict"
)
#Aquí es donde personalizo el proceso:
textos_extraidos = listaTextosExtraidos(dict_recibido)
return textos_extraidos
except Exception as e:
print(f"Error al procesar el archivo: {e}")
return 'Error'
def obtener_fecha(texto):
# El patrón busca:
# - "FECHADENACIMIENTO" (insensible a mayúsculas/minúsculas)
# - Seguido opcionalmente de CERO o MÁS caracteres que NO SEAN UN DÍGITO (lo que inicia la fecha).
# Esto cubrirá ':', '.', espacios, o cualquier otro carácter de separación.
# - Captura el patrón de fecha: \d{1,2}-[A-Za-z0-9]{3}-\d{4}
patron = r"FECHADENACIMIENTO[^\d]*(\d{1,2}-[A-Za-z0-9]{3}-\d{4})"
match = re.search(patron, texto, re.IGNORECASE)
fecha_encontrada = None
if match:
fecha_encontrada = match.group(1)
if fecha_encontrada:
partes_fecha = fecha_encontrada.split('-')
if len(partes_fecha) == 3:
dia = partes_fecha[0]
mes = partes_fecha[1].lower() # Convierte el mes a minúsculas
año = partes_fecha[2]
return f"{dia}-{mes}-{año}"
else:
# Esto se ejecutaría si el formato de la fecha extraída no es el esperado (ej. 2 partes)
return fecha_encontrada
return None # Si no se encontró el patrón de fecha
def obtener_sexo(texto):
# El patrón ahora busca "Sexo" O "Seno" (insensible a mayúsculas/minúsculas)
# Seguido opcionalmente de un ":"
# Seguido opcionalmente de espacios en blanco
# Captura la siguiente letra
patron = r"(Sexo|Seno):?\s*([A-Za-z])"
# re.search busca la primera ocurrencia del patrón en el texto
# re.IGNORECASE hace que la búsqueda sea insensible a mayúsculas/minúsculas para "Sexo" y "Seno"
match = re.search(patron, texto, re.IGNORECASE)
if match:
# match.group(2) devuelve lo que se capturó en el SEGUNDO grupo de paréntesis,
# que es la letra del sexo/seno. match.group(1) sería "Sexo" o "Seno".
return match.group(2)
else:
return None |