Versión Final
El último prototipo comprende toda la funcionalidad de los prototipos anteriores, y añade la posibilidad de filtrar imágenes de 3 y 4 dimensiones.
El proceso de filtrado completo de una imagen n-dimensional en la versión final es el siguiente:
CARGA DE IMAGEN
La carga inicial de la imagen en memoria principal del sistema se realiza de dos formas diferentes.
Imágenes 2D
Para cargar imágenes en 2D se hace uso de la biblioteca de OpenCV; esto se realiza en dos pasos:
-
Cargar la imagen a memoria principal
-
Copiar la imagen a memoria de GPU
OpenCV se utiliza en el primer paso, y crea una imagen de tipo RGBA en memoria principal.
En el paso de copiar la imagen a memoria de GPU se realiza un paso extra que consiste en separar cada uno de los canales recibidos inicialmente (RGBA) en memoria de GPU. Esto siguiendo los lineamientos de programación en CUDA, en donde se recomienda tener una estructura de arreglos (SoA[9]) a comparación de un arreglo de estructuras (AoS).
Este paso extra se programó en CUDA de manera paralela, asegurando desde el principio que se utiliza todos los recursos computacionales incluso en algo trivial como lo es la separación de canales.
Imágenes ITK
Para cargar imágenes que no solo sean 2D se hace uso de ITK, específicamente se hace uso de las clases itkImageFileReader y posteriormente itkImageFileWriter.
De igual manera que en la carga de imágenes 2D, la carga de imágenes usando ITK se divide en dos pasos:
-
Cargar la imagen a memoria principal
-
Copiar la imagen a memoria de GPU
Una diferencia importante con respecto a la anterior forma de cargar imágenes es que no se requiere aquel paso “extra” de división de canales, ya que al cargar la imagen a memoria principal se está haciendo por defecto la carga de cada canal en un arreglo diferente.
En el diagrama 3 se ve este proceso, más simple a comparación de la carga con OpenCV.
Diagrama 3: Convolución de imágenes 3D en GPU
DEFINIR EL KERNEL
El primer paso del filtrado es la definición del kernel que se aplicará. Esta definición viene en dos partes:
-
Radio del kernel
-
Valores del kernel
Las dos partes de la definición se estipulan directamente en el código.
El radio del kernel se refiere al tamaño del mismo en cada dimensión. Por defecto el radio se define como un único numero ya que el tamaño del kernel es en mismo en todas las dimensiones. Con respecto a los valores del kernel, estos son los que indican que tipo de filtrado se aplicará. Existen varios tipos de filtrados aplicables, algunos de estos están descritos en [Marco Conceptual, 1.4.2].
EJECUTAR EL FILTRADO
Luego de tener tanto kernel como imagen cargadas en la memoria de la GPU, es posible ejecutar el algoritmo de filtrado.
Como ya se ha dicho, el filtrado se aplicará mediante una convolución. El algoritmo de convolución utilizado es el descrito en [Marco Conceptual, 1.4.2.3], que implementa una gran cantidad de optimizaciones a comparación de la convolución trivial [Marco Conceptual, 1.4.2.1].
Al momento de iniciar la ejecución del algoritmo, es necesario calcular la dimensión y cantidad de bloques el mismo que se van a lanzar. En la ilustración 14 se aprecia la vista general de los hilos de ejecución, y en la sección [Marco Conceptual, 1.2.1.2] se explica cómo se ejecuta un algoritmo paralelo en CUDA.
Ilustración 14: Vista general de ejecución paralela en CUDA
La dimensión y cantidad de los bloques de ejecución debería ser optima (que genere la mayor ocupación [18]) para aprovechar lo mejor posible los recursos computacionales de la GPU.
-
Luego de que todas las divisiones de la imagen han sido filtradas, se siguen los siguientes pasos para producir un archivo de imagen de nuevo:
-
Unión de los diferentes canales (Ej. RGBA)
-
Copiar imagen a memoria principal
-
Generación del archivo (OpenCV o ITK)
La unión de los canales aplica únicamente a las imágenes que tuvieron que ser desagregadas para ejecutar el filtro. Esta unión de canales, de igual manera que la separación de los mismos, se realiza utilizando todos los recursos computacionales de la GPU.
Cumplimiento de objetivos Objetivo general
El objetivo general del desarrollo fue el siguiente:
Desarrollar un prototipo que implemente los algoritmos de convolucion de imágenes n-dimensionales, aprovechando los recursos computacionales de una GPU Nvidia.
El objetivo fue cumplido, se desarrolló un prototipo y se diseñó un modelo de integración con CUDA y otras plataformas (ITK, OpenCV) en las que se evidencia que es posible implementar el filtrado de imágenes n-dimensionales.
Los resultados con respecto al rendimiento del filtrado a comparación de aplicaciones de filtrado convencionales se encuentra en la sección [Resultados y reflexión sobre los mismos, 3.].
Objetivos específicos
La siguiente tabla muestra el cumplimiento de los objetivos específicos planteados en la planeación del proyecto.
Objetivos
|
Estado
|
Comentarios
|
Caracterizar los algoritmos de filtrado para imágenes n-dimensionales existentes en la literatura
|
Cumplido
|
Se generó un documento que describe las principales formas de implementar convoluciones
|
Caracterizar los requerimientos de los algoritmos para que se puedan implementar utilizando el lenguaje de programación CUDA de Nvidia
|
Cumplido
|
Se generó un documento que describe la arquitectura de CUDA.
|
Diseñar los algoritmos previamente caracterizados de manera paralela
|
Cumplido
|
Se eligió la convolución de filtros separables y se diseñó un modelo que permite filtrar imágenes usando ITK/OpenCV y filtrarlas en CUDA.
|
Diseñar un prototipo que implemente los algoritmos paralelos diseñados
|
Cumplido
|
Cinco prototipos incrementales fueron implementados para validar el diseño propuesto.
|
Implementar un prototipo en lenguaje de programación CUDA, con base en el diseño anterior, ejecutable en una GPU Nvidia.
|
Cumplido
|
Se implementaron cinco prototipos incrementales.
|
Validar los algoritmos diseñados con los del prototipo implementado
|
Cumplido
|
Los prototipos implementados permitieron validar los algoritmos diseñados.
|
Diseñar un caso de prueba de filtrado de imágenes médicas complejas
|
Cumplido
|
Se diseñaron casos de prueba en dos dimensiones que comprobaron la diferencia de rendimiento entre CUDA y las implementaciones convencionales.
|
Tabla 2: Resultado objetivos específicos
Dostları ilə paylaş: |