- MATLAB 60.6%
- Python 39.4%
| .idea | ||
| marcadores | ||
| matlab | ||
| tests | ||
| arti.py | ||
| basic_functions.py | ||
| computations.py | ||
| eppa.py | ||
| gai.py | ||
| gai2.py | ||
| input.csv | ||
| main.py | ||
| output.csv | ||
| output_filled.csv | ||
| README.md | ||
README: Migración de Matlab a Python / EPPA Postural API
Este proyecto es una reingeniería de la aplicación original de Matlab (que medía y diagnosticaba postura) hacia un sistema en Python que expone una API para que un frontend u otros servicios accedan a los mismos cálculos.
A continuación se detalla:
- Resumen de la Migración
- Estructura del Proyecto
- Endpoints Explicados
- Lanzar la Aplicación
- Ejecutar los Tests
- Principales Diferencias vs. MATLAB
- Umbrales (Thresholds) por Defecto
- Consideraciones Finales
1. Resumen de la Migración
En la versión de Matlab, se tenían varios scripts y Callbacks de interfaz (“TagCabeza”, “TagTroncoColumna”, “TagAnguloCalcaneo”, etc.) que:
- Capturaban marcadores en imágenes (con
ginputy.matguardados). - Calculaban distancias y ángulos, aplicando un umbral:
- 2° para decidir si la inclinación angular es “neutra” o “derecha/izquierda”.
- 1 cm para decidir si la diferencia lineal es “neutra” o “asimétrica”.
- Exportaban resultados a Excel y mostraban diagnósticos (derecha/izquierda, antepulsión/retropulsión, genu varo/valgo, etc.).
En este proyecto, esa lógica se pasa a Python con FastAPI. Ahora, cada cálculo (calcáneo, tronco, pelvis…) es un endpoint al cual se le puede enviar un JSON con los marcadores ("markers") y otros parámetros ("p1x", "fc", "side", etc.). La API devuelve un JSON con el diagnóstico, distancias y ángulos equivalentes.
2. Estructura del Proyecto
my_project/
├── main.py # API principal en FastAPI
├── computations.py # (Opcional) Funciones de cálculo real
├── basic_functions.py # calibrate_grid, import_markers, etc.
├── tests/
│ └── test_api.py # Suite de tests con unittest
├── README.md # Este documento
└── requirements.txt # Dependencias (fastapi, pydantic, etc.)
main.py: expone todos los endpoints que simulan la lógica de Matlab (inclinación cabeza, ángulo calcáneo, calibración de grilla, etc.).test_api.py: tests automáticos que llaman a cada endpoint (igual que la interfaz original).computations.py(si se usa): tendría funciones reales para “compute_angulo_calcaneo(...)”, etc.basic_functions.py: “import_markers(...)”, “calibrate_grid(...)”, etc.
3. Endpoints Explicados
/uploadMarkers(POST)- Permite subir un archivo
.mat(simulación). En Matlab se hacíaload(filename.mat).
- Permite subir un archivo
/calibrateGrid(POST)- Recibe query params
x1, y1, x2, y2, known_distance. - Devuelve
factor_calibracion = known_distance / distancia_pixeles. - Equivalente a
TagCalibracionGrilla_Callbacken Matlab.
- Recibe query params
/computeAnguloCalcaneo- Simula
TagAnguloCalcaneo_Callback. - Usa
threshold = 2.0°para ángulos por defecto.
- Simula
/computeAnguloRodillaPerfil,/computeAnguloTibioTarsiano, etc.- Manejan las lógicas de umbrales 2° en rodillas, tibias, etc.
/computeCabezaSagital,/computeInclinacionCabezaFrontal- Umbral de 2° (o 1 cm, según se definía en Matlab).
/computeCinturaEscapular,/computeHombroMsuperiorFrontal- Habitualmente con threshold=1 cm para definir asimetría.
/computePelvisMiembroInferiorFrontal,/computePelvisMiembroInferiorEspalda- Genu varo/valgo, si distCondilos > 1 cm => “valgo”.
/computeTroncoColumnaFrontal,/computeTroncoColumnaPosterior,/computeTroncoSacroSagital- offsets > 1 cm => “derecha”/“izquierda”.
- ángulos > 2° => “no alineado”.
Cada endpoint recibe un JSON del tipo:
{
"markers": {
"NombreMarcador": [x, y],
"OtroMarcador": [x2, y2]
},
"p1x": 100,
"fc": 1.0,
"side": "Der",
"threshold": 2.0
}
Si threshold no se envía, se aplican los valores por defecto descritos abajo.
4. Lanzar la Aplicación
Primero, instala las dependencias (FastAPI, pydantic, etc.):
pip install -r requirements.txt
o manualmente:
pip install fastapi uvicorn pydantic
Luego, en la carpeta raíz (my_project/), ejecuta:
uvicorn main:app --reload
main:appes la ruta de la instancia de FastAPI.--reloadrecarga en caliente cada vez que cambies el código.
Ahora la API corre en http://127.0.0.1:8000.
5. Ejecutar los Tests
Para correr los tests (definidos en tests/test_api.py):
python -m unittest tests/test_api.py
- Cada test llama un endpoint con
requests.post(...). - Se imprime la llamada cURL sin escapes (
ensure_ascii=False) y la respuesta JSON en una sola línea. - Debería devolver
200 OKsi el endpoint coincide con la firma esperada.
6. Principales Diferencias vs. MATLAB
- Interfaz:
- En Matlab, se usaban GUIs (GUIDE) con callbacks y
ginput. - En Python, tenemos endpoints HTTP y no hay interfaz gráfica. El frontend puede ser React/Vue/etc.
- En Matlab, se usaban GUIs (GUIDE) con callbacks y
- Persistencia:
- En Matlab, se guardaba
handles.vector=cell_resyMarcadores_ID_xxx.mat. - En Python, se puede subir
.mata un endpoint (/uploadMarkers) o parsear enimport_markers(...).
- En Matlab, se guardaba
- Umbrales:
- Matlab: 2° en ángulos, 1 cm en distancias.
- Python: se definen en modelos Pydantic, con defaults. El frontend puede overridear.
- Cálculo:
- Se replican fórmulas (
sqrt((X1-X2)^2 + (Y1-Y2)^2)) oangle(...). - FastAPI en Python en vez de scripts/funciones
.m.
- Se replican fórmulas (
7. Umbrales (Thresholds) por Defecto
- Ángulos:
threshold = 2.0grados.- Si
\lvert \text{angle} \rvert \le 2⇒ neutro, si >2 ⇒ desplazado/varia.
- Si
- Distancias:
threshold = 1.0cm.- Si
\lvert \text{dist} \rvert \le 1⇒ neutro, si >1 ⇒ asimétrico, genu valgo, etc.
- Si
Esto es igual que en el MATLAB original.
8. Consideraciones Finales
- El código aquí es un prototipo: en producción, normalmente se aísla la lógica de test/ejemplo fuera de
main.py. - Falta terminar de pasar cálculos reales (ej.
compute_angulo_calcaneo(...)) en vez de los valores “dummy” que se devuelven en cada endpoint. - La API resultante expone la misma lógica que se usaba en Matlab, con la ventaja de ser “consumible” por un frontend (React, Angular, etc.) y de permitir tests automáticos.