Subscribe:

sábado, 5 de marzo de 2016

Función "genérica" de correlación en C#

Desde el semestre pasado he estado trabajando con imágenes en la universidad. Primero fue en la clase de Graficación y ahora en Procesamiento de Imágenes (aunque el primer acercamiento que tuve con este tema fue en 4to semestre).

El procesamiento de Imágenes no es de mis temas favoritos pero, como pueden ver, he tenido que acercarme en repetidas ocasiones. Hace una semana nos pidieron que escribiésemos funciones para aplicar los filtros de caja, Gaussiano, promedio y además que escribiésemos otras dos funciones (una para correlación y otra para convolución).

Cuando estaba viendo cómo se aplicaba la correlación a una imagen usando un filtro me di cuenta de que los otros filtros (caja y Gaussiano) que nos habían pedido que programáramos tenían el mismo comportamiento, así que no me quedé con la duda e investigando resultó que sí.

Como ya he mencionado en este blog, soy una persona floja, así que prefería quebrarme la cabeza un poquito en hacer una función a la que pudiera enviar una imagen y un filtro (cuadrado de dimensiones impares) cualesquiera y no tener que programar una función nueva por cada nuevo filtro que viésemos. La función es sencilla y, al igual que siempre lo digo, puede ser optimizada, pero para fines prácticos (usando imágenes Full HD) me ha servido bastante bien. Sin más que comentar, aquí debajo les dejo el código de la función. Este código está escrito en C#, más abajo les dejo una foto del pseudo código que escribí en mi libreta para que no se me olvidara.

La función retorna un array de Bytes porque así se crean las BitmapImage, así que para evitar tener que estar creando una matriz para trabajar y luego aplanarla para hacer la imagen, decidí trabajar la imagen en ese array de una dimensión. Siendo honesto, ha resultado más fácil de lo que pensé el estar trabajando de esa manera. Entre las cosas que se pueden mejorar está el cambiar las sentencias Linq por for (no recuerdo dónde leí que los for consumen menos tiempo de procesamiento que las consultas de Linq). Se puede "evitar" crear la vecindad y sólo enviar el centro del filtro, entre otras cosas más.

Aquí dejo la foto que ya había dicho del psudocódigo.

Bueno, espero que les sirva de algo si es que andan trabajando con imágenes. Quedo abierto a cualquier duda, comentario, queja o sugerencia.

Hasta luego.

PD. Había olvidado escribirlo. Al final del método se normaliza la imagen. Para esta parte de la clase estamos trabajando con imágenes monocromáticas con un byte de profundidad. Dependiendo de qué tipo de imágenes estén usando se deben hacer unas adecuaciones a los ciclos, pero son adecuaciones menores.

PPD. Sé que una función genérica es aquella a la que se le envía el tipo (función nombre<Tipo>(arg)), pero no se me ocurrió otra forma de llamarla :p

0 Comentarios:

Publicar un comentario