Para poner en práctica el gaussian blur usted simplemente toma el gaussian function y calcular un valor para cada uno de los elementos en su núcleo.
Por lo general, desea asignar el peso máximo al elemento central en su kernel y valores cercanos a cero para los elementos en los bordes del kernel. Esto implica que el núcleo debe tener una altura impar (o ancho) para garantizar que realmente exista un elemento central.
para calcular los elementos del núcleo reales es posible que la escala de la campana de Gauss a la red núcleo (elegir una arbitraria por ejemplo sigma = 1
y un rango arbitrario por ejemplo -2*sigma ... 2*sigma
) y normalizarla, S.T. los elementos suman uno. Para lograr esto, si desea admitir tamaños de kernel arbitrarios, es posible que desee adaptar sigma al tamaño de kernel requerido.
Aquí está un ejemplo de C++:
#include <cmath>
#include <vector>
#include <iostream>
#include <iomanip>
double gaussian (double x, double mu, double sigma) {
return std::exp(-(((x-mu)/(sigma))*((x-mu)/(sigma)))/2.0);
}
typedef std::vector<double> kernel_row;
typedef std::vector<kernel_row> kernel_type;
kernel_type produce2dGaussianKernel (int kernelRadius) {
double sigma = kernelRadius/2.;
kernel_type kernel2d(2*kernelRadius+1, kernel_row(2*kernelRadius+1));
double sum = 0;
// compute values
for (int row = 0; row < kernel2d.size(); row++)
for (int col = 0; col < kernel2d[row].size(); col++) {
double x = gaussian(row, kernelRadius, sigma)
* gaussian(col, kernelRadius, sigma);
kernel2d[row][col] = x;
sum += x;
}
// normalize
for (int row = 0; row < kernel2d.size(); row++)
for (int col = 0; col < kernel2d[row].size(); col++)
kernel2d[row][col] /= sum;
return kernel2d;
}
int main() {
kernel_type kernel2d = produce2dGaussianKernel(3);
std::cout << std::setprecision(5) << std::fixed;
for (int row = 0; row < kernel2d.size(); row++) {
for (int col = 0; col < kernel2d[row].size(); col++)
std::cout << kernel2d[row][col] << ' ';
std::cout << '\n';
}
}
La salida es:
$ g++ test.cc && ./a.out
0.00134 0.00408 0.00794 0.00992 0.00794 0.00408 0.00134
0.00408 0..02412 0.03012 0.02412 0..00408
0.00794 0.02412 0.04698 0.05867 0.04698 0.02412 0.00794
0.00992 0.03012 0.05867 0.07327 0.05867 0.03012 0.00992
0.00794 0.02412 0.04698 0.05867 0.04698 0.02412 0.00794
0.00408 0..02412 0.03012 0.02412 0..00408
0.00134 0.00408 0.00794 0.00992 0.00794 0.00408 0.00134
Como una simplificación que no es necesario utilizar un 2d-núcleo. Más fácil de implementar y también más eficiente de calcular es usar dos núcleos 1d ortogonales. Esto es posible debido a la asociatividad de este tipo de convolución lineal (separabilidad lineal). Es posible que también desee ver this section del artículo de wikipedia correspondiente.
Aquí es lo mismo en Python (con la esperanza de que alguien podría encontrar útil):
from math import exp
def gaussian(x, mu, sigma):
return exp(-(((x-mu)/(sigma))**2)/2.0)
#kernel_height, kernel_width = 7, 7
kernel_radius = 3 # for an 7x7 filter
sigma = kernel_radius/2. # for [-2*sigma, 2*sigma]
# compute the actual kernel elements
hkernel = [gaussian(x, kernel_radius, sigma) for x in range(2*kernel_radius+1)]
vkernel = [x for x in hkernel]
kernel2d = [[xh*xv for xh in hkernel] for xv in vkernel]
# normalize the kernel elements
kernelsum = sum([sum(row) for row in kernel2d])
kernel2d = [[x/kernelsum for x in row] for row in kernel2d]
for line in kernel2d:
print ["%.3f" % x for x in line]
produce el núcleo:
['0.001', '0.004', '0.008', '0.010', '0.008', '0.004', '0.001']
['0.004', '0.012', '0.024', '0.030', '0.024', '0.012', '0.004']
['0.008', '0.024', '0.047', '0.059', '0.047', '0.024', '0.008']
['0.010', '0.030', '0.059', '0.073', '0.059', '0.030', '0.010']
['0.008', '0.024', '0.047', '0.059', '0.047', '0.024', '0.008']
['0.004', '0.012', '0.024', '0.030', '0.024', '0.012', '0.004']
['0.001', '0.004', '0.008', '0.010', '0.008', '0.004', '0.001']
¿Ha leído esto: http://en.wikipedia.org/wiki/Gaussian_function? –
O incluso esto: http://en.wikipedia.org/wiki/Gaussian_blur – Bart
Sí, he pasado mucho tiempo intentando entenderlos. Lo que necesito es un ejemplo paso a paso. Después de que lo entiendo, probablemente agregue el ejemplo a la página Gaussian Blur. – gsingh2011