11 Sensoriamento remoto
11.1 Imagens de RPAs
Este capítulo oferece uma introdução ao processamento e classificação de imagens de RPAs no ambiente R, usando algoritmos de aprendizado capazes de realizer diversos processamentos. Ele também fornece um tutorial de referência conciso e prático, que oferece aos leitores uma nosso geral do que é possível realizar no Sistema R com o processamento e classificação de imagens de RPAs.
É necessário instalar alguns pacotes necessários para aplicar esta tarefa:
install.packages("devtools", dependency=TRUE)
library(devtools)
install_github("filipematias23/FIELDimageR")
install.packages("sp", dependency=TRUE)
install.packages("raster", dependency=TRUE)
install.packages("rgdal", dependency=TRUE)
Carregar os pacote que foram baixados:
Baixar a imagem ortomosaicada:
Plotar a imagem nas bandas RGB:
Remover o solo e trabalhar apenas com a vegetação para aplicar os índices de vegetação RGB:
Aplicado os índices de vegetação.
Aplicaremos o índice NGRDI, BGI e podemos criar um índice usando as bandas disponíveis. Criaremos como exemplo myIndex
com a fórmula Red-Blue/Green
:
11.2 Imagens de satélites
Esse procedimento será realizado com imagens de satélite (Sentinel 2), porêm pode ser aplicado com imagens de RPA, desde que sejam multiespectrais.
Carregar pacotes necessários para trabalhar com os dados raster. Caso não tenha algum dos pacotes, realize a sua instalação:
library(raster)
library(knitr)
library(sp)
library(rgdal)
library(ggplot2)
library(viridis)
library(rasterVis)
library(LSRS)
Baixar o arquivo . sentinel2.tif.
Visualizar os dados:
É necessário criar camadas individuais para cada uma das bandas espectrais:
b1 <- raster('sentinel2.tif', band=1)
b2 <- raster('sentinel2.tif', band=2)
b3 <- raster('sentinel2.tif', band=3)
b4 <- raster('sentinel2.tif', band=4)
b5 <- raster('sentinel2.tif', band=5)
b6 <- raster('sentinel2.tif', band=6)
b7 <- raster('sentinel2.tif', band=7)
b8 <- raster('sentinel2.tif', band=8)
b9 <- raster('sentinel2.tif', band=9)
b10 <- raster('sentinel2.tif', band=10)
b11 <- raster('sentinel2.tif', band=11)
b12 <- raster('sentinel2.tif', band=12)
Comparar duas bandas para ver se elas possuem a mesma extensão:
Plotar a banda 4 para pré-visualização:
Visualizar a imagem nas bandas do RGB:
RGB <- stack(list(b4, b3, b2))
plotRGB(RGB, axes = TRUE, stretch = "lin", main = "Sentinel RGB colour composite")
Juntar todas as bandas num só arquivo:
Aplicar o índice de vegetação NDVI, para o Sentinel 2 com: NIR = 8, red = 4.
Criar a VI (vegetation index) por meio de função:
NDVI:
Outras fórmula de aplicar o NDVI
vi2 <- function(x, y) {
(x - y) / (x + y)
}
ndvi2 <- overlay(st[[8]], st[[4]], fun=vi2)
plot(ndvi2, col=rev(terrain.colors(10)), main="Sentinel2-NDVI")
Visualizar o NDVI em histograma
hist(ndvi,
main = "Distribuição dos valores de NDVI",
xlab = "NDVI",
ylab= "Frequência",
col = "wheat",
xlim = c(-0.5, 1),
breaks = 30,
xaxt = 'n')
axis(side=1, at = seq(-0.5,1, 0.05), labels = seq(-0.5,1, 0.05))
Visualizar apenas a vegetação com NDVI acima de 0.4:
Reclassificar o NDVI e difini-lo por classes numéricas:
vegc <- reclassify(ndvi, c(-Inf,0.25,1, 0.25,0.3,2, 0.3,0.4,3, 0.4,0.5,4, 0.5,Inf, 5))
plot(vegc,col = rev(terrain.colors(4)), main = 'NDVI reclassificado')
Criar uma classificação não supervisionada a partir do NDVI:
Converter o raster (NDVI) a um vetor/matriz:
É importante definir o gerador de pontos, porque o “kmeans” inicia os centros em locais aleatórios:
Criar 10 clusters, permitir 500 iterações, comece com 5 conjuntos aleatórios usando o método Lloyd
:
Ver o vetor/matriz:
Crie uma cópia do NDVI para não perder os dados:
Agora substitua os valores das células de varredura pelo kmncluster$cluster
:
Realize o plot do NDVI e do kmeans:
par(mfrow = c(1, 2))
plot(ndvi, col = rev(terrain.colors(10)), main = "NDVI")
plot(knr, main = "Kmeans", col = viridis_pal(option = "D")(10))
Se quiser traçar a classificação kmeans ao lado da renderização do RGB para verificar a qualidade da classificação e identificação das classes:
par(mfrow = c(1, 2))
plotRGB(RGB, axes = FALSE, stretch = "lin", main = "RGB")
plot(knr, main = "Kmeans", yaxt = 'n', col = viridis_pal(option = "D")(10))
Aplicar outros índices de vegetação com o pacote LSRS
:
NDVI=NDVI(b8,b4)
SAVI=SAVI(b8,b4)
TGSI=TGSI(b4,b2,b3)
MSAVI=MSAVI(b8,b4, Pixel.Depth=1)
EVI=EVI(b8,b4,b2,Pixel.Depth=1)
NBR=NBR(b8,b11)
par(mfrow = c(3, 2))
plot(NDVI,lwd=4,main="NDVI",xlab="easting", ylab="northing")
plot(SAVI,lwd=4,main="SAVI",xlab="easting", ylab="northing")
plot(TGSI,lwd=4,main="TGSI",xlab="easting", ylab="northing")
plot(MSAVI,lwd=4,main="MSAVI",xlab="easting", ylab="northing")
plot(EVI,lwd=4,main="EVI",xlab="easting", ylab="northing")
plot(NBR,lwd=4,main="NBR",xlab="easting", ylab="northing")
11.3 Curvas de nível e modelo 3D a partir do Modelo Digital de Elevação
Primeiro carregar os pacotes necessários:
Carregar o dado raster do pacote Raster (Volcano) para ser usado como exemplo:
Criar as curvas de nível:
cont <- contourLines(volcano)
fun <- function(x) x$level
LEVS <- sort(unique(unlist(lapply(cont, fun))))
COLS <- terrain.colors(length(LEVS))
Plotar somente as curvas de nível:
Plotar o modelo 3D com curvas de nível:
Exemplo 1:
Exemplo 2:
Exemplo 3:
Exemplo 4:
Exemplo 5:
11.4 LIDAR
O exemplo a seguir é um processamento de imagens LIDAR, por meio da qual será segmentado árvores individuais e métricas.
Carregar pacote:
Baixar dados Example.las
Carregar uma área florestal de exemplo a partir de imagens LIDAR que será trabalhada:
O lasground fornece vários algoritmos para classificar os pontos de referência. Essa função é conveniente para gráficos de pequeno a médio porte, como o que estamos processando.
Classificar pontos do solo (pontos de referência):
É necessário definir o terreno em 0 metros. Deve-se subtrair o MDT para obter pontos de aterramento em 0, mas aqui não será usado um MDT, mas vamos interpolar exatamente cada ponto.
Definir altura normalizada:
Na próxima etapa, será usado um algoritmo que requer um modelo de altura da copa a partir da nuvem de pontos.
Calcular um modelo de altura das copas:
Plotar o CHM:
A segmentação pode ser alcançada com lastrees
. Aqui foi escolhido o algorítmo de bacia com um limiar de 4 metros. A nuvem de pontos foi atualizada e cada ponto agora tem um número que se refere a uma árvore individual (treeID). Pontos que não são árvores recebem o valor de ID NA.
Realizar a segmentação das árvores:
Remova os pontos que não estão atribuídos a uma árvore:
Plotar a segmentação:
Calcular algumas métricas:
No exemplo anterior, mesmo se a segmentação for feita usando um modelo de altura do dossel, a classificação foi feita na nuvem de pontos. Isso ocorre porque lidR
é uma biblioteca orientada à nuvem de pontos. Mas pode-se querer que o raster trabalhe com rasters. Nesse caso, a função divisor de águas pode ser usada de forma independente:
Criar poligonos de contornos a partir da copa:
Plotar o CHM e contornos:
11.5 Modelo Digital de Elevação MDE
Carregar pacotes:
Carregar dados e plotar:
Usar a função terrain()
para calcular/extrair algumas informações topográficas:
Declividade <- terrain(MDE, "slope")
Aspecto <- terrain(MDE, "aspect")
TPI <- terrain(MDE, "TPI") # Topographic Position Index (Índice de posição topográfica)
TRI <- terrain(MDE, "TRI") # Terrain Ruggedness Index (Índice de robustez do terreno)
Rugosidade <- terrain(MDE, "roughness")
Escoamento <- terrain(MDE, "flowdir")
Hillshade <- hillShade(Declividade, Aspecto, angle=45, direction=0, filename='', normalize=FALSE)
Juntar todos os dados com a função stack()
:
Renomear os dados para aparecerem no plot
:
Plotar os dados: