💡 OBJETIVOS DE LA ACTIVIDAD:
► Conocer los diversos procedimientos para mejorar el contraste de las imágenes.
► Saber aplicar los procedimientos para realzar las características de brillo y contraste de una imagen, reducir su ruido, o agudizar o intensificar detalles presentes en ella
💡 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.
Los sensores que portan los satélites están diseñados para recoger la energía o radiancia de una gran variedad de superficies, desde superficies acuáticas con baja radiancia hasta la nieve o la arena, que por el contrario muestran una gran radiancia. Por lo tanto, deben ser capaces de registrar la respuesta todas esas superficies, pero, en la mayoría de las ocasiones, tan sólo registran alguna de ellas. El que los valores de radiancia permanezcan confinados a un rango limitado reduce los contrastes de imagen, y por lo tanto, su calidad visual.
La mejora del contraste de una imagen digital es una técnica que modificar los niveles de grises originales de una imagen. Esto incrementa el contraste entre diferentes elementos de la imagen, lo cual a su vez mejora su calidad. Dentro de los diferentes métodos de mejora de contraste es posible diferenciar aquellos basados en métodos lineales y otros basados en métodos no lineales, cuyas diferentes metodologías serán revisadas en las siguientes líneas.
Las operaciones que componen esta técnica se dividen en operaciones de procesamiento pixel por pixel y operaciones de procesamiento por grupo de pixeles.
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
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.3.3
library(rasterVis)
## Warning: package 'rasterVis' was built under R version 4.3.2
## Loading required package: lattice
## Warning: package 'lattice' was built under R version 4.3.2
A continuación, se realiza una lista de los ficheros que existen en
la carpeta datos
.
lista <- list.files("D:/G174_2025/LABORATORIO_4_Visualizacion_imagenes/datos/",
pattern = ".*band[1234567]\\.tif$",
ignore.case=TRUE,
full.names = TRUE)
En tercer lugar, esa lista permite importar los ficheros en forma de
un objeto SpatRaster
.
imagen_landsat <- rast(lista)
imagen_landsat
## class : SpatRaster
## dimensions : 1545, 1480, 7 (nrow, ncol, nlyr)
## resolution : 30, 30 (x, y)
## extent : 549615, 594015, 4613355, 4659705 (xmin, xmax, ymin, ymax)
## coord. ref. : WGS 84 / UTM zone 29N (EPSG:32629)
## sources : LC82040312015193LGN00_sr_band1.tif
## LC82040312015193LGN00_sr_band2.tif
## LC82040312015193LGN00_sr_band3.tif
## ... and 4 more sources
## names : LC820~band1, LC820~band2, LC820~band3, LC820~band4, LC820~band5, LC820~band6, ...
Como ya se ha señalado en ocasiones previas, la identificación de las bandas es complicada si se mantienen los nombres de los archivos originales, siendo conveniente su transformación en nombres de más fácil identificación.
names(imagen_landsat) <- gsub(pattern = "LC82040312015193LGN00_sr_",
replace ="",
x <- names(imagen_landsat))
imagen_landsat
## class : SpatRaster
## dimensions : 1545, 1480, 7 (nrow, ncol, nlyr)
## resolution : 30, 30 (x, y)
## extent : 549615, 594015, 4613355, 4659705 (xmin, xmax, ymin, ymax)
## coord. ref. : WGS 84 / UTM zone 29N (EPSG:32629)
## sources : LC82040312015193LGN00_sr_band1.tif
## LC82040312015193LGN00_sr_band2.tif
## LC82040312015193LGN00_sr_band3.tif
## ... and 4 more sources
## names : band1, band2, band3, band4, band5, band6, ...
En este caso, sólo se necesitan las bandas 2, 3, 4 y 5 del objeto
imagen
, que tiene originalmente 7 bandas. Podemos proceder
de dos maneras alternativas.
► Eliminando del objeto anterior imagen_landsat
las
bandas 1, 6 y 7. El objeto sigue siendo un SpatRaster
.
imagen_landsat
## class : SpatRaster
## dimensions : 1545, 1480, 7 (nrow, ncol, nlyr)
## resolution : 30, 30 (x, y)
## extent : 549615, 594015, 4613355, 4659705 (xmin, xmax, ymin, ymax)
## coord. ref. : WGS 84 / UTM zone 29N (EPSG:32629)
## sources : LC82040312015193LGN00_sr_band1.tif
## LC82040312015193LGN00_sr_band2.tif
## LC82040312015193LGN00_sr_band3.tif
## ... and 4 more sources
## names : band1, band2, band3, band4, band5, band6, ...
imagen_contraste <- subset(imagen_landsat, -c(1,6,7))
imagen_contraste
## class : SpatRaster
## dimensions : 1545, 1480, 4 (nrow, ncol, nlyr)
## resolution : 30, 30 (x, y)
## extent : 549615, 594015, 4613355, 4659705 (xmin, xmax, ymin, ymax)
## coord. ref. : WGS 84 / UTM zone 29N (EPSG:32629)
## sources : LC82040312015193LGN00_sr_band2.tif
## LC82040312015193LGN00_sr_band3.tif
## LC82040312015193LGN00_sr_band4.tif
## LC82040312015193LGN00_sr_band5.tif
## names : band2, band3, band4, band5
► Una segunda posiblidad es cargar las 4 imágenes directamente de la carpeta donde están almacenadas, uniéndolas posteriormente en un único objeto..
lista <- list.files("D:/G174_2025/LABORATORIO_4_Visualizacion_imagenes/datos/", # Directorio de los datos
pattern = ".*band[2345]\\.tif$", # El signo $ lista todos los ficheros que acaban igual
ignore.case=TRUE, # Sensible a mayúsculas y minúsculas
full.names = TRUE)
imagen_contraste <- rast(lista)
De nuevo, cambiamos los nombres de las bandas para que sean más inteligibles.
names(imagen_contraste) <- paste("B",
2:5,
sep="")
imagen_contraste
## class : SpatRaster
## dimensions : 1545, 1480, 4 (nrow, ncol, nlyr)
## resolution : 30, 30 (x, y)
## extent : 549615, 594015, 4613355, 4659705 (xmin, xmax, ymin, ymax)
## coord. ref. : WGS 84 / UTM zone 29N (EPSG:32629)
## sources : LC82040312015193LGN00_sr_band2.tif
## LC82040312015193LGN00_sr_band3.tif
## LC82040312015193LGN00_sr_band4.tif
## LC82040312015193LGN00_sr_band5.tif
## names : B2, B3, B4, B5
También es posible cambiar las bandas a su denominación original.
names(imagen_contraste) <- c("blue", "green", "red", "nir")
imagen_contraste
## class : SpatRaster
## dimensions : 1545, 1480, 4 (nrow, ncol, nlyr)
## resolution : 30, 30 (x, y)
## extent : 549615, 594015, 4613355, 4659705 (xmin, xmax, ymin, ymax)
## coord. ref. : WGS 84 / UTM zone 29N (EPSG:32629)
## sources : LC82040312015193LGN00_sr_band2.tif
## LC82040312015193LGN00_sr_band3.tif
## LC82040312015193LGN00_sr_band4.tif
## LC82040312015193LGN00_sr_band5.tif
## names : blue, green, red, nir
A continuación, se representa gráficamente la distribución de los valores de los píxeles de cada banda usando el siguiente código.
histogram(imagen_contraste,
col = "wheat",
main = "Histograma de las bandas",
xlab = "Valores de los píxeles")
A partir de los histogramas de las bandas del fichero raster se comprueba cómo, efectivamente, los valores de los píxeles suelen estar confinados a rangos muy concretos. A continuación se representa una imagen en falso color para verificar su calidad visual.
ggRGB(imagen_contraste,
r=4, g=3, b=2,
stretch = "none") +
ggtitle("Imagen sin mejorar") + # Título
labs(x = "Longitud (m)", y = "Latitud (m)") + # Etiquetas de los ejes x e y
theme(plot.title = element_text(hjust = 0.5, size = 25), # Título alineado al centro y con tamaño de 25
axis.title = element_text(size=15)) + # Tamaños de las etiquetas ejes x e y
theme_minimal()
De acuerdo con la inspección visual de esa imagen, el contraste entre los elementos que lo componen es bajo. Por ello, sería conveniente aplicar algunas de la técnicas de mejora del contraste para mejorar a su vez la calidad visual de la imagen. Estas técnicas reciben el nombre de “estiramiento” (stretching)
Mediante las técnicas de mejora linear, los números digitales de las imágenes originales son expandidos linearmente al rango completo de los niveles de gris. Puede ser realizado con R, a través de dos métodos, el contraste entre Máximo-Mínimos, y el contraste con porcentajes.
Según este método, los valores máximo y mínimo de los píxeles de la imagen original se convierte en los valores máximo y mínimo del rango radiométrico total, y los valores reales se estiran linealmente entre esos valores preasignados.
ggRGB(imagen_contraste,
r=4, g=3, b=2,
stretch = "lin") +
ggtitle("Mejora de contraste, Método máx-mín") + # Título
labs(x = "Longitud (m)", y = "Latitud (m)") + # Etiquetas de los ejes x e y
theme(plot.title = element_text(hjust = 0.5, size = 25), # Título alineado al centro y con tamaño de 25
axis.title = element_text(size=15)) + # Tamaños de las etiquetas ejes x e y
theme_minimal()
Este método es similar al anterior, excepto que en este método los valores máximos y mínimos representan un cierto porcentaje de píxeles respecto a la media del histograma. Supóngase que se desea aplicar un estiramiento lineal del 2%; esto significa que el 2% de los valores más bajos y el 2% de los valores más altos del histograma serán omitidos mientras se aplica esta mejora de contraste.
ggRGB(imagen_contraste,
r=4, g=3, b=2,
stretch = "lin",
quantiles = c(0.02,0.98)) + # Porcentaje en forma de cuantiles
ggtitle("Mejora de contraste, método 2 %") + # Título
labs(x = "Longitud (m)", y = "Latitud (m)") + # Etiquetas de los ejes x e y
theme(plot.title = element_text(hjust = 0.5, size = 25), # Título alineado al centro y con tamaño de 25
axis.title = element_text(size=15)) + # Tamaños de las etiquetas ejes x e y
theme_minimal()
Estas técnicas no “estiran” de manera lineal los valores de los píxeles, sino mediante algún tipo de algorítmo no lineal. Existen varios tipos diferentes.
En este método, los valores de los píxeles son estirados dependiendo de su frecuencia en la imagen. A los valores de los píxeles que aparecen con más frecuencias se les asignan un rango de valores más amplio que a los que ocurren con menor frecuencia. Este método proporciona una mejora de los detalles de la imagen en aquellas zonas con valores que ocurren frecuentemente. Esta posibilidad está incluida tanto en el paquete raster como en RStoolbox
► Con el paquete terra.
plotRGB(imagen_contraste,
r=4, g=3, b=2,
stretch = "hist",
main = "Mejora de contraste a través de la ecualizacióndel histograma")
► Con el el paquete “RStoolbox”.
ggRGB(imagen_contraste,
r=4, g=3, b=2,
stretch = "hist") +
ggtitle("Mejora de contraste, método histograma") + # Título
labs(x = "Longitud (m)", y = "Latitud (m)") + # Etiquetas de los ejes x e y
theme(plot.title = element_text(hjust = 0.5, size = 25), # Título alineado al centro y con tamaño de 25
axis.title = element_text(size=15)) + # Tamaños de las etiquetas ejes x e y
theme_minimal()
Este método calcula la raíz cuadrada del histograma de la imagen
original y aplica un estiramiento lineal. Sirve para mejorar la parte
más oscura de la imagen. Se utiliza para ello el argumento
stretch = "sqrt"
en la función ggRGB del paquete
RStoolbox.
ggRGB(imagen_contraste,
r=4, g=3, b=2,
stretch = "sqrt") +
ggtitle("Mejora de contraste, método raíz cuadrada") + # Título
labs(x = "Longitud (m)", y = "Latitud (m)") + # Etiquetas de los ejes x e y
theme(plot.title = element_text(hjust = 0.5, size = 25), # Título alineado al centro y con tamaño de 25
axis.title = element_text(size=15)) + # Tamaños de las etiquetas ejes x e y
theme_minimal()
El método de estiramiento logarítmico reescala los valores originales
de los píxeles de manera logarítmica, es decir, asigna a los valores más
bajos un conjunto más amplio de nuevos valores, mientras que los píxeles
originales con valores elevados reciben un rango de valores menor. Este
método mejor los detalles de las áreas más oscuras de la imagen. Se
utiliza para ello el argumento stretch = "log"
en la función
ggRGB del paquete RStoolbox.
ggRGB(imagen_contraste,
r=4, g=3, b=2,
stretch = "log") +
ggtitle("Mejora de contraste, método logarítmico") + # Título
labs(x = "Longitud (m)", y = "Latitud (m)") + # Etiquetas de los ejes x e y
theme(plot.title = element_text(hjust = 0.5, size = 25), # Título alineado al centro y con tamaño de 25
axis.title = element_text(size=15)) + # Tamaños de las etiquetas ejes x e y
theme_minimal()
En este caso, el histograma de los valores de la imagen original es
modificado para que se parezca a un histograma que sigue una
distribución “normal” o gaussiAna.Se utiliza para ello el argumento
norme = "TRUE"
en la función normImage
del
paquete RStoolbox.
imagen_normalizada <- normImage(imagen_contraste, norm = TRUE)
imagen_normalizada
## class : SpatRaster
## dimensions : 1545, 1480, 4 (nrow, ncol, nlyr)
## resolution : 30, 30 (x, y)
## extent : 549615, 594015, 4613355, 4659705 (xmin, xmax, ymin, ymax)
## coord. ref. : WGS 84 / UTM zone 29N (EPSG:32629)
## source(s) : memory
## names : blue, green, red, nir
## min values : -1.972773, -2.565205, -2.141667, -3.997184
## max values : 17.135898, 16.460832, 13.083512, 5.169301
Posteriormente, podemos representarlo gráficamente. Téngase en cuenta
que el argumento strech =
ya no debe utilizarse aquí.
ggRGB(imagen_normalizada,
r=4, g=3, b=2) +
ggtitle("Mejora de contraste, método gaussiano") + # Título
labs(x = "Longitud (m)", y = "Latitud (m)") + # Etiquetas de los ejes x e y
theme(plot.title = element_text(hjust = 0.5, size = 25), # Título alineado al centro y con tamaño de 25
axis.title = element_text(size=15)) + # Tamaños de las etiquetas ejes x e y
theme_minimal()
Dado que no se utilizará más los objetos creados hasta aquí, son eliminados del Global Environment para que no interfieran en el resto de la actividad
rm(list=ls())