💡 OBJETIVOS DE LA ACTIVIDAD:

► Entender la necesidad de los filtros para la mejora de las imágenes de satélite.

► Saber aplicar los diferentes filtros en función del tipo de imagen y de las necesidades del investigador.

💡 MATERIALES PARA LA ACTIVIDAD:

► En este apartado se va a utilizar la misma imagen utilizada en el apartado dedicado a la representación gráfica.

script_laboratorio_4_filtros.

INTRODUCCIÓN

Las imagenes obtenidas mediante sensores remotos tienen una característica importante, conocida como “frecuencia espacial”. Esta frecuencia espacial se define como el número de cambios en el valor de los píxeles según una unidad de distancia.

El filtrado espacial es una aproximación para extraer información espacial cuantitativa tomando en consideración los valores de los píxeles vecinos alrededor del valor de un determinado pixel. Por consiguiendo, el filtrado espacial es una técnica para modificar o mejorar una imagen, con el objetivo de mejorar la interpretabilidad de una imagen o extraer cierta información de ella. Es una operación de vecindad porque el valor de cualquier pixel en la futura imagen será determinado tras aplicar ciertos algoritmos a los pixeles vecinos. La natualeza de estos algorítmos depende de la información que el usuario quiera resaltar. Las operaciones de filtrado se realizan principalmente para suavización, eliminación de ruido, realce de bordes y “sharpening”.

Un filtro es un kernel de un pequeño array que es aplicado a un pixel y sus píxeles circundantes. Existen diferentes tipos de filtos, que van a ser aplicados a continuación

Lo primer de todo es activar el paquete raster e importar un fichero multibanda sobre el que realizaremos todo el procedimiento

setwd("D:/G174_2025/LABORATORIO_4_Visualizacion_imagenes/datos/")            # Directorio de trabajo
getwd()
## [1] "D:/G174_2025/LABORATORIO_4_Visualizacion_imagenes/datos"
library(terra)
## Warning: package 'terra' was built under R version 4.3.3
## terra 1.8.21
library(RStoolbox)
## Warning: package 'RStoolbox' was built under R version 4.3.3
## This is version 1.0.0 of RStoolbox

Importación del fichero que incluye una imagen raster multibanda.

sentinel <- rast("D:/G174_2025/LABORATORIO_4_Visualizacion_imagenes/datos/sentinel.tif")
sentinel
## class       : SpatRaster 
## dimensions  : 507, 848, 12  (nrow, ncol, nlyr)
## resolution  : 9.217891e-05, 9.217891e-05  (x, y)
## extent      : -4.320218, -4.242051, 56.45366, 56.50039  (xmin, xmax, ymin, ymax)
## coord. ref. : lon/lat WGS 84 (EPSG:4326) 
## source      : sentinel.tif 
## names       : sentinel_1, sentinel_2, sentinel_3, sentinel_4, sentinel_5, sentinel_6, ...
plot(sentinel)

A continuación, se separan de ese ráster una a una las bandas necesarias para la actividad, que son la 3, la 4 y la 8.

imagen <- sentinel[[c(8,4,3)]]
names(imagen) <- c("NIR", "Red", "Green")                # Establecer los nombres de las bandas del fichero
imagen                                                   # Atributos del fichero raster importado
## class       : SpatRaster 
## dimensions  : 507, 848, 3  (nrow, ncol, nlyr)
## resolution  : 9.217891e-05, 9.217891e-05  (x, y)
## extent      : -4.320218, -4.242051, 56.45366, 56.50039  (xmin, xmax, ymin, ymax)
## coord. ref. : lon/lat WGS 84 (EPSG:4326) 
## source      : sentinel.tif 
## names       : NIR, Red, Green

A continuación, eliminarán las bandas originales y se representa gráficamente el objeto raster.

rm(sentinel)
plotRGB(imagen, 
        stretch = "lin")

Mediante la aplicación de cualquier filtro a la imagen, creamos un kernel en forma de matriz cuyos valores dependeran del tipo de filtro que se crea. Este kernel es aplicado posteriormente a cada uno de los píxeles de la image, utilizando la función focal() del paquete terra. Esta función focal() sólo podemos aplicarla a una única banda. Por ello, en caso de disponer de un único fichero multibanda, tendremos que repetir el mismo procedimiento en cada banda y lugeo crear un raster brick con las capas filtradas. Este raster brick será usado a continuación para representar gráficamente una imagen en falso color. Los detalles de la matriz de cada filtro en particular será discutidos en cada apartado.

FILTROS DE PASO BAJO.

Los filtros de paso bajo o de suavizado provocan una perdida de foco en la imagen (desenfoque). Este efecto se consigue disminuyendo las diferencias entre los valores de los píxeles contiguos. Los filtros de paso bajo se utilizan para retener la información de baja frecuencia y reducir la de alta frecuencia en la imagen. Este efecto puede expresarse mediante un kernel (o núcleo) como el siguiente:

Kernel de un filtro de paso bajo Tomado de https://volaya.github.io/libro-sig/index.html

Este efecto se consigue calculando la media, la mediana, la moda etc de los píxeles que están incluidos dentro del tamaño del kernel, lo que reduce la variación en los valores de brillo de un pixel a otro. Aumentando el tamaño del kernel, el efecto de suavizado se intensifica.

Filtro con la media

El filtro basado en la media calcula el valor promedio de todos los píxeles dentro del kernel, asignando a cada pixel este valor. Es usado para reducir el ruido de la imagen raster, suavizando los límites más nítidos. Es el filtro más simple y fácil de implementar, pero si un pixel tiene un valor anómalo, puede afectar significativamente al valor medio y producir efectos no deseados.

