Desenfoque de caja | Box blur

Repo: https://github.com/umarquez/100DaysOfC0D3/tree/master/29-box-blur

A box blur (also known as a box linear filter) is a spatial domain linear filter in which each pixel in the resulting image has a value equal to the average value of its neighboring pixels in the input image. Un desenfoque de caja (también conocido como caja de filtro lineal) es un filtro lineal de dominio espacial en donde cada píxel de la imagen de salida es el promedio resultante de los píxeles vecinos (incluyendo el pixel que se procesa) de la imagen de entrada. https://en.wikipedia.org/wiki/Box_blur

De igual forma que hicimos en el tramado, aplicaremos un filtro a una imagen con el fin de realizar ciertas modificaciones, en este caso el objetivo será generar un efecto de desenfoque; esto lo haremos definiendo la cantidad de píxeles vecinos que vamos a considerar en el cálculo para, a continuación, recorrer cada píxel de la imagen original y promediar todos los vecinos , el valor resultante será escrito en la imagen nueva.

El rango de píxeles que procesaremos cada vez se conoce como ventana, esta ventana contendrá en el centro la posición que estamos procesando; en el siguiente ejemplo podremos encontrar una venta de 3x3 misma que será utilizada más adelante en el ejemplo.

**(x,y) =** ((x-1,y-1)+(x,y-1)+(x+1,y-1)+(x-1,y)+(x,y)+(x+1,y)+(x-1,y+1)+(x,y+1)+(x+1,y+1))/9

El tamaño de la venta afectará directamente el tiempo que nos tome procesar la imagen pues por cada píxel a debemos recorrer n píxeles para realizar el cálculo; por tal motivo, una ventana de 5x5 implicará recorrer 25 veces la cantidad de píxeles de la imagen pero a su vez generará un efecto de desenfoque más pronunciado.

Ejemplo

Vamos a procesar los siguientes valores utilizando una venta de 3x3

Comenzaremos con el primer píxel A1, este únicamente cuenta con 3 vecinos aparte de él, en este caso solo promediaremos los valores disponibles: A1, B1, A2 y B2, esto será: 7 + 7 + 7 + 7 = 28 / 4 = 7

La tabla siguiente contiene las operaciones que deberemos realizar en cada caso:

Una vez calculado cada valor, deberemos redondearlo y almacenarlo en la imagen de salida, hecho esto, la imagen resultante se verá de la siguiente forma:

Como podemos observar, el cambio drástico en los valores entre la columna C y D ha sido matizada en la imagen resultante, este cambio de valores podría representar un borde vertical que ha sido suavizado.

Implementación en Go

Original
Original
Original

ventana: 3x3
ventana: 3x3
ventana: 3x3

ventana: 9x9
ventana: 9x9
ventana: 9x9

ventana: 27x27
ventana: 27x27
ventana: 27x27

ventana: 50x50
ventana: 50x50
ventana: 50x50

ventana: 100x100
ventana: 100x100
ventana: 100x100

Palabras finales

Este método podría ser optimizado de diferentes maneras, una de ellos podría ser procesando la imagen en paralelo pues finalmente se leen varios píxeles para generar uno de salida, por lo que podríamos distribuir las posiciones a procesar entre varias goroutines.

También existe un método para reducir el tiempo de procesamiento que consiste en procesar, primero, todas las columnas y en una segunda vuelta, todas las filas. Podríamos intentar estos método o algún otro que sugieran en próximos capítulos.

Me gustaría saber qué otros temas te gustaría que exploremos en este espacio, ademas de tu opinión con respecto a este en particular; si tienes alguna sugerencia o comentario no dejes de compartirla.

-Uriel Márquez.