# Tecnologías multimedia e interacción/Curso 2015-2016: Caso 4
## Introducción: Segmentación 3D de Resonancias Magnéticas Craneales

En la actualidad las resonancias magnéticas se almacenan digitalmente en diferentes formatos. A medida que se ha ido investigando en el campo del aprendizaje automático ha quedado patente el valor de la información en el ámbito médico para la deducción de nueva información.
En este proyecto, tratamos de aprender un modelo de reconocimiento de patrones en imágenes médicas de cara a la etiquetación automática de tejidos en resonancias magnéticas craneales. Existen numerosos estudios sobre el tema en cuestión, nosotros queremos aportar una nueva visión del problema además de una herramienta de visualización 3D de las imágenes generadas para evaluar los errores y estudiar posibles mejoras en el algoritmo de aprendizaje.
Esta herramienta viene motivada por lo abstracto que resultan las RMI en crudo, siendo solo legibles por el ojo experto del médico. Generando modelos de este tipo de imágenes, sencillos y legibles para el ordenador, computar este tipo de información sería más sencillo.

## Segmentación y algoritmos de aprendizaje
### Definición del problema y Retos

Esta primera parte del proyecto tiene como objetivo crear un programa, que haciendo uso de aprendizaje automático, sea capaz de determinar las distintas partes del cerebro usando imágenes de resonancias magnéticas craneales.
Se usan como datos de entrenamiento resonancias con las distintas partes del cerebro ya etiquetadas, y como datos de test se usan este mismo tipo de imágenes pero sin información etiquetada. La salida debe ser una representación matricial de las imágenes de test recibidas ya con las partes del cerebro etiquetadas, representadas de tal manera que las siguientes partes del proyecto puedan usar esta representación y las etiquetas para modelar un cerebro 3D coloreado según sus distintas secciones.
Esta primera parte presenta ciertos retos:
* Algoritmo de aprendizaje automático a usar.
* Determinar cuántos datos usar para entrenamiento y test.
* Ajustar la representación de la imagen al formato de entrada del algoritmo de aprendizaje y optimizarla para que el programa mantenga un equilibrio entre tiempo de ejecución y memoria usada. Hay que conseguir que se ejecute en tiempo razonable sin usar tanta memoria como para desbordarla.
Disponemos de antecedentes en proyectos de este tipo que nos permitieron dar un enfoque inicial a estos retos. Ya se realizó un proyecto de aprendizaje usando resonancias magnéticas aplicando distintos enfoques, aunque en este caso las imágenes eran 2D, y en este se tratan conjuntos de imágenes que forman un modelo 3D, por lo que la complejidad aumenta.

### Tratamiento inicial

El primer paso fue tratar la imagen para desechar información innecesaria. Una gran parte de la imagen es un fondo negro que resulta innecesario. El problema principal es que el fondo negro no ocupa siempre la misma posición en todas las imágenes. Para solucionarlo, se superponen las imágenes y a partir de esta superposición se averigua cuál es el fondo común a todas las imágenes, y así se evita recortar datos que sean importantes. Con esta superposición se genera un máscara, y se pasan las imágenes por esta máscara para quitar el fondo y quedarnos con los datos de entrenamiento útiles. Esto redujo en el orden de miles los píxeles usados.
El segundo paso es definir una instancia que los algoritmos de aprendizaje puedan recibir. En este caso, por cada píxel se agrupa información de varios de sus píxeles adyacentes en una sola unidad. Como varias imágenes representan distintas secciones del mismo cerebro, los píxeles no solo están relacionados con otros píxeles de la misma sección si no también con otros de distintas secciones, luego se debe trabajar con volúmenes y no con áreas. Lo necesario es definir cuántos píxeles se consideran adyacentes a otro (3x3x3, 4x4x4, 5x5x5, etc).
Una vez conseguido esto, se procede a probar distintos algoritmos de aprendizaje.

### Redes neuronales

Lo primero que se intentó fueron redes neuronales, aplicándolas de distintas maneras:
* Aplicar una red neuronal por cada pixel. Está entrenada con información de los píxeles adyacentes en 3D, es decir información del vóxel completo. Esta aproximación resulta en un mal tratamiento de la memoria, y acaba desbordando.
* Aplicar una red neuronal por intervalos en función de los valores del eje X. Es decir, si el máximo valor que puede alcanzar X es 300, entonces 300 dividido entre el número de intervalos que se ha decidido tener da como resultado el número de redes que se han aplicado. Al igual que antes, desborda por un mal tratamiento de la memoria.
* Debido a los fallos de memoria, se trató de reducir el número de datos de entrenamiento. Se trató de encontrar una manera de reducir a la mitad los datos de entrenamiento, y usar las redes neuronales entrenadas de las filas adyacentes a los píxeles no entrenados para deducir sus valores. Esta deducción se realizaba mediante un proceso de votación de las filas adyacentes a los píxeles no entrenados. Esta aproximación fue la que mejor resultados dio en cuanto a uso de memoria, llegando a procesar un 78% de los datos antes de desbordar la memoria.

### Árboles de decisión

