Los procedimientos que se explicarán en este apartado son útiles para excluir aquellas áreas de las imágenes de satélite que no interesan para su análisis posterior. Con ello, se aligera su “peso”, lo que redunda en una mayor velocidad de procesamiento.
Aunque aparentemente es una acción inocua, conviene tener en cuenta ciertos aspectos que pueden generar problemas. Por ejemplo, en una determinada composición RGB (por ejemplo a color natural o falso color), el recorte afectará a todas las bandas que componen la imagen multibanda; esto influye en la profundidad de píxel de la nueva escena resultante. Si se emplean formatos de archivos (JPG, TIF, PNG, JP2, ECW…) con profundidad de píxel diferente a la del archivo original los valores originales del píxel también variarán, produciendo imágenes con contrastes cromáticos diferentes a los originales.
La resolución espacial de la imagen será otro de los factores a tener en cuenta y determinará un mayor o menor suavizado en los bordes de la imagen en función de la escala. Con imágenes de alta resolución espacial los límites de la imagen recortada serán más límpios que los de imágenes con píxeles de gran tamaño, porque un píxel no puede cortarse por la mitad.
Para recortar, además del fichero ráster que va a ser modificado, es
necesario disponer de otro fichero con los límites de la región de
interés. Este último puede estar en formato ráster
(RasterLayer
) o en formato vectorial (objetos
sf
), siendo lo último los más frecuente. Para conocer
diferentes formas de obtener ese fichero con los límites de la región de
interés (ROI, “region of interest” en inglés) puede consultarse la
página delimitacion_ROI
Por último, cabe mencionar que el recorte se puede efectuar de dos maneras:
Recorte espacial: es el más habitual, y tiene por objeto reducir el área original de la imagen raster a un zona de tamaño más reducido.
Recorte espectral: cuyo objetivo es trabajar con un número reducido de bandas espectrales, extraídas de una imagen raster multibanda.
Este tipo de recorte es una labor muy frecuente cuando deseamos trabajar con una área mucho más pequeña que la escena original (el tamaño de una imagen Landsat es de unos 170 km x 185 km, es decir, unoas 31450 \(km^2\)). Con ello se ahorra espacio de almacenamiento y tiempo de procesamiento. Los procedimientos son muy diversos, por lo que el investigador puede elegir el más conveniente para sus intereses.
Como en casos anteriores, vamos a trabajar con varios paquetes de R, que debemos activar.
library(raster)
## Loading required package: sp
library(sf)
## Linking to GEOS 3.11.1, GDAL 3.6.2, PROJ 9.1.1; sf_use_s2() is TRUE
Como en capítulos precedentes, se creará un objeto ráster, ahora formado por 625 píxeles, a las que se incorporarán las coordenadas geográficas.
<- raster(ncol= 25, # Número de columnas del ráster
raster nrow= 25, # Número de filas
xmx= -2,xmn= -5, # Coordenadas del eje X (considerémoslas la longitud)
ymx= 42,ymn= 39) # Coordenadas del eje y (idem latitud)
values(raster) <- as.integer(runif(ncell(raster),
min = 1,
max= 10))
raster
## class : RasterLayer
## dimensions : 25, 25, 625 (nrow, ncol, ncell)
## resolution : 0.12, 0.12 (x, y)
## extent : -5, -2, 39, 42 (xmin, xmax, ymin, ymax)
## crs : +proj=longlat +datum=WGS84 +no_defs
## source : memory
## names : layer
## values : 1, 9 (min, max)
En ocasiones, el fichero que corresponde a la región de interés debe ser creado ad hoc. En el siguiente ejemplo, se creará esta región delimitándolo con sus coordenadas geográficas (longitud y latitud, siempre en este orden). En primer lugar, establecerán las coordenadas mediante sendos vectores.
<- c(-4.20, -4.20, -3.00,-3.00, -4.20)
lon <- c(40.25,40.64, 40.64, 40.25, 40.25) lat
Para convertir esos vectores en un objeto espacial, deben ser convertidos primero en una lista.
<- list(cbind(lon, lat)) lista
Este objeto list
debe convertirse en un posteriormente
en un objeto sfg
con la función
sf:st_polygon
.
<- st_polygon(lista)
lista class(lista)
## [1] "XY" "POLYGON" "sfg"
Los objetos sfg
almacenan la geometría con la
información gráfica del objeto: sus coordenadas, sus dimensiones,
geometría etc… Una de las clases típicas es polygon
: un
polígono cerrado con cero o más huecos interiores.
Al objeto anterior se le debe añadir el CRS, en este caso el EPSG:4326 (WGS84), que es el que posee el objeto ráster.
<- st_sf(st_sfc(lista),
limite crs = 4326)
Por último, y dado que ambos comparten el mismo CRS, se pueden cartografiar de manera simultánea.
plot(raster, axis = TRUE)
plot(st_geometry(limite),
add = TRUE)
A continuación procederemos a enmascarar y recortar el objeto ráster
con el objeto vectorial. La función raster::mask
requiere
como argumentos
• El nombre del objeto ráster que será enmascarado y recortado
• El nombre del objeto que servirá de ventana espacial (puede ser vectorial o ráster).
<- mask(raster, limite)
raster_enmascarado plot(raster_enmascarado)
Una vez enmascarado, el objeto ráster es recortado.
<- crop(raster_enmascarado,
raster_recortado limite)
Por último, se puede comprobar los resultados representándolos gráficamente:
plot(raster_enmascarado)
plot(st_geometry(limite),
add = TRUE)
La diferencia entre las funciones raster::crop
(recorte)
y raster::mask
(enmascara ese área de interés) es la
siguiente:
La función raster::mask
mantiene las dimensiones
originales del raster, pero los valores situados fuera de los límites
del objeto vectorial son convertidos en NA.
La función raster:crop
reemplaza esos valores por
valores nulos y ajusta la ventana a los límites del objeto
vectorial.
Puede observarse que la imagen está recortada, y que los píxeles que se mantienen son aquellos cuya superficie se incluye mayoritariamente dentro de la imagen.
rm(lat, lon, lista, limite, raster_enmascarado, raster_recortado)
Sin embargo, en la mayor parte de los casos se utilizan objetos
vectoriales proporcionados por alguna institución. En este caso, se va a
trabajar con los límites administrativos de la Comunidad de Madrid. El
fichero vectorial con formato .shp se importa con la función
sf::st_rad
.
<- st_read("D:/G174_OCW/Lab_3_preprocesamiento_imagenes_satelite/datos/proyeccion/comunidad.shp") comunidad
## Reading layer `comunidad' from data source
## `D:\G174_OCW\Lab_3_preprocesamiento_imagenes_satelite\datos\proyeccion\comunidad.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 1 feature and 1 field
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: 365635.7 ymin: 4415272 xmax: 495483.9 ymax: 4557310
## Projected CRS: WGS 84 / UTM zone 30N
Dado que el CRS de este objeto corresponde a un sistema de referencia de coordenadas proyectado (WGS 84 / UTM zone 30N), es más correcto reproyectarlo en vez de reproyectar el objeto ráster.
<- st_transform(comunidad,
comunidad 4326) # El CRS correspondiente a coordenadas geográficas
A continuación, se representan gráficamente ambos objetos.
plot(raster,
axis = TRUE)
plot(st_geometry(comunidad),
add = TRUE)
Por último, se utilizará el objeto vectorial para recortar y enmascarar el objeto ráster.
<- mask(raster,
raster_enmascarado
comunidad)plot(raster_enmascarado)
<- crop(raster_enmascarado,
raster_recortado
comunidad)plot(raster_recortado)
plot(st_geometry(comunidad),
add = TRUE)
rm(raster, raster_enmascarado, raster_recortado, comunidad)
A diferencia de los casos anteriores, en los que se ha trabajado con ficheros unibanda, las escenas de Landsat contienen un conjunto de bandas que deben ser recortadas de la misma manera para su posterior análisis. Este puede hacerse repitiendo, de manera consecutiva y para cada una de las imágenes, los procedimientos anteriores. Esto puede considerarse una pérdida de tiempo, ya que es posible recortar de manera simultánea todas las bandas.
A continuación se muestra un procedimiento para convertir los
ficheros individuales de cada banda en un objeto multibanda utilizando
la función raster::RasterBrick
. Esto lo realizaremos en dos
pasos:
<- list.files("D:/G174_OCW/Lab_2_manejo_ficheros_raster_R/datos", # Directorio de los datos
lista pattern = ".*B[1234567]\\.tif$", # El signo del dólar lista todos los ficheros que acaban igual
ignore.case=TRUE, # Sensible a mayúsculas y minúsculas
full.names = TRUE)
RasterStack
, y luego se transforma en
RasterBrick
.<- stack(lista)
stack <- brick(stack) imagen
A continuación se consultan las características de este
RasterBrick
.
imagen
## class : RasterBrick
## dimensions : 7911, 7791, 61634601, 7 (nrow, ncol, ncell, nlayers)
## resolution : 30, 30 (x, y)
## extent : 316485, 550215, 4345785, 4583115 (xmin, xmax, ymin, ymax)
## crs : +proj=utm +zone=30 +datum=WGS84 +units=m +no_defs
## source : r_tmp_2024-02-06_080647.781183_76468_10184.grd
## names : LC08_L1TP//9_02_T1_B1, LC08_L1TP//9_02_T1_B2, LC08_L1TP//9_02_T1_B3, LC08_L1TP//9_02_T1_B4, LC08_L1TP//9_02_T1_B5, LC08_L1TP//9_02_T1_B6, LC08_L1TP//9_02_T1_B7
## min values : 8486, 7594, 7003, 5998, 5207, 4755, 4954
## max values : 65535, 57121, 65535, 65535, 65535, 65535, 65535
Como ya se ha señalado, el manejo de ficheros con bandas cuya
denominación es tan complicada dificulta cualquier análisis posterior.
Por ello,es conveniente renombrar las bandas para mejorar su
identificación. En este caso, se eliminará el texto
LC08_L1TP_201032_20210723_20210729_02_T1_
de cada imagen,
dejando sólo la letra B
(de banda) y el número de cada
banda.
names(imagen) <- gsub(pattern = "LC08_L1TP_201032_20210723_20210729_02_T1_", # conjunto de caracteres que se desea sustituir
replace ="", # caracteres que sustituirán a los anteriores
<- names(imagen)) # vector o dataframe que sustituirán a los anteriores
x imagen
## class : RasterBrick
## dimensions : 7911, 7791, 61634601, 7 (nrow, ncol, ncell, nlayers)
## resolution : 30, 30 (x, y)
## extent : 316485, 550215, 4345785, 4583115 (xmin, xmax, ymin, ymax)
## crs : +proj=utm +zone=30 +datum=WGS84 +units=m +no_defs
## source : r_tmp_2024-02-06_080647.781183_76468_10184.grd
## names : B1, B2, B3, B4, B5, B6, B7
## min values : 8486, 7594, 7003, 5998, 5207, 4755, 4954
## max values : 65535, 57121, 65535, 65535, 65535, 65535, 65535
Por último, con el fin de verificar que todo el proceso se ha
realizado satisfactoriamente, la imagen se representa gráficamente. Como
la imagen es multibanda, se pueden representar de manera simultánea
varias bandas, mediante la función RStoolbox::ggRGB
. Esta
función incluye como argumentos:
• imagen -> Un RasterStack
o un
RasterBrick
.
• r -> capa 1.
• g -> capa 2.
• b -> capa 3.
• stretch -> función para el realce de la imagen. ‘lin’ corresponde a realce lineal.
Para trabajar con la función RStoolbox::ggRGB
es
necesario cargar el paquete correspondiente:
library(RStoolbox)
La imagen se representa a continuación en una combinación específica de badnas denominada “falso color”.
ggRGB(imagen,
r = 5, g = 4 , b = 3,
stretch = "lin")
El objeto imagen, obtenido a partir de una escena de Lansat, posee un gran tamaño (sus dimensiones son 61634601 píxeles). Para el recorte de esa imagen existen diferentes posibilidades.
extent
.Tanto los objetos Raster
como los
vectoriales
contienen información sobre su extensión
espacial, que adquiere denominaciones diferentes
extensión (extent
) en objetos ráster.
cuadro delimitador (bbox
) en objetos
vectoriales.
En el caso de los primeros, la extensión se define mediante cuatro valores, que corresponden a las cuatro esquinas del rectángulo de cierre:
las coordenadas mínima y máxima de la dimensión x
(xmin
, xmax
)
las coordenadas minima y maxima de la dimensión y (ymin, ymax),
Si se trabaja simultáneamente con dos objetos ráster, por ejemplo una
escena de Landsat y un MDT o una base de datos de usos del territorio,
la función raster::extent
puede ser útil para trasladar los
límites de uno de los objetos (normalmente el más pequeño) al otro. El
procedimiento para recortar una imagen utilizando la función
raster::extent
implica los siguientes pasos:
raster::extent()
, que devuelve un objeto
extent
(operativo tanto para objetos ráster como
vectoriales).extent(imagen)
## class : Extent
## xmin : 316485
## xmax : 550215
## ymin : 4345785
## ymax : 4583115
Los objetos Extent
tienen una característica particular:
se pueden cambiar de tamaño fácilmente. Por ejemplo, multiplicar la
extensión por 0,5 no moverá las coordenadas por un 50% hacia la
izquierda y hacia abajo, sino que reducirá la extensión
proporcionalmente, pero manteniendo la ubicación geográfica del
centroide. Un ejemplo es el siguiente:
# borrame <- extent(imagen)
# plot(borrame)
# plot(borrame*0.5, add = TRUE)
# rm(borrame)
Este recurso puede ser muy útil en ocasiones, por ejemplo, para una expansión/contracción rápida de las dimensiones de trazado sin tener que jugar con las coordenadas o con la extracción de un subconjunto.
roi
a partir de la función raster:extent
. Este
objeto se creará modificando las dimensiones del objeto
imagen
.<- extent(xmin(imagen) + 50000,
roi xmax(imagen) - 50000,
ymin(imagen) + 45000,
ymax(imagen) - 83000)
# roi <- extent(400000,500000,4400000,4500000) # Una forma alternativa
roi
## class : Extent
## xmin : 366485
## xmax : 500215
## ymin : 4390785
## ymax : 4500115
Una vez disponible el objeto roi
correspondiente al
nuevo área de trabajo, se usará para recortar la imagen original con la
función raster::crop
.
<- crop(imagen,
imagen_recortada roi)
Podemos verficar el resultado de este recorte mediante sus metadatos y compararlos con los de la imagen original.
imagen_recortada
## class : RasterBrick
## dimensions : 3644, 4457, 16241308, 7 (nrow, ncol, ncell, nlayers)
## resolution : 30, 30 (x, y)
## extent : 366495, 500205, 4390785, 4500105 (xmin, xmax, ymin, ymax)
## crs : +proj=utm +zone=30 +datum=WGS84 +units=m +no_defs
## source : r_tmp_2024-02-06_080755.283986_76468_59321.grd
## names : B1, B2, B3, B4, B5, B6, B7
## min values : 9265, 8315, 7134, 6188, 5207, 4755, 4954
## max values : 52017, 51199, 43592, 51099, 57124, 65535, 65535
Y también gráficamente mediante una imagen en color natural.
ggRGB(imagen_recortada,
r = 4, g =3, b = 2,
stretch = "lin")
rm(x, lista, stack, imagen_recortada, roi)
En la mayoría de los casos, sobre todo cuando se trabaja sobre áreas con una delimitación irregular, por ejemplo, un límite administrativo (caso de un ayuntamiento, una comunidad autónoma o un parque nacional) es necesario recortar el objeto ráster inicial apoyándose en un fichero vectorial que incorpora esos límites irregulares.
El fichero vectorial puede añadirse desde el disco duro, en cuyo caso debe estar proyectado en proyectado en el mismo sistema CRS del objeto ráster, o se puede general interactivamente.
Si poseemos un fichero vectorial con los límites de la zona de
interés almacenado en nuestro disco duro, podemos importarlo con la
función st_read
del paquete sf.
<- st_read("./datos/recorte/originales/poligono.shp") limites
## Reading layer `poligono' from data source
## `D:\G174_OCW\Lab_3_preprocesamiento_imagenes_satelite\datos\recorte\originales\poligono.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 1 feature and 1 field
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: 407201.9 ymin: 4434128 xmax: 488607.1 ymax: 4482673
## CRS: NA
class(limites)
## [1] "sf" "data.frame"
Como se ha señalado, es necesario que tanto el objeto raster como el vectorial tengan la misma proyección. Se puede preguntar a R si ambos ficheros comparten el mismo sistema de proyección.
compareCRS(limites, imagen)
## [1] FALSE
Para conocer cuáles son los sistemas de proyección de cada formato, se recurrirá a las funciones:
sf::st_crs
(para el fichero vectorial).st_crs(limites) # Se comprueba que no el fichero vectorial no tiene CRS
## Coordinate Reference System: NA
-raster::crs
para el formato ráster
crs(imagen)
## Coordinate Reference System:
## Deprecated Proj.4 representation:
## +proj=utm +zone=30 +datum=WGS84 +units=m +no_defs
## WKT2 2019 representation:
## PROJCRS["unknown",
## BASEGEOGCRS["unknown",
## DATUM["World Geodetic System 1984",
## ELLIPSOID["WGS 84",6378137,298.257223563,
## LENGTHUNIT["metre",1]],
## ID["EPSG",6326]],
## PRIMEM["Greenwich",0,
## ANGLEUNIT["degree",0.0174532925199433],
## ID["EPSG",8901]]],
## CONVERSION["UTM zone 30N",
## METHOD["Transverse Mercator",
## ID["EPSG",9807]],
## PARAMETER["Latitude of natural origin",0,
## ANGLEUNIT["degree",0.0174532925199433],
## ID["EPSG",8801]],
## PARAMETER["Longitude of natural origin",-3,
## ANGLEUNIT["degree",0.0174532925199433],
## ID["EPSG",8802]],
## PARAMETER["Scale factor at natural origin",0.9996,
## SCALEUNIT["unity",1],
## ID["EPSG",8805]],
## PARAMETER["False easting",500000,
## LENGTHUNIT["metre",1],
## ID["EPSG",8806]],
## PARAMETER["False northing",0,
## LENGTHUNIT["metre",1],
## ID["EPSG",8807]],
## ID["EPSG",16030]],
## CS[Cartesian,2],
## AXIS["(E)",east,
## ORDER[1],
## LENGTHUNIT["metre",1,
## ID["EPSG",9001]]],
## AXIS["(N)",north,
## ORDER[2],
## LENGTHUNIT["metre",1,
## ID["EPSG",9001]]]]
Como el objeto vectorial carece de proyección, se le asigna un
sistema de proyección con la función sf::st_crs
. Existen
varias sintaxis alternativas.
<- crs(imagen) # Objeto con el CRS del fichero ráster
crs_raster #limites2 <- st_set_crs(limites, crs_raster)
Una vez establecido el CRS de interés en el objeto vectorial, se procede a su recorte y enmascaramiento.
<- crop(imagen, limites)
imagen_recortada <- mask(imagen_recortada,limites)
imagen_enmascarada plot(imagen_enmascarada)
Y también gráficamente mediante una imagen en la que se combinan las bandas 5, 6 y 4, muy utilizada para la detección de superfiice acuáticas.
ggRGB(imagen_enmascarada,
r = 5, g =6, b = 4,
stretch = "lin")
rm(crs_raster, imagen_enmascarada, imagen_recortada, limites)
Otra posibilidad es que el fichero vectorial se importe con un sistema de coordenadas de referencia ya establecido. Para ello es necesario descargar el fichero denominado metro que está en formato shapefile.
Primero se importará el fichero vectorial con la función
sf::st_read
.
<- st_read("D:/G174_OCW/Lab_3_preprocesamiento_imagenes_satelite/datos/recorte/originales/metro.shp") metro
## Reading layer `metro' from data source
## `D:\G174_OCW\Lab_3_preprocesamiento_imagenes_satelite\datos\recorte\originales\metro.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 1 feature and 1 field
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: -4.11172 ymin: 40.19909 xmax: -3.410273 ymax: 40.73222
## Geodetic CRS: GCS_unknown
A continuación se compararán los sistemas de coordenadas del nuevo
fichero vectorial y del fichero raster con la función
raster
::compareCRS`.
compareCRS(metro, imagen)
## [1] FALSE
A continuación, preguntaremos al sistema cuál es el CRS del fichero vectorial
crs(metro)
## [1] "GEOGCRS[\"GCS_unknown\",\n DATUM[\"World Geodetic System 1984\",\n ELLIPSOID[\"WGS 84\",6378137,298.257223563,\n LENGTHUNIT[\"metre\",1]],\n ID[\"EPSG\",6326]],\n PRIMEM[\"Greenwich\",0,\n ANGLEUNIT[\"Degree\",0.0174532925199433]],\n CS[ellipsoidal,2],\n AXIS[\"longitude\",east,\n ORDER[1],\n ANGLEUNIT[\"Degree\",0.0174532925199433]],\n AXIS[\"latitude\",north,\n ORDER[2],\n ANGLEUNIT[\"Degree\",0.0174532925199433]]]"
Debe cambiarse dicho CRS con la función
sf::st_tranform
.
<- st_transform(metro,
metro "EPSG:32630")
compareCRS(metro, imagen)
## [1] TRUE
Una vez transformado el CRS del fichero vectorial, se puede
representar la imagen en formato ráster, y superpuestos, los límites del
área de interés representados por el fichero vectorial. En este caso se
utiliza la función Rstoolbox::plotRGB
solicitando que, del
objeto imagen, se representen sólo las bandas 6,5 y 4.
plotRGB(imagen[[6:4]],
stretch = "lin",
axes = TRUE)
plot(metro,
border = "blue",
lwd = 4,
add = TRUE)
Una vez que el raster y el shapefile están en el mismo CRS, se puede crear la máscara.
raster::crop
.<- crop(imagen, metro)
crop ggRGB(crop,
r= 4, g= 3, b= 2,
stretch = "lin")
PASO 2. Recorte de la imagen usando como máscara el poligono con la
función raster::mask
. A continuación, su correspondiente
representación gráfica en color natural (RGB 432)
<- mask(crop,
imagen_recortada mask = metro)
ggRGB(imagen_recortada,
r= 4, g= 3, b= 2,
stretch = "lin")
Si se desea grabar el objeto resultante, habría que añadir a la
función raster::maks
dos argumentos:
filename = “./datos/recorte/imagen_recortada.tif” Ruta y nombre del fichero resultante.
overwrite = TRUE sobreescribe cualquier fichero anterior con el mism nombre.
Ejemplo (se exporta con formato .tif):
# imagen_recortada <- mask(crop,
# mask = metro,
# filename = "./mi_ruta/nombre_fichero.tif",
# overwrite = TRUE)
Si desea agilizar todo este proceso, ambas funciones se pueden encadenar.
<- mask(crop(imagen, metro), metro)
borrame ggRGB(borrame, r= 5, g= 6, b= 2,
stretch = "lin")
Otra posibilidad, no muy frecuente, es el recorte de la zona de
interés, pero vaciando su interior y manteniendo las áreas circundantes.
Para ello, debe incluirse el argumento inverse = TRUE
en la
función raster::mask
.
<- mask(imagen,
borrame
metro, inverse = TRUE)
ggRGB(borrame,
r= 4, g= 3, b= 2,
stretch = "lin")
También es posible utilizar como fuente del área de interés otro fichero raster. De nuevo, ambos ficheros ráster deberían tener la misma proyección para que se puedan superponer.
<- brick("./datos/recorte/imagen_recortada.tif")
mascara_raster mascara_raster
## class : RasterBrick
## dimensions : 1973, 1984, 3914432, 7 (nrow, ncol, ncell, nlayers)
## resolution : 30, 30 (x, y)
## extent : 405675, 465195, 4450095, 4509285 (xmin, xmax, ymin, ymax)
## crs : +proj=utm +zone=30 +datum=WGS84 +units=m +no_defs
## source : imagen_recortada.tif
## names : imagen_recortada_1, imagen_recortada_2, imagen_recortada_3, imagen_recortada_4, imagen_recortada_5, imagen_recortada_6, imagen_recortada_7
## min values : 10076, 9268, 8278, 7456, 7015, 6331, 5932
## max values : 52017, 51199, 40913, 46914, 57124, 65535, 65535
Siguiendo el mismo procedimiento realizado en líneas precedentes, primero representaremos toda la imagen y posteriormente supenpodremos la imagen correspondiente al objeto mascara_raster.
plotRGB(imagen[[4:2]],
stretch = "lin",
axes = TRUE,
alpha = 100) # Parámetro que define el nivel de transparencia
plotRGB(mascara_raster[[4:2]],
stretch = "lin",
add = TRUE)
Una vez confirmado el grado de superposición entre ambas imágenes, se puede proceder a crear el subcojunto.
<- crop(imagen,
borrame
mascara_raster) borrame
## class : RasterBrick
## dimensions : 1973, 1984, 3914432, 7 (nrow, ncol, ncell, nlayers)
## resolution : 30, 30 (x, y)
## extent : 405675, 465195, 4450095, 4509285 (xmin, xmax, ymin, ymax)
## crs : +proj=utm +zone=30 +datum=WGS84 +units=m +no_defs
## source : memory
## names : B1, B2, B3, B4, B5, B6, B7
## min values : 9476, 8547, 7361, 6541, 6129, 5547, 5388
## max values : 52017, 51199, 43592, 51099, 57124, 65535, 65535
ggRGB(borrame, r= 5, g= 6, b= 2,
stretch = "lin")
Si se quiere crear un subconjunto definiendo el rango de unas celdas,
podemos utilizar la función rasterFromCells
. Esta función
sólo puede trabajar con una única capa raster, a diferencia de lo que
ocurre en las opciones anteriores.
<- rasterFromCells(imagen[[2]], # La 2ª banda de la imagen, que sería la green
borrame cells = c(10000:900000)) # Rango de píxeles (número)
# Metadatos de la nueva imagen borrame
## class : RasterLayer
## dimensions : 115, 7791, 895965 (nrow, ncol, ncell)
## resolution : 30, 30 (x, y)
## extent : 316485, 550215, 4579635, 4583085 (xmin, xmax, ymin, ymax)
## crs : +proj=utm +zone=30 +datum=WGS84 +units=m +no_defs
## source : memory
## names : layer
## values : 7792, 903756 (min, max)
Este nueva capa se representaría así
plot(borrame)
La selección de alguna banda específica de la imagen de trabajo se
realiza mediante la función subset
. Esta(s) nueva(s)
imágen(es) pueden salvarse posteriormente en el disco duro especificando
su nombre en el argumento filename
. En el siguiente ejemplo
se seleccionan las bandas correspondientes al verde y al rojo, situadas
en las posiciones 2 y 3.
<- subset(imagen_recortada,
recorte_espectral 2:3)
recorte_espectral
## class : RasterBrick
## dimensions : 1973, 1984, 3914432, 2 (nrow, ncol, ncell, nlayers)
## resolution : 30, 30 (x, y)
## extent : 405675, 465195, 4450095, 4509285 (xmin, xmax, ymin, ymax)
## crs : +proj=utm +zone=30 +datum=WGS84 +units=m +no_defs
## source : memory
## names : B2, B3
## min values : 9268, 8278
## max values : 51199, 40913
plot(recorte_espectral)
Se eliminan todos los objetos creados hasta el momento
rm(list=ls())
Un mosaico es la combinación de dos o más imágenes raster en una única imagen. A veces, una sola escena no cubre completamente el área de estudio deseada, por lo que puede requerirse combinar dos o más escenas. Las escenas Landsat permiten su superposición espacial, ya que comparten franjas comunes, pero el tamaño de píxel debe ser el mismo para la creación de mosaicos.
Para este ejercicio es necesario descargar los siguientes ficheros
Se crea el objeto ráster mosaico1
a partir de un fichero
en formato .tif
<- brick("./datos/mosaico/originales/mosaico1.tif") mosaico1
A continuación se revisa el contenido de este objeto.
mosaico1
## class : RasterBrick
## dimensions : 1488, 1142, 1699296, 7 (nrow, ncol, ncell, nlayers)
## resolution : 30, 30 (x, y)
## extent : 414855, 449115, 4438995, 4483635 (xmin, xmax, ymin, ymax)
## crs : +proj=utm +zone=30 +datum=WGS84 +units=m +no_defs
## source : mosaico1.tif
## names : mosaico1_1, mosaico1_2, mosaico1_3, mosaico1_4, mosaico1_5, mosaico1_6, mosaico1_7
## min values : 8881, 7609, 6917, 5821, 4546, 4837, 5034
## max values : 65535, 65535, 65535, 65535, 65535, 65535, 65535
Es muy habitual que los mosaicos se realicen a partir de dos o más escenas de Landsat contiguas. Es habitual que las escenas incluyan valores NA correspondientes al marco espacial sin datos de cada imagen. En consecuencia, es conveniente asignar el valor 0 a los píxeles con un valor NA de ambas escenas. Este valor sin datos se ignora al asignar las funciones.
NAvalue(mosaico1) <- 0 # Asignación del valor 0 a los píxeles NoData
A continuación se cartografía la primera imagen en falso (FCC), que luega será utilizada en la composición.
plotRGB(mosaico1,
r=3, g=2, b=1,
stretch ='lin',
axes =TRUE,
main = "Primera imagen")
A continuación se cargan las restantes imágenes.
<- brick("./datos/mosaico/originales/mosaico2.tif")
mosaico2 <- brick("./datos/mosaico/originales/mosaico3.tif")
mosaico3 <- brick("./datos/mosaico/originales/mosaico4.tif") mosaico4
Y se cartografía todas ellas en un único gráfico
par(mfrow = c(2, 2))
plotRGB(mosaico1,
r=3, g=2, b=1,
stretch ='lin',
axes =TRUE,
main = "Primera imagen")
plotRGB(mosaico2,
r=3, g=2, b=1,
stretch ='lin',
axes =TRUE,
main = "Segunda imagen")
plotRGB(mosaico3,
r=3, g=2, b=1,
stretch ='lin',
axes =TRUE,
main = "Tercera imagen")
plotRGB(mosaico4,
r=3, g=2, b=1,
stretch ='lin',
axes =TRUE,
main = "Cuarta imagen")
Volvemos al estado original
par(mfrow = c(1, 1))
Cuando el paquete raster
crea un mosaico con varias
imágenes, aquella parte que es común (normalmente, en uno o varios
bordes) se superponen entre sí. Además, todos los objetos deben tener un
origen, una resolución y un sistema de coordenadas de referencia
iguales.
Para crear un nuevo objeto raster con unas dimensiones mayores que la
de los objetos individuales debe usarse la función
raster::mosaic
. Esta función aplica a su vez una serie de
rutinas para computar el valor de los píxeles en las zonas de
superposición. En R, se pueden aplicar tres funciones a la región
superpuesta: la media, el mínimo y el máximo. Además, la función acepta
como argumento los valores ausentes (na.rm
).
Para aplicar la función promedio a la región superpuesta se asigna el
argumento fun = mean
. Esta función calcula la media de los
valores de los píxel de la región superpuesta y asigna ese valor medio
al ráster de salida.
<- mosaic(mosaico1, mosaico2, mosaico3, mosaico4,
mosaico_promedio fun = mean)
mosaico_promedio
## class : RasterBrick
## dimensions : 1488, 1142, 1699296, 7 (nrow, ncol, ncell, nlayers)
## resolution : 30, 30 (x, y)
## extent : 414855, 449115, 4438995, 4483635 (xmin, xmax, ymin, ymax)
## crs : +proj=utm +zone=30 +datum=WGS84 +units=m +no_defs
## source : memory
## names : layer.1, layer.2, layer.3, layer.4, layer.5, layer.6, layer.7
## min values : 8881, 7609, 6917, 5821, 4546, 4837, 5034
## max values : 65535, 65535, 65535, 65535, 65535, 65535, 65535
ggRGB(mosaico_promedio,
r= 3, g= 2, b= 1,
stretch = "lin")
min()
a la región superpuestaPara aplicar esta función, se asigna el argumento
fun = min
, que toma el valor mínimo de los píxeles de las
regiones superpuestas de las imágenes ráster que se van a unir y lo
asigna a la imagen de salida.
<- mosaic(mosaico1, mosaico2, mosaico3, mosaico4,
mosaico_minimo fun = min)
mosaico_minimo
## class : RasterBrick
## dimensions : 1488, 1142, 1699296, 7 (nrow, ncol, ncell, nlayers)
## resolution : 30, 30 (x, y)
## extent : 414855, 449115, 4438995, 4483635 (xmin, xmax, ymin, ymax)
## crs : +proj=utm +zone=30 +datum=WGS84 +units=m +no_defs
## source : memory
## names : layer.1, layer.2, layer.3, layer.4, layer.5, layer.6, layer.7
## min values : 8881, 7609, 6917, 5821, 4546, 4837, 5034
## max values : 65535, 65535, 65535, 65535, 65535, 65535, 65535
ggRGB(mosaico_minimo, r= 3, g= 2, b= 1,
stretch = "lin")
max()
a la región superpuestaEn este caso se asigana el valor máximo de píxel de las regiones
superpuestas, pasando el argumento fun = max
. Crea la mejor
imagen sin pérdida de datos, y por eso es la elegida habitualmente.
<- mosaic(mosaico1, mosaico2, mosaico3, mosaico4,
mosaico_maximo fun = max)
mosaico_maximo
## class : RasterBrick
## dimensions : 1488, 1142, 1699296, 7 (nrow, ncol, ncell, nlayers)
## resolution : 30, 30 (x, y)
## extent : 414855, 449115, 4438995, 4483635 (xmin, xmax, ymin, ymax)
## crs : +proj=utm +zone=30 +datum=WGS84 +units=m +no_defs
## source : memory
## names : layer.1, layer.2, layer.3, layer.4, layer.5, layer.6, layer.7
## min values : 8881, 7609, 6917, 5821, 4546, 4837, 5034
## max values : 65535, 65535, 65535, 65535, 65535, 65535, 65535
ggRGB(mosaico_maximo,
r= 3, g= 2, b= 1,
stretch = "lin")
Como estos objetos ya no van a ser de utilidad, se eliminan del Global Enviroment.
rm(mosaico1, mosaico2, mosaico3,mosaico4, mosaico_promedio, mosaico_minimo, mosaico_maximo)