Sistema de reconocimiento de escritura manuscrita con Deep Learning
Reconoce caracteres, palabras y frases escritas a mano usando redes neuronales convolucionales (CNN) y recurrentes (CRNN)
######### ATENCIÓN: ESTO ES SOLO UNA PRIMERA VERSIÓN HABRÁ FALLO SEGURO
- Reconocimiento de caracteres individuales (A-Z, a-z, 0-9) con 95%+ de precisión
- Procesamiento de palabras completas usando arquitectura CRNN
- Interfaz gráfica intuitiva con Gradio
- API lista para producción con TensorFlow Serving
- Sistema de logging profesional para monitoreo
- Contenerizado con Docker para fácil despliegue
handwriting-recognition/
├── app/ # Interfaz gráfica
├── data_preprocessing/ # Procesamiento de imágenes
├── inference/ # Lógica de predicción
├── model/ # Arquitecturas y entrenamiento
├── tests/ # Pruebas unitarias
├── logs/ # Logs de ejecución
├── saved_models/ # Modelos entrenados
├── Dockerfile # Configuración de contenedor
├── requirements.txt # Dependencias
├── config.py # Configuración global
└── main.py # Punto de entrada
- Python 3.9+
- TensorFlow 2.x
- GPU (recomendado para entrenamiento)
# Clonar repositorio
git clone https://github.com/tu-usuario/handwriting-recognition.git
cd handwriting-recognition
# Instalar dependencias
pip install -r requirements.txt
# Descargar datasets (opcional)
python -c "import tensorflow_datasets as tfds; tfds.load('emnist/letters')"
python main.py --train
Ejemplo de salida:
[INFO] 2024-02-20 10:15:23 — model.train — Iniciando entrenamiento
[DEBUG] 2024-02-20 10:15:25 — data_preprocessing — Procesando 814,255 muestras
Epoch 1/15 - Loss: 1.2456 - Accuracy: 0.6321
...
[INFO] 2024-02-20 11:30:45 — model.train — Modelo guardado en saved_models/cnn_model.h5
python main.py --gui
Reconoce caracteres dibujados en tiempo real
from inference.predict import HandwritingRecognizer
recognizer = HandwritingRecognizer()
image = cv2.imread("muestra.png")
print(recognizer.predict_char(image)) # Output: 'A'
# Construir imagen
docker build -t handwriting-api .
# Ejecutar servicio
docker run -p 8501:8501 handwriting-api
Endpoint POST /predict
acepta imágenes multipart
# Ejecutar todas las pruebas
pytest --cov=.
# Pruebas específicas
pytest tests/model/test_train.py -v
Dataset | Precisión | Tiempo Inferencia |
---|---|---|
EMNIST | 95.2% | 12ms |
IAM | 89.7% | 45ms |
- Haz fork del proyecto
- Crea tu rama (
git checkout -b feature/nueva-funcionalidad
) - Haz commit de tus cambios (
git commit -m 'Add some feature'
) - Haz push a la rama (
git push origin feature/nueva-funcionalidad
) - Abre un Pull Request
Nota: Para uso comercial o en producción, considerar:
- Añadir autenticación a la API
- Implementar sistema de colas para procesamiento por lotes
- Configurar monitoreo con Prometheus/Grafana
pip install pyinstaller
# cli.py (nuevo archivo)
import argparse
from main import main
if __name__ == "__main__":
parser = argparse.ArgumentParser()
parser.add_argument('--train', action='store_true')
parser.add_argument('--gui', action='store_true')
args = parser.parse_args()
main(args) # Modifica main.py para aceptar args en lugar de parsear
# main.py (actualizado)
def main(args):
if args.train:
# Lógica de entrenamiento...
if args.gui:
# Lógica de interfaz...
# build.spec
block_cipher = None
a = Analysis(
['cli.py'],
pathex=[],
binaries=[],
datas=[
('config.py', '.'),
('data_preprocessing/*.py', 'data_preprocessing'),
('model/*.py', 'model'),
('inference/*.py', 'inference'),
('app/*.py', 'app'),
('logs', 'logs') # Si necesitas mantener la estructura de logs
],
hiddenimports=[
'tensorflow',
'tensorflow_datasets',
'cv2',
'gradio'
],
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='HandwritingRecognition',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=True, # Cambiar a False para ocultar la consola en Windows
icon='icon.ico' # Añade un archivo .ico si quieres un icono personalizado
)
pyinstaller --onefile --windowed --add-data "config.py;." --add-data "data_preprocessing/*;data_preprocessing" --add-data "model/*;model" --add-data "inference/*;inference" --add-data "app/*;app" --hidden-import tensorflow --hidden-import tensorflow_datasets cli.py
# Añade esto al comando anterior
--add-data "saved_models/*;saved_models"
Problema con TensorFlow:
# Añade esto al inicio de cli.py
import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2' # Reduce mensajes de TensorFlow
Archivos estáticos adicionales:
Crea un archivo hooks/hook-tensorflow.py
:
from PyInstaller.utils.hooks import collect_all
datas, binaries, hiddenimports = collect_all('tensorflow')
pyinstaller \
--onefile \
--noconsole \
--add-data "config.py:." \
--add-data "data_preprocessing/*.py:data_preprocessing" \
--add-data "model/*.py:model" \
--add-data "inference/*.py:inference" \
--add-data "app/*.py:app" \
--add-data "saved_models/*:saved_models" \
--hidden-import tensorflow \
--hidden-import tensorflow_datasets \
--hidden-import cv2 \
--hidden-import gradio \
--icon=assets/icon.ico \
--name HandwritingRecognition \
cli.py
dist/
└── HandwritingRecognition # (o .exe en Windows)
├── cli.exe
├── config.py
├── data_preprocessing/
├── model/
├── inference/
├── app/
└── saved_models/
- Usa NSIS (Nullsoft Scriptable Install System)
- Crea un script
.nsi
:
!include "MUI2.nsh"
Name "Handwriting Recognition"
OutFile "HandwritingRecognition_Installer.exe"
InstallDir "$PROGRAMFILES\HandwritingRecognition"
!insertmacro MUI_PAGE_DIRECTORY
!insertmacro MUI_PAGE_INSTFILES
Section
SetOutPath $INSTDIR
File /r "dist\HandwritingRecognition\*"
CreateShortCut "$SMPROGRAMS\Handwriting Recognition.lnk" "$INSTDIR\cli.exe"
SectionEnd
- Tamaño del ejecutable: Puede superar los 100MB debido a TensorFlow
- Requisitos del sistema: Asegúrate de incluir en la documentación:
Requiere: - CPU con soporte AVX (para TensorFlow) - NVIDIA GPU con CUDA 11.2+ (opcional para aceleración)
- Alternativa para reducir tamaño: Usa TensorFlow Lite:
converter = tf.lite.TFLiteConverter.from_keras_model(model) tflite_model = converter.convert() open("model.tflite", "wb").write(tflite_model)
# Para entrenamiento
HandwritingRecognition --train
# Para interfaz gráfica
HandwritingRecognition --gui