Como ejemplo, se elaborarán 3 filtros basados en la media pero con diferentes tamaños de kernel (3x3, 5x5 y 25 x 25) con el fin de comprobar el efecto de cada uno de ellos en las imágenes resultantes. Para aplicar este filtro, el tamaño de la matriz kernel es especificado con el argumento w =y el argumento fun = meande la función focal().

  • Filtro con un kernel de 3x3 aplicado a cada banda del fichero raster
filtro_promedio3_B1 <- focal(imagen[[1]],                                   # Banda NIR
                      w = matrix(1, 3,3),
                      fun = mean)

filtro_promedio3_B2 <- focal(imagen[[2]],                                   # Banda red
                      w = matrix(1, 3,3),
                      fun = mean)

filtro_promedio3_B3 <- focal(imagen[[3]],                                   # Banda green 
                      w = matrix(1,3,3),
                      fun = mean)

Creación del SpatRaster con las capas filtradas y comprobación de los atributos

filtro_promedio3 <- c(filtro_promedio3_B1,filtro_promedio3_B2,filtro_promedio3_B3)

filtro_promedio3
## class       : SpatRaster 
## dimensions  : 507, 848, 3  (nrow, ncol, nlyr)
## resolution  : 9.217891e-05, 9.217891e-05  (x, y)
## extent      : -4.320218, -4.242051, 56.45366, 56.50039  (xmin, xmax, ymin, ymax)
## coord. ref. : lon/lat WGS 84 (EPSG:4326) 
## source(s)   : memory
## varnames    : sentinel 
##               sentinel 
##               sentinel 
## names       : focal_mean,   focal_mean,  focal_mean 
## min values  :  0.0001000, 0.0001444444, 0.001122222 
## max values  :  0.7663778, 0.2190888888, 0.228144445
  • Filtro con un kernel de 5x5 aplicado a cada banda del fichero raster
filtro_promedio5_B1 <- focal(imagen[[1]],                                   # Banda NIR
                      w = matrix(1,5,5),
                      fun = mean)

filtro_promedio5_B2 <- focal(imagen[[2]],                                   # Banda red
                      w = matrix(1,5,5),
                      fun = mean)

filtro_promedio5_B3 <- focal(imagen[[3]],                                   # Banda green 
                      w = matrix(1,5,5),
                      fun = mean)

Creación del SpatRaster con las capas filtradas y comprobación de los atributos

filtro_promedio5 <- c(filtro_promedio5_B1,filtro_promedio5_B2,filtro_promedio5_B3)
filtro_promedio5
## class       : SpatRaster 
## dimensions  : 507, 848, 3  (nrow, ncol, nlyr)
## resolution  : 9.217891e-05, 9.217891e-05  (x, y)
## extent      : -4.320218, -4.242051, 56.45366, 56.50039  (xmin, xmax, ymin, ymax)
## coord. ref. : lon/lat WGS 84 (EPSG:4326) 
## source(s)   : memory
## varnames    : sentinel 
##               sentinel 
##               sentinel 
## names       : focal_mean, focal_mean, focal_mean 
## min values  :   0.000100,   0.000300,    0.00154 
## max values  :   0.748508,   0.167796,    0.16042
  • Filtro con un kernel de 25x25 aplicado a cada banda del fichero raster
filtro_promedio25_B1 <- focal(imagen[[1]],                                   # Banda NIR
                      w = matrix(1,25,25),
                      fun = mean)

filtro_promedio25_B2 <- focal(imagen[[2]],                                   # Banda red
                      w = matrix(1,25,25),
                      fun = mean)

filtro_promedio25_B3 <- focal(imagen[[3]],                                   # Banda green 
                      w = matrix(1,25,25),
                      fun = mean)

Creación del SpatRaster con las capas filtradas y comprobación de los atributos.

filtro_promedio25 <- c(filtro_promedio25_B1,filtro_promedio25_B2,filtro_promedio25_B3)
filtro_promedio25
## class       : SpatRaster 
## dimensions  : 507, 848, 3  (nrow, ncol, nlyr)
## resolution  : 9.217891e-05, 9.217891e-05  (x, y)
## extent      : -4.320218, -4.242051, 56.45366, 56.50039  (xmin, xmax, ymin, ymax)
## coord. ref. : lon/lat WGS 84 (EPSG:4326) 
## source(s)   : memory
## varnames    : sentinel 
##               sentinel 
##               sentinel 
## names       : focal_mean, focal_mean, focal_mean 
## min values  :  0.0001000,  0.0007640, 0.00215984 
## max values  :  0.6670854,  0.1096248, 0.08955008

Una vez obtenidos los ficheros filtrados, crearemos a continuación una imagen en falso color de las imágenes fitradas para comparar el efecto del tramaño de los kernel.

  • Kernel 3x3
plotRGB(filtro_promedio3,
        main = "Imagen filtrada con el promedio de un kernel 3x3",
        axes = TRUE)

  • Kernel 5x5
plotRGB(filtro_promedio5,
        stretch="lin",
        main = "Imagen filtrada con el promedio de un kernel 5x5",
        axes = TRUE)

  • Kernel 25x25
plotRGB(filtro_promedio25,
        stretch="lin",
        main = "Imagen filtrada con el promedio de un kernel 25x25",
        axes = TRUE)

Puede comprobarse cómo un incremento del kernel supone una imagen mucho más difusa, a causa del suavizado.

En caso de necesidad de limpiar el Global Environment, se eliminarán los siguientes objetos

rm(filtro_promedio3_B1, filtro_promedio3_B2, filtro_promedio3_B3, filtro_promedio3, 
   filtro_promedio5_B1, filtro_promedio5_B2, filtro_promedio5_B3, filtro_promedio5,
   filtro_promedio25_B1, filtro_promedio25_B2, filtro_promedio25_B3, filtro_promedio25)

Filtro con la mediana

El filtro de mediana reemplaza el valor de píxel en la imagen ráster con la mediana de todos los valores de píxel que caen alrededor del kernel. La mediana se obtiene organizando todos esos píxeles dentro del kernel que rodean al píxel de entrada en orden asignando el valor mediano al píxel de salida. Este filtro no crea valores tan poco realistas en los bordes como el de la media, preservando mejor los bordes y evita el efecto de píxeles no representativos. Generalmente se usa para reducir el ruido, pero su cálculo conlleva más tiempo.

  • Filtro con un kernel de 3x3 aplicado a cada banda del fichero raster, seguido de la creación de un RasterBrickcon las capas filtradas y comprobación de sus atributos
filtro_mediana3_B1 <- focal(imagen[[1]],                                   # Banda NIR
                      w = matrix(1, 3,3),
                      fun = median)

filtro_mediana3_B2 <- focal(imagen[[2]],                                   # Banda red
                      w = matrix(1, 3,3),
                      fun = median)

filtro_mediana3_B3 <- focal(imagen[[3]],                                   # Banda green 
                      w = matrix(1, 3,3),
                      fun = median)

filtro_mediana3 <- c(filtro_mediana3_B1, filtro_mediana3_B2, filtro_mediana3_B3)
filtro_mediana3
## class       : SpatRaster 
## dimensions  : 507, 848, 3  (nrow, ncol, nlyr)
## resolution  : 9.217891e-05, 9.217891e-05  (x, y)
## extent      : -4.320218, -4.242051, 56.45366, 56.50039  (xmin, xmax, ymin, ymax)
## coord. ref. : lon/lat WGS 84 (EPSG:4326) 
## source(s)   : memory
## varnames    : sentinel 
##               sentinel 
##               sentinel 
## names       : focal_median, focal_median, focal_median 
## min values  :       0.0001,       0.0001,       0.0008 
## max values  :       0.7777,       0.2682,       0.2794
  • Idem con un kernel de 5x5.
filtro_mediana5_B1 <- focal(imagen[[1]],                                   # Banda NIR
                      w = matrix(1,5,5),
                      fun = median)

filtro_mediana5_B2 <- focal(imagen[[2]],                                   # Banda red
                      w = matrix(1,5,5),
                      fun = median)

filtro_mediana5_B3 <- focal(imagen[[3]],                                   # Banda green 
                      w = matrix(1,5,5),
                      fun = median)

filtro_mediana5 <- c(filtro_mediana5_B1, filtro_mediana5_B2, filtro_mediana5_B3)
filtro_mediana5
## class       : SpatRaster 
## dimensions  : 507, 848, 3  (nrow, ncol, nlyr)
## resolution  : 9.217891e-05, 9.217891e-05  (x, y)
## extent      : -4.320218, -4.242051, 56.45366, 56.50039  (xmin, xmax, ymin, ymax)
## coord. ref. : lon/lat WGS 84 (EPSG:4326) 
## source(s)   : memory
## varnames    : sentinel 
##               sentinel 
##               sentinel 
## names       : focal_median, focal_median, focal_median 
## min values  :       0.0001,       0.0001,       0.0014 
## max values  :       0.7605,       0.1660,       0.1520
  • Idem con un kernel de 25x25
filtro_mediana25_B1 <- focal(imagen[[1]],                                   # Banda NIR
                      w = matrix(1,25,25),
                      fun = median)

filtro_mediana25_B2 <- focal(imagen[[2]],                                   # Banda red
                      w = matrix(1,25,25),
                      fun = median)

filtro_mediana25_B3 <- focal(imagen[[3]],                                   # Banda green 
                      w = matrix(1,25,25),
                      fun = median)

filtro_mediana25 <- c(filtro_mediana25_B1, filtro_mediana25_B2, filtro_mediana25_B3)
filtro_mediana25
## class       : SpatRaster 
## dimensions  : 507, 848, 3  (nrow, ncol, nlyr)
## resolution  : 9.217891e-05, 9.217891e-05  (x, y)
## extent      : -4.320218, -4.242051, 56.45366, 56.50039  (xmin, xmax, ymin, ymax)
## coord. ref. : lon/lat WGS 84 (EPSG:4326) 
## source(s)   : memory
## varnames    : sentinel 
##               sentinel 
##               sentinel 
## names       : focal_median, focal_median, focal_median 
## min values  :       0.0001,       0.0008,       0.0022 
## max values  :       0.6741,       0.1127,       0.0870

Una vez obtenidos los ficheros filtrados, crearemos a continuación una imagen en falso color de las imágenes fitradas para comparar el efecto del tramaño de los kernel.

# Una fila, dos columnas
par(mfrow = c(2, 2))

plotRGB(filtro_mediana3,
        stretch="lin",
        main = "Imagen filtrada. Mediana con kernel 3x3",
        axes = TRUE)

plotRGB(filtro_mediana5,
        stretch="lin",
        main = "Imagen filtrada. Mediana con kernel 5x5",
        axes = TRUE)

plotRGB(filtro_mediana25,
        stretch="lin",
        main = "Imagen filtrada. Promedio con kernel 25x25",
        axes = TRUE)

# Volvemos al estado original
par(mfrow = c(1, 1))

Puede comprobarse cómo un incremento del kernel supone una imagen progresivamene más difusa.

En caso de necesidad de limpiar el Global Environment, se eliminarán los siguientes objetos

rm(filtro_mediana3_B1, filtro_mediana3_B2, filtro_mediana3_B3, filtro_mediana3, 
   filtro_mediana5_B1, filtro_mediana5_B2, filtro_mediana5_B3, filtro_mediana5,
   filtro_mediana25_B1, filtro_mediana25_B2, filtro_mediana25_B3, filtro_mediana25)

Filtro gaussiano

El Kernel del filtro gaussiano usa tiene una distribución gaussiana o en forma de campana. El usuario debe debe diseñar la matriz kernel gaussiana del tamaño deseado, ya que no existe una función específica para ella.

Las siguientes líneas de código crean una matriz con un filtro gaussiano de 5x5

