Desenfoque gaussiano: cómo funciona + filtro para Imaset
Escrito por Alex Barros Me he propuesto realizar el filtro de Desenfoque Gaussiano, y lo he conseguido. A continuación os muestro el algoritmo, y la descarga del filtro para quienes usen Imaset 2.1
El algoritmo
El filtro gaussiano consiste en la mezcla de los colores de una imágen para conseguir un efecto de desenfoque. Esta es una explicación muy general, y por supuesto el algoritmo es más complejo que esto.
En primer lugar, consideraremos la imágen como una matriz de puntos (pixeles), con unos valores determinados de rojo, verde y azul. A partir de aquí, los valores de cada punto de la nueva imágen, serán una combinación de los puntos cercanos. De esta forma, si un punto es de color rojo, y cercano a él hay puntos negros, este rojo se oscurecerá (y los negros se enrojecerán).
Pero para determinar cuáles son los pixeles que son cercanos, y los que no, se debe especificar al filtro un radio de acción. Con esto, si por ejemplo indicamos un radio de 10 pixeles, cada píxel de la nueva imágen se verá modificado por los todos los pixeles a menos de 10 unidades de distancia. Pero no todos los pixeles modifican con la misma “fuerza”, cuanto más cerca estén del pixel que se está modificando, más valor tendrán en el cálculo del nuevo color. Es aquí donde aparece nuestro simpático amigo Gauss.
La función de la distribución Gaussiana va a ayudarnos a adjudicar cuánto aporta cada pixel, en función de lo cerca o lejos que se encuentre. Esta función tiene la forma
donde (x-b) es la distancia entre el pixel que está siendo modificado y el píxel del que se está tomando el valor, a y c valen 1, y f(x) resulta un número Real entre 0 y 1 que representa el porcentaje de influencia.
Resumiendo
Lo que está claro es que hay que mezclar los píxeles entre sí, y que usaremos un radio de influencia en que cuanto más lejos está un píxel de otro, menos le afecta.
Después de analizar el problema, y aplicar una fórmula estadística, podemos concluir que el valor de cada pixel es:
La suma de todos los píxeles dentro del radio R, multiplicados cada uno por
(tal y como se ha descrito antes), y todo esto, dividido entre la suma de todos los valores de la fórmula
en los puntos que intervienen.
Y todo eso es sólo para calcular uno de los tres componentes (Rojo, Verde o Azul) de un sólo pixel.
De modo que, a falta de una fórmula mágica de optimización, el efecto de desenfoque Gaussiano no es ninguna broma, realiza una cantidad muy elevada de cálculos (que aumenta junto al Radio y al tamaño de la imágen).
El archivo de descarga
Aquí os dejo el código fuente y la descarga del filtro Desenfoque Gaussiano para Imaset 2.1
Tened en cuenta que, como he dicho, es un filtro muy costoso, y aplicarlo puede llevar bastantes segundos.
La forma de poder usarlo es: descargar el archivo ZIP, descomprimir su contenido, y subir el archivo gaussian.xml al directorio “/filters” y el archivo es_ES.php al directorio “/lang”
Ejemplo del filtro Gaussiano en Imaset


Como se puede apreciar, realiza un toque de suavizado, si se aplica poco desenfoque (poco radio).
Código fuente
Os dejo como siempre el código fuente de este filtro.
-
<filter>
-
<name>gaussian_blur</name>
-
<category>effect</category>
-
<parameters>
-
<pa>$rad=5</pa>
-
</parameters>
-
<function>
-
if(!$rad) $rad = 5;
-
-
$sx = imagesx($im);
-
-
$sy = imagesy($im);
-
-
-
-
for($x=-$rad;$x<$sx+$dar;$x++) // meto en una matriz los valores de colores
-
-
{
-
-
for($y=-$rad;$y<$sy+$rad;$y++)
-
-
{
-
if($x<0 || $y<0 || $x>$sx || $y>$sy)
-
else {
-
-
$rgb = ImageColorAt($im, $x, $y);
-
-
$r = ($rgb >> 16) & 0xFF;
-
-
$g = ($rgb >> 8) & 0xFF;
-
-
$b = $rgb & 0xFF;
-
}
-
-
}
-
-
}
-
-
-
// Ahora voy a poner valores (calculandolos previamente)
-
for($x=0; $x<$sx; $x++) { // recorro el array antes construido, pixel a pixel
-
for($y=0; $y<$sy; $y++) {
-
for($i=$x-$rad; $i<$x+$rad; $i++) { // circundantes en eje x
-
for($j=$y-$rad; $j<$y+$rad; $j++) { // circundantes en eje y
-
$su1R += $sue * $imatrix[$i][$j][0]; //Sumando de rojos
-
$su1G += $sue * $imatrix[$i][$j][1]; //Sumando de verdes
-
$su1B += $sue * $imatrix[$i][$j][2]; //Sumando de azules
-
$su2 += $sue;
-
}
-
}
-
-
}
-
}
-
-
return $im;
-
</function>
-
</filter>
Categorias: Código, Imagen Digital, PHP, Plugins |



Respeta el copyleft
diciembre
3:59 Statuesque Ha dicho:
Me ha gustado mucho Alex. Tanto la explicación como el código. Mola. Enhorabuena.
diciembre
14:05 Alex Barros Ha dicho:
Muchas gracias Statu! Te la dedico.
diciembre
15:10 marcioangel Ha dicho:
Muy bueno Alex, la documentación esta mas que correcta
Felicitaciones
mayo
17:45 Danikaze Ha dicho:
Una optimización inmediata y muy sencilla es precalcular los pesos en una matriz, ya que siempre van a ser los mismos, por así decirlo.
Y como el calculo del peso es el que tiene las operaciones más pesadas, debería de acelerar un poco el proceso