En el procesamiento de imágenes , un núcleo , una matriz de convolución o una máscara es una matriz pequeña . Se utiliza para desenfocar, afilar, grabar en relieve, detectar bordes y más. Esto se logra haciendo una convolución entre un kernel y una imagen .
Detalles
La expresión general de una convolución es
dónde es la imagen filtrada, es la imagen original, es el núcleo de filtro. Cada elemento del núcleo de filtro es considerado por y .
Dependiendo de los valores de los elementos, un kernel puede causar una amplia gama de efectos.
Operación | Kernel ω | Resultado de imagen g (x, y) |
---|---|---|
Identidad | ||
Detección de bordes | ||
Afilar | ||
Desenfoque de cuadro ( normalizado ) | ||
Desenfoque gaussiano 3 × 3 (aproximación) | ||
Desenfoque gaussiano 5 × 5 (aproximación) | ||
Enmascaramiento de enfoque 5 × 5 Basado en desenfoque gaussiano con una cantidad de 1 y un umbral de 0 (sin máscara de imagen ) | |
Los anteriores son solo algunos ejemplos de efectos que se pueden lograr mediante la convolución de núcleos e imágenes.
Origen
El origen es la posición del kernel que está por encima (conceptualmente) del píxel de salida actual. Esto podría estar fuera del kernel real, aunque generalmente corresponde a uno de los elementos del kernel. Para un núcleo simétrico, el origen suele ser el elemento central.
Circunvolución
La convolución es el proceso de agregar cada elemento de la imagen a sus vecinos locales, ponderados por el kernel. Esto está relacionado con una forma de convolución matemática . La operación de matriz que se realiza, convolución, no es la multiplicación de matrices tradicional, a pesar de que se denota de manera similar con *.
Por ejemplo, si tenemos dos matrices de tres por tres, la primera un núcleo y la segunda una pieza de imagen, la convolución es el proceso de voltear las filas y columnas del núcleo y multiplicar entradas locales similares y sumar. El elemento en las coordenadas [2, 2] (es decir, el elemento central) de la imagen resultante sería una combinación ponderada de todas las entradas de la matriz de la imagen, con pesos dados por el núcleo:
Las otras entradas se ponderarían de manera similar, donde colocamos el centro del núcleo en cada uno de los puntos límite de la imagen y calculamos una suma ponderada.
Los valores de un píxel dado en la imagen de salida se calculan multiplicando cada valor del núcleo por los correspondientes valores de píxel de la imagen de entrada. Esto se puede describir algorítmicamente con el siguiente pseudocódigo:
para cada fila de imagen en la imagen de entrada : para cada píxel en la fila de imagen : poner el acumulador a cero para cada fila del kernel en el kernel : para cada elemento en la fila del kernel : si la posición del elemento corresponde * a la posición del píxel, entonces multiplique el valor del elemento correspondiente * al valor del píxel agregue el resultado al acumulador endif establecer el píxel de la imagen de salida en el acumulador
- * Los píxeles de la imagen de entrada correspondientes se encuentran en relación con el origen del kernel.
Si el kernel es simétrico, coloque el centro (origen) del kernel en el píxel actual. El kernel se superpondrá a los píxeles vecinos alrededor del origen. Cada elemento del kernel se debe multiplicar por el valor de píxel con el que se superpone y se deben sumar todos los valores obtenidos. Esta suma resultante será el nuevo valor para el píxel actual actualmente superpuesto con el centro del núcleo.
Si el núcleo no es simétrico, debe voltearse alrededor de su eje horizontal y vertical antes de calcular la convolución como se indicó anteriormente. [1]
La forma general de convolución matricial es
Manejo de bordes
La convolución del kernel generalmente requiere valores de píxeles fuera de los límites de la imagen. Existe una variedad de métodos para manejar los bordes de la imagen.
- Ampliar
- Los píxeles del borde más cercanos se extienden conceptualmente tanto como sea necesario para proporcionar valores para la convolución. Los píxeles de las esquinas se extienden en cuñas de 90 °. Otros píxeles de borde se extienden en líneas.
- Envoltura
- La imagen está envuelta conceptualmente (o en mosaico) y los valores se toman del borde o esquina opuesta.
- Espejo
- La imagen se refleja conceptualmente en los bordes. Por ejemplo, al intentar leer un píxel 3 unidades fuera de un borde, se lee 3 unidades dentro del borde.
- Cultivo
- Se omite cualquier píxel de la imagen de salida que requiera valores más allá del borde. Este método puede hacer que la imagen de salida sea un poco más pequeña, con los bordes recortados.
- Cultivo de granos
- Cualquier píxel del kernel que se extienda más allá de la imagen de entrada no se utiliza y la normalización se ajusta para compensar.
Normalización
La normalización se define como la división de cada elemento en el kernel por la suma de todos los elementos del kernel, de modo que la suma de los elementos de un kernel normalizado es la unidad. Esto asegurará que el píxel promedio en la imagen modificada sea tan brillante como el píxel promedio en la imagen original.
Implementación concreta
Aquí una implementación de convolución concreta realizada con el lenguaje de sombreado GLSL :
// autor: csblo // Trabajo realizado solo consultando: // https://en.wikipedia.org/wiki/Kernel_(image_processing)// Definir kernels #definir identidad mat3 (0, 0, 0, 0, 1, 0, 0, 0, 0) #define edge0 mat3 (1, 0, -1, 0, 0, 0, -1, 0, 1) #define edge1 mat3 (0, 1, 0, 1, -4, 1, 0, 1, 0) #define edge2 mat3 (-1, -1, -1, -1, 8, -1, -1 , -1, -1) #define sharpen mat3 (0, -1, 0, -1, 5, -1, 0, -1, 0) #define box_blur mat3 (1, 1, 1, 1, 1, 1 , 1, 1, 1) * 0.1111 #define gaussian_blur mat3 (1, 2, 1, 2, 4, 2, 1, 2, 1) * 0.0625 #define emboss mat3 (-2, -1, 0, -1, 1, 1, 0, 1, 2)// Encuentra la coordenada del elemento de la matriz del índice vec2 kpos ( int index ) { return vec2 [ 9 ] ( vec2 ( - 1 , - 1 ), vec2 ( 0 , - 1 ), vec2 ( 1 , - 1 ), vec2 ( - 1 , 0 ), vec2 ( 0 , 0 ), vec2 ( 1 , 0 ), vec2 ( - 1 , 1 ), vec2 ( 0 , 1 ), vec2 ( 1 , 1 ) ) [ índice ] / iResolution . xy ; }// Extracto región de 3x3 dimensión desde sampler centrada en uv // sampler: Textura sampler // uv: coordenadas actuales sobre sampler // retorno: una matriz de MAT3, cada índice correspondiente con un canal de color MAT3 [ 3 ] region3x3 ( sampler2D sampler , vec2 uv ) { // Crea cada píxel para la región vec4 [ 9 ] region ; para ( int i = 0 ; i < 9 ; i ++ ) región [ i ] = textura ( muestreador , uv + kpos ( i )); // Crea una región 3x3 con 3 canales de color (rojo, verde, azul) mat3 [ 3 ] mRegion ; para ( int i = 0 ; i < 3 ; i ++ ) mRegion [ i ] = mat3 ( region [ 0 ] [ i ], region [ 1 ] [ i ], region [ 2 ] [ i ], region [ 3 ] [ i ], región [ 4 ] [ i ], región [ 5 ] [ i ], región [ 6 ] [ i ], región [ 7 ] [ i ], región [ 8 ] [ i ] ); return mRegion ; }// Convolucionar una textura con el kernel // kernel: kernel utilizado para la convolución // muestreador: muestreador de textura // uv: coordenadas actuales en el muestreador vec3 convolución ( mat3 kernel , sampler2D muestreador , vec2 uv ) { vec3 fragment ; // Extrae una región 3x3 centrada en uv mat3 [ 3 ] region = region3x3 ( sampler , uv ); // para cada canal de color de la región para ( int i = 0 ; i < 3 ; i ++ ) { // obtener el canal de la región mat3 rc = region [ i ]; // multiplicación por componentes del kernel por canal de región mat3 c = matrixCompMult ( kernel , rc ); // suma cada componente de la matriz flotante r = c [ 0 ] [ 0 ] + c [ 1 ] [ 0 ] + c [ 2 ] [ 0 ] + c [ 0 ] [ 1 ] + c [ 1 ] [ 1 ] + c [ 2 ] [ 1 ] + c [ 0 ] [ 2 ] + c [ 1 ] [ 2 ] + c [ 2 ] [ 2 ]; // para el fragmento en el canal i, establece el resultado fragment [ i ] = r ; } devolver fragmento ; }void mainImage ( fuera vec4 fragColor , en vec2 fragCoord ) { // Coordenadas de píxeles normalizadas (de 0 a 1) vec2 uv = fragCoord / iResolution . xy ; // Convolve núcleo con textura vec3 col = convolución ( relieve , iChannel0 , uv ); // Salida a pantalla fragColor = vec4 ( col , 1.0 ); }
Referencias
- Ludwig, Jamie (sin fecha). Convolución de la imagen (PDF) . Universidad Estatal de Portland .
- Lecarme, Olivier; Delvare, Karine (enero de 2013). El libro de GIMP: una guía completa de casi todo . Sin prensa de almidón . pag. 429. ISBN 978-1593273835.
- Gumster, Jason van; Shimonski, Robert (marzo de 2012). Biblia GIMP . Wiley . págs. 438–442. ISBN 978-0470523971.
- Shapiro, Linda G .; Stockman, George C. (febrero de 2001). Visión por computadora . Prentice Hall . págs. 53–54. ISBN 978-0130307965.
enlaces externos
- Implementación de convolución 2d en FPGA
- Guía de programación de vImage: realización de operaciones de convolución
- Procesamiento de imágenes mediante convolución 2D
- Programa de manipulación de imágenes GNU - Manual del usuario - 8.2. Matriz de convolución
- Demostración GLSL de núcleos de convolución 3x3
- Proyecto completo de código abierto C ++