matriz_gaus <- matrix(c(1,4,7,4,1,4,16,26,16,4,7,26,41,26,7,4,16,26, 16,4,1,4,7,4,1), 
               nrow= 5) / 273
matriz_gaus                                                         # Atributos
##             [,1]       [,2]       [,3]       [,4]        [,5]
## [1,] 0.003663004 0.01465201 0.02564103 0.01465201 0.003663004
## [2,] 0.014652015 0.05860806 0.09523810 0.05860806 0.014652015
## [3,] 0.025641026 0.09523810 0.15018315 0.09523810 0.025641026
## [4,] 0.014652015 0.05860806 0.09523810 0.05860806 0.014652015
## [5,] 0.003663004 0.01465201 0.02564103 0.01465201 0.003663004

A continuación se aplica el filtro gaussiano a cada banda del ráster

filtro_gaus_B1 <- focal(imagen[[1]], 
                        w = matriz_gaus) 
filtro_gaus_B2 <- focal(imagen[[2]], 
                        w = matriz_gaus) 
filtro_gaus_B3 <- focal(imagen[[3]], 
                        w = matriz_gaus) 

Tras ello, se crea un SpatRaster con las bandas ya filtradas y se visualizan sus atributos:

filtro_gaus <- c(filtro_gaus_B1, filtro_gaus_B2, filtro_gaus_B3)
filtro_gaus 
## class       : SpatRaster 
## dimensions  : 507, 848, 3  (nrow, ncol, nlyr)
## resolution  : 9.217891e-05, 9.217891e-05  (x, y)
## extent      : -4.320218, -4.242051, 56.45366, 56.50039  (xmin, xmax, ymin, ymax)
## coord. ref. : lon/lat WGS 84 (EPSG:4326) 
## source(s)   : memory
## varnames    : sentinel 
##               sentinel 
##               sentinel 
## names       : focal_sum,    focal_sum, focal_sum 
## min values  : 0.0001000, 0.0002212454, 0.0013000 
## max values  : 0.7583498, 0.2030787552, 0.2153136

Finalmente, se representa gráficamente el objeto ráster resultante.

plotRGB(filtro_gaus,
        stretch = "lin", 
        axes =TRUE,
        main = "Filtro Gaussiano")

En caso de necesidad de limpiar el Global Environment, se eliminarán los siguientes objetos

rm(matriz_gaus, filtro_gaus_B1, filtro_gaus_B2, filtro_gaus_B3, filtro_gaus)

FILTROS DE PASO ALTO

Los filtros de realce (o de paso alto) tienen el efecto contrario al de los de paso bajo, ya que acentúan las diferencias entre píxeles adyacentes (efecto de enfoque), lo que aumenta la definición de las imágenes. Si se compara con la imagen original, se aprecia una separación más clara entre las tonalidades de píxeles contiguos, cuya diferencia se acentúa.

Los filtros de paso alto se utilizan para agudizar la imagen de trama mejorando el contraste entre áreas adyacentes. Este tipo de filtros retiene la información de alta frecuencia y reduce la información de baja frecuencia, enfatizando los detalles más finos en la imagen.

Imagen tras la aplicación de un filtro de realce Tomado de https://volaya.github.io/libro-sig/index.html

El paquete raster no tiene ninguna función específica para aplicar este tipo de filtros, por lo que es necesario crear una matriz kernel para realizar esa tarea. La matriz kernel deberá ser diseñada para que está diseñada de tal manera que cree un único valor positivo en el centro rodeado de valores negativos, disposición que aumenta el valor de brillo del píxel central en relación con circundantes.

Crea y muestra una matriz kernel de paso alto de 3x3.

matriz_pa <- matrix(c(-1,-1,-1,-1,9,-1,-1,-1,-1), 
               nrow =3)
matriz_pa                                         
##      [,1] [,2] [,3]
## [1,]   -1   -1   -1
## [2,]   -1    9   -1
## [3,]   -1   -1   -1

Aplicación del filtro a cada banda de la imagen.

filtro_pa_B1 <- focal(imagen[[1]], 
                    w = matriz_pa) 
filtro_pa_B2 <- focal(imagen[[2]], 
                    w = matriz_pa) 
filtro_pa_B3 <- focal(imagen[[3]], 
                    w = matriz_pa) 

Creación de un SpatRastercon las capas filtradas, mostrando sus atributos y se traza una imagen filtrada en falso color

filtro_pa <- c(filtro_pa_B1, filtro_pa_B2, filtro_pa_B3)
filtro_pa
## class       : SpatRaster 
## dimensions  : 507, 848, 3  (nrow, ncol, nlyr)
## resolution  : 9.217891e-05, 9.217891e-05  (x, y)
## extent      : -4.320218, -4.242051, 56.45366, 56.50039  (xmin, xmax, ymin, ymax)
## coord. ref. : lon/lat WGS 84 (EPSG:4326) 
## source(s)   : memory
## varnames    : sentinel 
##               sentinel 
##               sentinel 
## names       : focal_sum, focal_sum, focal_sum 
## min values  :   -1.5701,   -0.5586,   -0.4940 
## max values  :    2.1804,    1.3243,    1.5965
plotRGB(filtro_pa, 
        stretch ='lin', 
        axes =TRUE, 
        main = "Filtro de alta frecuencia") 

La imagen salida enfatiza las áreas de alta frecuencia y los detalles más finos, creando así un efecto de nitidez.

En caso de necesidad de limpiar el Global Environment, se eliminarán los siguientes objetos

rm(matriz_pa, filtro_pa_B1, filtro_pa_B2, filtro_pa_B3, filtro_pa)

FILTROS DE DETECCIÓN DE BORDES

Los bordes de las imágenes se caracterizan por cambios bruscos en los valores de brillo entre píxeles adyacentes, estando orientado a delimitar con claridad bordes. Los filtros de mejora de bordes pueden ser direccionales, es decir, mejorar los bordes en una dirección específica (pe. filtros horizontales, verticales y diagonales), o no direccionales, es decir, orientados a mejorar los bordes independientemente de la dirección (pe. filtro laplaciano).

