para - ¿Cómo difumino Gauss una imagen sin utilizar ninguna función gaussiana incorporada?
lapiz carboncillo definicion (5)
Quiero difuminar mi imagen usando la fórmula de desenfoque Gaussiana nativa. Lo leí, pero no estoy seguro de cómo implementar esto.
¿Cómo utilizo la fórmula para decidir los pesos?
No quiero usar ninguna función incorporada como lo que MATLAB tiene
Aquí está el pseudo-código para el código que usé en C # para calcular el kernel. Sin embargo, no me atrevo a decir que trato las condiciones finales correctamente:
double[] kernel = new double[radius * 2 + 1];
double twoRadiusSquaredRecip = 1.0 / (2.0 * radius * radius);
double sqrtTwoPiTimesRadiusRecip = 1.0 / (sqrt(2.0 * Math.PI) * radius);
double radiusModifier = 1.0;
int r = -radius;
for (int i = 0; i < kernel.Length; i++)
{
double x = r * radiusModifier;
x *= x;
kernel[i] =
sqrtTwoPiTimesRadiusRecip * Exp(-x * sqrtTwoPiTimesRadiusRecip);
r++;
}
double div = Sum(kernel);
for (int i = 0; i < kernel.Length; i++)
{
kernel[i] /= div;
}
Espero que esto pueda ayudar.
Bueno, Gaussian Kernel es un kernel separable.
Por lo tanto, todo lo que necesita es una función que admita Separable 2D Convolution como - ImageConvolutionSeparableKernel()
.
Una vez que lo tiene, todo lo que necesita es un contenedor para generar 1D Gaussian Kernel y enviarlo a la función como se hace en ImageConvolutionGaussianKernel()
.
El código es una implementación de C directa de 2D Image Convolution acelerada por SIMD (SSE) y Multi Threading (OpenMP).
Todo el proyecto está dado por: Image Convolution - GitHub .
Escribir un desenfoque gaussiano ingenuo es en realidad bastante fácil. Se hace exactamente de la misma manera que cualquier otro filtro de convolución. La única diferencia entre un cuadro y un filtro gaussiano es la matriz que utiliza.
Imagine que tiene una imagen definida de la siguiente manera:
0 1 2 3 4 5 6 7 8 9
10 11 12 13 14 15 16 17 18 19
20 21 22 23 24 25 26 27 28 29
30 31 32 33 34 35 36 37 38 39
40 41 42 43 44 45 46 47 48 49
50 51 52 53 54 55 56 57 58 59
60 61 62 63 64 65 66 67 68 69
70 71 72 73 74 75 76 77 78 79
80 81 82 83 84 85 86 87 88 89
90 91 92 93 94 95 96 97 98 99
Una matriz de filtro de caja de 3x3 se define de la siguiente manera:
0.111 0.111 0.111
0.111 0.111 0.111
0.111 0.111 0.111
Para aplicar el desenfoque gaussiano harías lo siguiente:
Para el píxel 11, deberá cargar los píxeles 0, 1, 2, 10, 11, 12, 20, 21, 22.
luego multiplicaría el píxel 0 por la parte superior izquierda del filtro de desenfoque 3x3. Pixel 1 por la mitad superior, pixel 2, pixel 3 por la parte superior derecha, pixel 10 por la mitad izquierda y así sucesivamente.
A continuación, agréguelas por completo y escriba el resultado en el píxel 11. Como puede ver, Pixel 11 es ahora el promedio de sí mismo y los píxeles circundantes.
Los casos extremos se vuelven un poco más complejos. ¿Qué valores usas para los valores del borde de la textura? Una forma puede ser envolver al otro lado. Esto se ve bien para una imagen que se muestra más tarde. Otra forma es empujar el píxel hacia los lugares circundantes.
Entonces, para la esquina superior izquierda, puede colocar las muestras de la siguiente manera:
0 0 1
0 0 1
10 10 11
Espero que pueda ver cómo esto se puede extender fácilmente a los núcleos de filtro grandes (es decir, 5x5 o 9x9, etc.).
La diferencia entre un filtro gaussiano y un filtro de caja son los números que van en la matriz. Un filtro gaussiano usa una distribución gaussiana en una fila y columna.
por ejemplo, para un filtro definido arbitrariamente como (es decir, no es un gaussiano, pero probablemente no está muy lejos)
0.1 0.8 0.1
la primera columna sería la misma pero se multiplicaría en el primer elemento de la fila de arriba.
0.01 0.8 0.1
0.08
0.01
La segunda columna sería la misma, pero los valores se multiplicarían por el 0,8 en la fila anterior (y así sucesivamente).
0.01 0.08 0.01
0.08 0.64 0.08
0.01 0.08 0.01
El resultado de sumar todo lo anterior debe ser igual a 1. La diferencia entre el filtro anterior y el filtro de cuadro original sería que el pixel final escrito tendría una ponderación mucho más pesada hacia el píxel central (es decir, el que está en esa posición). ya). El desenfoque se produce porque los píxeles circundantes se difuminan en ese píxel, aunque no tanto. Usando este tipo de filtro se obtiene una imagen borrosa pero que no destruye la mayor parte de la información de alta frecuencia (es decir, el cambio rápido de color de píxel a píxel).
Este tipo de filtros puede hacer muchas cosas interesantes. Puede hacer una detección de bordes utilizando este tipo de filtro al restar los píxeles circundantes del píxel actual. Esto solo dejará atrás los grandes cambios en el color (altas frecuencias).
Editar: Un núcleo de filtro de 5x5 se define exactamente como arriba.
por ejemplo, si tu fila es 0.1 0.2 0.4 0.2 0.1 entonces si multiplicas cada valor en su por el primer elemento para formar una columna y luego multiplicas por el segundo elemento para formar la segunda columna y así terminarás con un filtro de
0.01 0.02 0.04 0.02 0.01
0.02 0.04 0.08 0.04 0.02
0.04 0.08 0.16 0.08 0.04
0.02 0.04 0.08 0.04 0.02
0.01 0.02 0.04 0.02 0.01
tomando algunas posiciones arbitrarias puede ver que la posición 0, 0 es simple 0.1 * 0.1. La posición 0, 2 es 0.1 * 0.4, la posición 2, 2 es 0.4 * 0.4 y la posición 1, 2 es 0.2 * 0.4.
Espero que eso te dé una buena explicación.
No estoy seguro de si desea restringir esto a ciertas tecnologías, pero si no SVG (ScalableVectorGraphics) tiene una implementación de Gaussian Blur. Creo que se aplica a todas las primitivas, incluidos los píxeles. SVG tiene la ventaja de ser un estándar abierto y ampliamente implementado.
Para usar el kernel de filtro discutido en el artículo de Wikipedia, debe implementar una convolution (discreta). La idea es que tienes una pequeña matriz de valores (el núcleo), mueves este núcleo de píxel a píxel en la imagen (es decir, para que el centro de la matriz esté en el píxel), multiplica los elementos de la matriz con la imagen superpuesta elementos, sume todos los valores en el resultado y reemplace el antiguo valor de píxel con esta suma.
El desenfoque gaussiano se puede separar en dos convoluciones 1D (una vertical y una horizontal) en lugar de una convolución 2D, lo que también acelera un poco las cosas.