Lo segundo fue usar árboles de decisión Ejemplo. Para esto, se usó la librería ADABOOST, que proporciona un mecanismo de aceleración para algoritmos de aprendizaje. Lo que se hace es definir pequeños predictores no muy fiables pero rápidos, que solos no producen buenas soluciones pero comunicándose entre ellos consiguen resultados muy competitivos. La idea es alcanzar un equilibrio entre el número de predictores usados y el error de la predicción. Se ha seguido una aproximación similar a la usada con redes neuronales, y se dividen los datos de entrenamientos en distintos fragmentos. Es importante controlar el número de instancias que forman parte del entrenamiento de cada predictor, en particular en el caso que nos ocupa, ya que se disponen de pocos ejemplos de entrenamiento y es importante generalizar la máxima información posible de cada ejemplo de tal manera que tampoco desborde la memoria.
El principal reto es encontrar un equilibrio entre el número de fragmentos y el número de predictores usados:
* Si se aumenta el número de fragmentos, se disminuye el tamaño en disco de cada predictor, y en el peor de los casos se consigue aumentar la generalización al disminuir el número de instancias de entrenamiento.
* Si se disminuye el número de fragmentos, se aumenta el tamaño en disco de cada predictor, y en el peor de los casos la dificultad de encontrar un espacio en el que las instancias se puedan separar aumenta.
* Si se aumenta el número de predictores, no aumenta el tamaño en disco (se hace un proceso de limpieza al finalizar el entrenamiento), pero sí se aumenta el tiempo de entrenamiento. En el peor de los casos donde el número de predictores válidos es muy alto, aumenta el tiempo de predicción de cada pixel.
* Si se disminuye el número de predictores, disminuye el tiempo de entrenamiento y en el peor de los casos se aumenta el error en la predicción, ya se suele requerir un número de predictores muy grande.

## Representación 3D

Una vez se ha conseguido etiquetar las distintas secciones cerebrales MRI, se quiere conseguir una representación cerebral 3D completa de estas secciones juntas. Este modelo 3D debe representar las distintas partes del cerebro con distintos colores, usando las etiquetas conseguidas en la primera parte del proyecto. Son muchos los ejemplos que encontrados en Internet que tratan acerca de la visualización de resonancias magnéticas, pero muchos de ellos se quedan en la generación de un modelo artificial de cráneo y otros discretizan el alcance del proyecto a una mera representación en 2D.

### Lectura de datos

La lectura de los datos iniciales se realiza mediante un archivo descriptor de la imagen NIFTI en formato XML con las etiquetas y sus píxeles asociados.

### Representación en 3D

El actual proyecto ha consistido en la realización de un workspace de visualización de RMI's. Los resultados que se han obtenido dan pie a pensar que es un campo que permite un amplio abanico de posibilidades en cuanto a mejoras. En primer momento, nos hemos centrado en la generación de modelos 3D a base de secuencias de imágenes en 2 dimensiones. Se ha hecho uso de JMonkey como procesador de gráficos. En la realización de esta primera parte hemos visto que no tenemos suficiente información o suficientes imágenes para que el modelo generado no parezca artificial. Una alternativa podría ser aplicar algún tipo de suavizado.
En segundo momento, hemos añadido más funcionalidad y otras vistas a la aplicación. Las vistas que se han añadido son las vistas sagital, cenital y frontal. Y en cuanto a la funcionalidad, se han añadido métodos para la navegación 2D y 3D.
Se ha hecho uso de varias librerías externas para el manejo de volúmenes.

## Interacción

Una vez se ha conseguido el modelo 3D se pretende añadir una interfaz de usuario para poder permitir su control. Este control incluye:
* Navegación 2D por los planos sagital, cenital y frontal de una RMI.
* Modificación básica del esquema de colores en la navegación 2D.
* Visualización 3D de un RMI etiquetada.
* Navegación 3D básica de una RMI.
* Selección de segmentos de una RMI.
* Navegación 3D básica de segmentos de una RMI.

## Trabajo futuro
### Segmentación y algoritmos de aprendizaje

Durante la realización de esta parte del proyecto aprendimos mejor como gestionar la memoria cuando se trabaja con algoritmos de este estilo. En un futuro se podría aplicar lo aprendido para tratar de rebajar el uso de la memoria.
También es posible darle otro enfoque al problema, y tratar de aplicar soluciones hardware, que al final son más rápidas que las software. Esto podría incluir usar una FPGA y programar los algoritmos en VHDL, haciendo uso de Simulink para la generación de este código.

### Representación 3D

Hay varias mejoras prioritarias, que se considerarían necesarias realizar en un futuro, tales como mejorar la iluminación y suavizar los volúmenes. También se podría calcular métricas asociadas a los volúmenes y ampliar los formatos permitidos a otros como DICCOM. Varias Ampliaciones y mejoras de la interfaz gráfica Java también serían bienvenidas.

## Conclusiones o resultados
### Segmentación y algoritmos de aprendizaje

Los resultados obtenido de aplicar los algoritmos de aprendizajes no han sido buenos, por problemas de tiempo de ejecución y de memoria.
La mayor parte de las aproximaciones usadas son válidas competitivamente, pero los recursos de los se dispusieron no lo eran. De haber poseído equipos con mejores prestaciones de cómputo paralelo se hubiera podido conseguir un resultado satisfactorio.
Debido a esto, no se ha integrado esta parte del proyecto en el producto final.

### Representación 3D

Aunque no se ha conseguido alcanzar el alcance total que se buscó inicialmente, sí se ha conseguido una primera versión acotada.
Entre los principales problemas encontrados estuvo la novedad del trabajo realizado, pertenece a un ámbito poco explorado. Fue difícil formular un algoritmo de traducción 2D a 3D, y a pesar de usar un motor gráfico como JMonkey, hubo que programar bastantes gráficos a bajo nivel, tales como los vectores normales de las caras formadas entre vértices.
En esta parte se ha aprendido a mezclar distintos temas relacionados con imagen y modelado 3D, yendo desde el más bajo nivel con el manejo de matrices de píxeles, hasta un nivel alto haciendo uso de un motor de videojuegos.