Filtro de detección de bordes lineal.

Este tipo de filtro mejora los bordes mediante un algoritmo de primera diferencia direccional que aproxima la primera derivada entre píxeles adyacentes. Estos filtros resaltan el gradiente en una dirección particular. La matriz de filtro de mejora de borde lineal se puede diseñar colocando los signos -1 y + 1 en la dirección en la que desea mejorar los bordes.

Creación de una matriz en dirección este.

matriz_filtro_borde_lineal <- matrix(c(0,1,0,0,0,0,0,-1,0), 
                               nrow =3)
matriz_filtro_borde_lineal 
##      [,1] [,2] [,3]
## [1,]    0    0    0
## [2,]    1    0   -1
## [3,]    0    0    0

Aplicación del filtro a cada banda de la imagen y creación de un RasterBrickcon las capas filtradas.

filtro_borde_lineal_B1 = focal(imagen[[1]], 
                               w = matriz_filtro_borde_lineal) 
filtro_borde_lineal_B2 = focal(imagen[[2]], 
                               w = matriz_filtro_borde_lineal) 
filtro_borde_lineal_B3 = focal(imagen[[3]], 
                               w = matriz_filtro_borde_lineal)
filtro_borde_lineal <- c(filtro_borde_lineal_B1, filtro_borde_lineal_B2, filtro_borde_lineal_B3)
filtro_borde_lineal
## class       : SpatRaster 
## dimensions  : 507, 848, 3  (nrow, ncol, nlyr)
## resolution  : 9.217891e-05, 9.217891e-05  (x, y)
## extent      : -4.320218, -4.242051, 56.45366, 56.50039  (xmin, xmax, ymin, ymax)
## coord. ref. : lon/lat WGS 84 (EPSG:4326) 
## source(s)   : memory
## varnames    : sentinel 
##               sentinel 
##               sentinel 
## names       : focal_sum, focal_sum, focal_sum 
## min values  :    -0.463,   -0.2596,   -0.2233 
## max values  :     0.421,    0.1561,    0.1850

Representación gráfica mediante falso color

plotRGB(filtro_borde_lineal, 
        stretch =' lin', 
        axes =TRUE, 
        main ='Filtro con intensificación lineal del borde') 

En caso de necesidad de limpiar el Global Environment, se eliminarán los siguientes objetos

rm(matriz_filtro_borde_lineal, filtro_borde_lineal_B1, filtro_borde_lineal_B2, filtro_borde_lineal_B3, filtro_borde_lineal)

Filtro Prewitt

El filtro de Prewitt se utiliza para la detección de bordes en dirección vertical y horizontal por separado mediante el uso de dos kernels de 3x3, uno con dirección horizontal y otro vertical, para calcular aproximaciones de las derivadas. Los bordes se calculan utilizando la diferencia entre los valores de brillo de píxeles correspondientes de una imagen

Aplicación de un filtro de Sobel vertical (a) y horizontal (b) Tomado de https://volaya.github.io/libro-sig/index.html

Primero se creará una matriz horizontal

matriz_filtro_prewitt_horizontal <- matrix(c(-1,0,1, -1,0,1,-1,0,1),
                                           nrow =3)
matriz_filtro_prewitt_horizontal 
##      [,1] [,2] [,3]
## [1,]   -1   -1   -1
## [2,]    0    0    0
## [3,]    1    1    1

Aplicación del filtro a cada banda de la imagen.

filtro_prewitt_horizontal_B1 = focal(imagen[[1]], 
                               w = matriz_filtro_prewitt_horizontal) 
filtro_prewitt_horizontal_B2 = focal(imagen[[2]], 
                               w = matriz_filtro_prewitt_horizontal) 
filtro_prewitt_horizontal_B3 = focal(imagen[[3]], 
                               w = matriz_filtro_prewitt_horizontal) 

Creación de un SpatRaster con las capas filtradas y representación gráfica mediante falso color

filtro_prewitt_horizontal <- c(filtro_prewitt_horizontal_B1, filtro_prewitt_horizontal_B2,
                                  filtro_prewitt_horizontal_B3)
filtro_prewitt_horizontal
## class       : SpatRaster 
## dimensions  : 507, 848, 3  (nrow, ncol, nlyr)
## resolution  : 9.217891e-05, 9.217891e-05  (x, y)
## extent      : -4.320218, -4.242051, 56.45366, 56.50039  (xmin, xmax, ymin, ymax)
## coord. ref. : lon/lat WGS 84 (EPSG:4326) 
## source(s)   : memory
## varnames    : sentinel 
##               sentinel 
##               sentinel 
## names       : focal_sum, focal_sum, focal_sum 
## min values  :   -1.4792,   -0.7510,   -0.6875 
## max values  :    1.2971,    0.7424,    0.6990
#plotRGB(filtro_prewitt_horizontal, 
#        stretch =' lin', 
#        axes =TRUE, 
#        main ='Filtro con intensificación Prewitt en horizontal') 

La máscara horizontal del filtro Prewitt ha detectado los bordes en la dirección horizontal.

De manera similar, podemos aplicar el filtro Prewitt en la dirección vertical como se muestra en el siguiente ejemplo de código.

matriz_filtro_prewitt_vertical <- matrix(c(-1,-1,-1,0,0,0,1,1,1), 
              nrow=3)
matriz_filtro_prewitt_vertical                                  
##      [,1] [,2] [,3]
## [1,]   -1    0    1
## [2,]   -1    0    1
## [3,]   -1    0    1

Apply vertical Prewitt filter to each band of the input raster

filtro_prewitt_vertical_B1 =focal(imagen[[1]], 
                                  w =matriz_filtro_prewitt_vertical) 
filtro_prewitt_vertical_B2 =focal(imagen[[2]], 
                                  w =matriz_filtro_prewitt_vertical) 
filtro_prewitt_vertical_B3 =focal(imagen[[3]], 
                                  w =matriz_filtro_prewitt_vertical) 

Creación de un SpatRaster con las capas filtradas y representación gráfica mediante falso color

filtro_prewitt_vertical <- c(filtro_prewitt_vertical_B1, filtro_prewitt_vertical_B2, filtro_prewitt_vertical_B3)
filtro_prewitt_vertical
## class       : SpatRaster 
## dimensions  : 507, 848, 3  (nrow, ncol, nlyr)
## resolution  : 9.217891e-05, 9.217891e-05  (x, y)
## extent      : -4.320218, -4.242051, 56.45366, 56.50039  (xmin, xmax, ymin, ymax)
## coord. ref. : lon/lat WGS 84 (EPSG:4326) 
## source(s)   : memory
## varnames    : sentinel 
##               sentinel 
##               sentinel 
## names       : focal_sum, focal_sum, focal_sum 
## min values  :   -1.0558,   -0.3711,   -0.3518 
## max values  :    1.3247,    0.5551,    0.4748
plotRGB(filtro_prewitt_vertical, 
        stretch ='lin', 
        axes =TRUE, 
        main = "Filtro con intensificación Prewit en vertical")

En caso de necesidad de limpiar el Global Environment, se eliminarán los siguientes objetos

rm(matriz_filtro_prewitt_vertical, filtro_prewitt_vertical_B1, filtro_prewitt_vertical_B2, filtro_prewitt_vertical_B3, filtro_prewitt_vertical,
   matriz_filtro_prewitt_horizontal, filtro_prewitt_horizontal_B1, filtro_prewitt_horizontal_B2, filtro_prewitt_horizontal_B3, filtro_prewitt_horizontal)

Filtro Sobel

El filtro Sobel realiza una mejora de bordes no lineal. Es similar al filtro de Prewitt, ya que ambos calculan aproximaciones de las derivadas, pero los coeficientes no son fijos en el filtro de Sobel a diferencia del filtro de Prewitt. Por lo tanto, el usuario puede modificar los coeficientes siempre que la máscara o matriz de filtro conserve las propiedades derivadas.

Aplicación de un filtro de Sobel vertical (a) y horizontal (b) Tomado de https://volaya.github.io/libro-sig/index.html

La máscara derivada tiene las siguientes propiedades:

  • El signo opuesto debe estar presente en la máscara.
  • La suma de la máscara debe ser cero.
  • La adición de más pesos dan como resultado una mayor detección de bordes en la imagen.

Filtro Sobel Tomado de https://volaya.github.io/libro-sig/index.html

Los filtros Sobel para las direcciones vertical y horizontal junto con un filtro que tiene mayor peso se aplican a la imagen ráster en los siguientes ejemplos de código R.

matriz_filtro_sobel_vertical <- matrix(c(-1,-2,-1,0,0,0,1,2,1), 
                                nrow=3)
matriz_filtro_sobel_vertical
##      [,1] [,2] [,3]
## [1,]   -1    0    1
## [2,]   -2    0    2
## [3,]   -1    0    1

Aplicación del filtro vertical a cada banda de la imagen.

filtro_sobel_vertical_B1 <- focal(imagen[[1]], 
                                  w = matriz_filtro_sobel_vertical) 
filtro_sobel_vertical_B2 <- focal(imagen[[2]], 
                                  w = matriz_filtro_sobel_vertical)
filtro_sobel_vertical_B3 <- focal(imagen[[3]], 
                                  w = matriz_filtro_sobel_vertical)

Creación de un SpatRastercon las capas filtradas y representación gráfica mediante falso color

filtro_sobel_vertical_conjunto <- c(filtro_sobel_vertical_B1, filtro_sobel_vertical_B2, filtro_sobel_vertical_B3)
filtro_sobel_vertical_conjunto
## class       : SpatRaster 
## dimensions  : 507, 848, 3  (nrow, ncol, nlyr)
## resolution  : 9.217891e-05, 9.217891e-05  (x, y)
## extent      : -4.320218, -4.242051, 56.45366, 56.50039  (xmin, xmax, ymin, ymax)
## coord. ref. : lon/lat WGS 84 (EPSG:4326) 
## source(s)   : memory
## varnames    : sentinel 
##               sentinel 
##               sentinel 
## names       : focal_sum, focal_sum, focal_sum 
## min values  :   -1.4465,   -0.5036,   -0.5368 
## max values  :    1.7757,    0.8147,    0.6981
plotRGB(filtro_sobel_vertical_conjunto, 
        stretch ='lin', 
        axes =TRUE, 
        main ='Máscara vertical de un filtro Sobel')

A continuación se aplicará una máscara horizontal del filtro Sobel.

matriz_filtro_sobel_horizontal  <- matrix(c(-1,0,1,-2,0,2,-1,0,1), 
              nrow=3)
matriz_filtro_sobel_horizontal
##      [,1] [,2] [,3]
## [1,]   -1   -2   -1
## [2,]    0    0    0
## [3,]    1    2    1

Aplicación del filtro horizontal a cada banda de la imagen, seguido de la creación de un SpatRaster con las capas filtradas y de la representación gráfica mediante falso color

filtro_sobel_horizontal_B1 <- focal(imagen[[1]], w = matriz_filtro_sobel_horizontal) 
filtro_sobel_horizontal_B2 <- focal(imagen[[2]], w = matriz_filtro_sobel_horizontal) 
filtro_sobel_horizontal_B3 <- focal(imagen[[3]], w = matriz_filtro_sobel_horizontal) 

filtro_sobel_horizontal_conjunto <- c(filtro_sobel_horizontal_B1, filtro_sobel_horizontal_B2, filtro_sobel_horizontal_B3)

filtro_sobel_horizontal_conjunto
## class       : SpatRaster 
## dimensions  : 507, 848, 3  (nrow, ncol, nlyr)
## resolution  : 9.217891e-05, 9.217891e-05  (x, y)
## extent      : -4.320218, -4.242051, 56.45366, 56.50039  (xmin, xmax, ymin, ymax)
## coord. ref. : lon/lat WGS 84 (EPSG:4326) 
## source(s)   : memory
## varnames    : sentinel 
##               sentinel 
##               sentinel 
## names       : focal_sum, focal_sum, focal_sum 
## min values  :   -1.9857,   -1.0271,   -0.9495 
## max values  :    1.7328,    0.9968,    0.9462
plotRGB(filtro_sobel_horizontal_conjunto, 
        stretch ='lin', 
        axes =TRUE,
        main ='Máscara horizontal del filtro Sobel')

La imagen falso color filtrada con el filtro Sobel detecta los bordes horizontales.

En tercer lugar, se elaborará una máscara horizontal con un filtro sobre con mayor ponderación.

matriz_filtro_sobel_horizontal_ponderada <- matrix(c(-1,0,1,-5,0,5,-1,0,1), 
             nrow=3)
matriz_filtro_sobel_horizontal_ponderada
##      [,1] [,2] [,3]
## [1,]   -1   -5   -1
## [2,]    0    0    0
## [3,]    1    5    1

Aplicación del filtro Sobel ponderado, creación del SpatRastercon las capas filtradas y representación gráfica mediante falso color.

filtro_sobel_horizontal_ponderado_B1 <- focal(imagen[[1]], 
                                              w = matriz_filtro_sobel_horizontal_ponderada) 
filtro_sobel_horizontal_ponderado_B2 <- focal(imagen[[2]], 
                                              w = matriz_filtro_sobel_horizontal_ponderada) 
filtro_sobel_horizontal_ponderado_B3 <- focal(imagen[[3]], 
                                              w = matriz_filtro_sobel_horizontal_ponderada) 

filtro_sobel_horizontal_ponderado <- c(filtro_sobel_horizontal_ponderado_B1, filtro_sobel_horizontal_ponderado_B2, filtro_sobel_horizontal_ponderado_B3)
filtro_sobel_horizontal_ponderado
## class       : SpatRaster 
## dimensions  : 507, 848, 3  (nrow, ncol, nlyr)
## resolution  : 9.217891e-05, 9.217891e-05  (x, y)
## extent      : -4.320218, -4.242051, 56.45366, 56.50039  (xmin, xmax, ymin, ymax)
## coord. ref. : lon/lat WGS 84 (EPSG:4326) 
## source(s)   : memory
## varnames    : sentinel 
##               sentinel 
##               sentinel 
## names       : focal_sum, focal_sum, focal_sum 
## min values  :   -3.5052,   -1.8602,   -1.7499 
## max values  :    3.2327,    1.7600,    1.6878
plotRGB(filtro_sobel_horizontal_ponderado, 
        stretch ='lim', 
        axes =TRUE, 
        main ='Filtro horizontal Sobel con incremento de ponderación')

En la imagen filtrada en falso color el aumento de los pesos del filtro Sobel detecta más bordes en la dirección horizontal.

En caso de necesidad de limpiar el Global Environment, se eliminarán los siguientes objetos

rm(matriz_filtro_sobel_vertical, filtro_sobel_vertical_B1, filtro_sobel_vertical_B2, filtro_sobel_verticalb3, brick_filtro_sobel_vertical,  matriz_filtro_sobel_horizontal, filtro_sobel_horizontal_B1, filtro_sobel_vhorizontal_B2, filtro_sobel_horizontal_B3, brick_filtro_sobel_horizontal,
   matriz_filtro_sobel_horizontal_ponderada, filtro_sobel_horizontal_ponderado_B1, filtro_sobel_horizontal_ponderado_B2, filtro_sobel_horizontal_ponderado_B3, filtro_sobel_horizontal_ponderado)
## Warning in rm(matriz_filtro_sobel_vertical, filtro_sobel_vertical_B1,
## filtro_sobel_vertical_B2, : objeto 'filtro_sobel_verticalb3' no encontrado
## Warning in rm(matriz_filtro_sobel_vertical, filtro_sobel_vertical_B1,
## filtro_sobel_vertical_B2, : objeto 'brick_filtro_sobel_vertical' no encontrado
## Warning in rm(matriz_filtro_sobel_vertical, filtro_sobel_vertical_B1,
## filtro_sobel_vertical_B2, : objeto 'filtro_sobel_vhorizontal_B2' no encontrado
## Warning in rm(matriz_filtro_sobel_vertical, filtro_sobel_vertical_B1,
## filtro_sobel_vertical_B2, : objeto 'brick_filtro_sobel_horizontal' no
## encontrado

Filtro laplaciano

El filtro laplaciano es un filtro no direccional que calcula derivadas de segundo orden a partir de la imagen original. Por lo tanto, ayuda a determinar si el cambio en los valores de píxeles adyacentes es un borde o una progresión continua. El kernel (núcleo) del filtro laplaciano contiene valores negativos en el centro y cero o valores positivos en las esquinas, como aparece a continuación:

matriz_filtro_laplaciano <- matrix(c(0,-1,0,-1,4,-1,0,-1,0), 
              nrow=3 )
matriz_filtro_laplaciano
##      [,1] [,2] [,3]
## [1,]    0   -1    0
## [2,]   -1    4   -1
## [3,]    0   -1    0

Filtro laplaciano Tomado de https://volaya.github.io/libro-sig/index.html

Aplicación del filtro a cada banda del ráster.

filtro_laplaciano_B1 <- focal(imagen[[1]], w= matriz_filtro_laplaciano)
filtro_laplaciano_B2 <- focal(imagen[[2]], w= matriz_filtro_laplaciano)
filtro_laplaciano_B3 <- focal(imagen[[3]], w= matriz_filtro_laplaciano)

Creación de un SpatRastercon las capas filtradas y representación gráfica mediante falso color.

filtro_laplaciano_conjunto <- c(filtro_laplaciano_B1, filtro_laplaciano_B2, filtro_laplaciano_B3)
filtro_laplaciano_conjunto
## class       : SpatRaster 
## dimensions  : 507, 848, 3  (nrow, ncol, nlyr)
## resolution  : 9.217891e-05, 9.217891e-05  (x, y)
## extent      : -4.320218, -4.242051, 56.45366, 56.50039  (xmin, xmax, ymin, ymax)
## coord. ref. : lon/lat WGS 84 (EPSG:4326) 
## source(s)   : memory
## varnames    : sentinel 
##               sentinel 
##               sentinel 
## names       : focal_sum, focal_sum, focal_sum 
## min values  :   -0.7670,   -0.2280,   -0.1947 
## max values  :    0.7426,    0.3915,    0.4922
plotRGB(filtro_laplaciano_conjunto, 
        stretch = 'lin', 
        axes = TRUE, main = "Filtro laplaciano")

La imagen filtrada en falso color muestra que el filtro laplaciano resalta puntos, líneas y bordes, suprimiendo las regiones uniformes y que varían suavemente.

En caso de necesidad de limpiar el Global Environment, se eliminarán los siguientes objetos

rm(matriz_filtro_laplaciano, filtro_laplaciano_B1, filtro_laplaciano_B2, filtro_laplaciano_B3, filtro_laplaciano_conjunto)

Filtro Diagonal

El filtro diagonal realza los bordes en dirección diagonal, mientras que efectúa un realce parcial de los bordes en ambas direcciones horizontal y vertical.

matriz_filtro_diagonal <- matrix(c(0,-1,-1,1,0,-1,1,1,0), 
                                 nrow =3)
matriz_filtro_diagonal
##      [,1] [,2] [,3]
## [1,]    0    1    1
## [2,]   -1    0    1
## [3,]   -1   -1    0

Aplicación del filtro a cada banda del ráster.

filtro_diagonal_B1 <- focal(imagen[[1]], w = matriz_filtro_diagonal) 
filtro_diagonal_B2 <- focal(imagen[[2]], w = matriz_filtro_diagonal) 
filtro_diagonal_B3 <- focal(imagen[[3]], w = matriz_filtro_diagonal) 

Creación de un RasterBrickcon las capas filtradas y representación gráfica mediante falso color.

filtro_diagonal_conjunto <- c(filtro_diagonal_B1, filtro_diagonal_B2, filtro_diagonal_B3)
filtro_diagonal_conjunto
## class       : SpatRaster 
## dimensions  : 507, 848, 3  (nrow, ncol, nlyr)
## resolution  : 9.217891e-05, 9.217891e-05  (x, y)
## extent      : -4.320218, -4.242051, 56.45366, 56.50039  (xmin, xmax, ymin, ymax)
## coord. ref. : lon/lat WGS 84 (EPSG:4326) 
## source(s)   : memory
## varnames    : sentinel 
##               sentinel 
##               sentinel 
## names       : focal_sum, focal_sum, focal_sum 
## min values  :   -1.2031,   -0.5754,   -0.5395 
## max values  :    1.1784,    0.5647,    0.5166
plotRGB(filtro_diagonal_conjunto, 
        stretch ='lin', 
        axes =TRUE, 
        main ='Mejora de los bordes en diagonal')

La imagen filtrada en falso color muestra que los bordes en diagonal se resaltan.

En caso de necesidad de limpiar el Global Environment, se eliminarán los siguientes objetos

rm(matriz_filtro_diagonal, filtro_diagonal_B1, filtro_diagonal_B2, filtro_diagonal_B3, filtro_diagonal_conjunto)

Filtro personalizado

También se puede crear un filtro personalizado de acuerdo con ciertos requisitos definiendo una matriz kernel con sus pesos correspondientes.

matriz_filtro_personal <- matrix(c(1,-2,1,-2,5,-2,1,-2,1), nrow =3)
matriz_filtro_personal 
##      [,1] [,2] [,3]
## [1,]    1   -2    1
## [2,]   -2    5   -2
## [3,]    1   -2    1

Se aplican los filtros y se crea un SpatRasterque luego se representa gráficamente.

filtro_personal_B1 <- focal(imagen[[1]], w = matriz_filtro_personal) 
filtro_personal_B2 <- focal(imagen[[2]], w = matriz_filtro_personal) 
filtro_personal_B3 <- focal(imagen[[3]], w = matriz_filtro_personal)
filtro_personal_conjunto <- c(filtro_personal_B1, filtro_personal_B2, filtro_personal_B3) 
filtro_personal_conjunto  
## class       : SpatRaster 
## dimensions  : 507, 848, 3  (nrow, ncol, nlyr)
## resolution  : 9.217891e-05, 9.217891e-05  (x, y)
## extent      : -4.320218, -4.242051, 56.45366, 56.50039  (xmin, xmax, ymin, ymax)
## coord. ref. : lon/lat WGS 84 (EPSG:4326) 
## source(s)   : memory
## varnames    : sentinel 
##               sentinel 
##               sentinel 
## names       : focal_sum, focal_sum,  focal_sum 
## min values  :   -0.5151,   -0.2114, -0.1942000 
## max values  :    1.1255,    0.5065,  0.5356001
plotRGB(filtro_personal_conjunto, 
        stretch ='lin', 
        axes =TRUE, main ='Filtro personalizado')

En caso de necesidad de limpiar el Global Environment, se eliminarán los siguientes objetos

rm(matriz_filtro_personal, filtro_personal_B1, filtro_personal_B2, filtro_personal_B3, filtro_personal_conjunto)