Teste - algoritmo em Python para monitoramento geoespectral.docx

davidmaciel37 9 views 9 slides Apr 30, 2025
Slide 1
Slide 1 of 9
Slide 1
1
Slide 2
2
Slide 3
3
Slide 4
4
Slide 5
5
Slide 6
6
Slide 7
7
Slide 8
8
Slide 9
9

About This Presentation

ALgorítimos


Slide Content

Teste - algoritmo em Python para monitoramento geoespectral: detecção de mudanças
usando o índice de vegetação (Normalized Difference Vegetation Index – NDVI).
1. O algoritmo pode comparar imagens de satélite multiespectrais da mesma área em duas datas diferentes
para identificar mudanças na vegetação.
Conceitos fundamentais:
1.Dados Geoespectrais: Imagens de satélite (como Landsat, Sentinel-2) que contêm múltiplas bandas espectrais
(ex: Vermelho, Infravermelho Próximo - NIR).
2.NDVI: Um índice calculado a partir das bandas Vermelho (Red) e Infravermelho Próximo (NIR) para estimar a
saúde e densidade da vegetação. Fórmula: NDVI = (NIR - Red) / (NIR + Red). Varia de -1 a +1.
3.Monitoramento: Comparar o NDVI em duas datas diferentes (T1 e T2) para ver onde a vegetação aumentou,
diminuiu ou permaneceu estável.
4.Bibliotecas Python: Usaremos rasterio para ler/escrever dados raster (imagens geoespaciais) e numpy para
cálculos numéricos. Opcionalmente, matplotlib para visualização.
Engenharia de Pré-requisitos:
●Python instalado.
●Bibliotecas instaladas:
pip install rasterio numpy matplotlib
content_copydownload
● Duas imagens de satélite multiespectrais da mesma área, em datas diferentes (T1 e T2).
● As imagens devem estar co-registradas (pixels alinhados geograficamente).
● Idealmente, devem ter passado por correção atmosférica.
● Você precisa saber quais números de banda correspondem ao Vermelho (Red) e ao
Infravermelho Próximo (NIR) para o seu satélite específico (ex: Landsat 8/9: Red=Banda 4,
NIR=Banda 5; Sentinel-2: Red=Banda 4, NIR=Banda 8).
import rasterio
import numpy as np
import matplotlib.pyplot as plt
import os
def calcular_ndvi(nir_band, red_band):
"""Calcula o NDVI a partir das bandas NIR e Red."""

# Ignorar avisos de divisão por zero ou valores inválidos
np.seterr(divide='ignore', invalid='ignore')
# Calcular NDVI: (NIR - Red) / (NIR + Red)
# Adicionar um pequeno epsilon para evitar divisão por zero onde NIR + Red = 0
# Converter para float32 para evitar problemas de tipo e precisão
ndvi = (nir_band.astype(np.float32) - red_band.astype(np.float32)) / \
(nir_band.astype(np.float32) + red_band.astype(np.float32) + 1e-8) # Epsilon
# Lidar com valores infinitos ou NaN que podem surgir
ndvi[np.isinf(ndvi)] = np.nan # Substituir infinitos por NaN
# Valores de NDVI devem estar entre -1 e 1. Fora disso podem ser erros ou areas sem dados.
# Você pode optar por mascarar ou limitar esses valores se necessário.
# ndvi[ndvi > 1] = 1
# ndvi[ndvi < -1] = -1
return ndvi
def monitoramento_ndvi_change(
image_path_t1,
image_path_t2,
red_band_index,
nir_band_index,
output_diff_path
):
"""
Calcula a diferença de NDVI entre duas imagens (T2 - T1) e salva o resultado.
Args:
image_path_t1 (str): Caminho para a imagem multiespectral da data 1 (T1).
image_path_t2 (str): Caminho para a imagem multiespectral da data 2 (T2).
red_band_index (int): Número da banda Vermelha (Red).
nir_band_index (int): Número da banda Infravermelha Próxima (NIR).
output_diff_path (str): Caminho para salvar a imagem de diferença de NDVI.
"""
print(f"Processando imagem T1: {image_path_t1}")
try:
with rasterio.open(image_path_t1) as src_t1:
# Ler as bandas Red e NIR para T1
red_t1 = src_t1.read(red_band_index)
nir_t1 = src_t1.read(nir_band_index)
profile = src_t1.profile # Salvar metadados para o arquivo de saída
nodata_val = src_t1.nodata # Obter valor nodata, se existir
# Criar máscara para valores nodata (se existirem)
mask_t1 = np.logical_or(red_t1 == nodata_val, nir_t1 == nodata_val) if nodata_val is not None else None
# Calcular NDVI para T1
print("Calculando NDVI para T1...")
ndvi_t1 = calcular_ndvi(nir_t1, red_t1)
if mask_t1 is not None:
ndvi_t1[mask_t1] = np.nan # Aplicar máscara nodata
except Exception as e:
print(f"Erro ao processar {image_path_t1}: {e}")
return

print(f"\nProcessando imagem T2: {image_path_t2}")
try:
with rasterio.open(image_path_t2) as src_t2:
# Verificar se as imagens têm a mesma projeção e extensão (CRÍTICO!)
if src_t1.crs != src_t2.crs or src_t1.transform != src_t2.transform:
print("ERRO: As imagens T1 e T2 não possuem o mesmo CRS ou Transformação!")
print("É necessário co-registrar as imagens antes de continuar.")
return
# Ler as bandas Red e NIR para T2
red_t2 = src_t2.read(red_band_index)
nir_t2 = src_t2.read(nir_band_index)
nodata_val_t2 = src_t2.nodata # Idealmente o mesmo nodata
# Criar máscara para valores nodata T2
mask_t2 = np.logical_or(red_t2 == nodata_val_t2, nir_t2 == nodata_val_t2) if nodata_val_t2 is not None else
None
# Calcular NDVI para T2
print("Calculando NDVI para T2...")
ndvi_t2 = calcular_ndvi(nir_t2, red_t2)
if mask_t2 is not None:
ndvi_t2[mask_t2] = np.nan # Aplicar máscara nodata
except Exception as e:
print(f"Erro ao processar {image_path_t2}: {e}")
return
# Calcular a diferença de NDVI (T2 - T1)
print("\nCalculando a diferença de NDVI (T2 - T1)...")
ndvi_diff = ndvi_t2 - ndvi_t1
# Atualizar o perfil para o arquivo de saída
profile.update(dtype=rasterio.float32, count=1, nodata=np.nan) # Usar float32 e NaN como nodata
# Salvar a imagem de diferença de NDVI
print(f"Salvando a imagem de diferença de NDVI em: {output_diff_path}")
try:
with rasterio.open(output_diff_path, 'w', **profile) as dst:
dst.write(ndvi_diff, 1)
print("Arquivo de diferença salvo com sucesso.")
except Exception as e:
print(f"Erro ao salvar o arquivo de diferença: {e}")
return
# --- Visualização Opcional ---
try:
print("\nGerando visualização da diferença de NDVI...")
plt.figure(figsize=(10, 10))
# Usar um colormap divergente para mostrar aumento (verde), diminuição (vermelho/marrom)
cmap = plt.cm.RdYlGn
plt.imshow(ndvi_diff, cmap=cmap, vmin=-0.5, vmax=0.5) # Ajuste vmin/vmax conforme necessário
plt.colorbar(label='Diferença de NDVI (T2 - T1)')
plt.title('Mudança de NDVI (Verde=Aumento, Vermelho/Marrom=Diminuição)')
plt.xlabel('Coluna (Pixel)')
plt.ylabel('Linha (Pixel)')
# Salvar a figura

viz_path = os.path.splitext(output_diff_path)[0] + '_visualization.png'
plt.savefig(viz_path)
print(f"Visualização salva em: {viz_path}")
# plt.show() # Descomente para exibir a imagem interativamente
plt.close() # Fechar a figura para liberar memória
except Exception as e:
print(f"Erro durante a visualização: {e}")
# --- Exemplo de Uso ---
if __name__ == "__main__":
# **IMPORTANTE: Substitua pelos caminhos e índices de banda corretos!**
# Caminhos para as imagens (ex: arquivos GeoTIFF)
# Use imagens co-registradas e (idealmente) corrigidas atmosfericamente
path_imagem_t1 = 'caminho/para/sua/imagem_T1.tif'
path_imagem_t2 = 'caminho/para/sua/imagem_T2.tif'
# Índices das bandas (começando em 1) - VERIFIQUE PARA SEU SATÉLITE
# Exemplo para Landsat 8/9 OLI:
# banda_vermelha = 4
# banda_nir = 5
# Exemplo para Sentinel-2 MSI:
banda_vermelha = 4
banda_nir = 8
# Caminho para salvar o resultado (será um GeoTIFF)
path_saida_diff = 'caminho/para/salvar/ndvi_difference.tif'
# Verificar se os arquivos de entrada existem
if not os.path.exists(path_imagem_t1):
print(f"ERRO: Arquivo de entrada T1 não encontrado: {path_imagem_t1}")
elif not os.path.exists(path_imagem_t2):
print(f"ERRO: Arquivo de entrada T2 não encontrado: {path_imagem_t2}")
else:
# Criar diretório de saída se não existir
output_dir = os.path.dirname(path_saida_diff)
if output_dir and not os.path.exists(output_dir):
os.makedirs(output_dir)
print(f"Diretório de saída criado: {output_dir}")
# Executar a função de monitoramento
monitoramento_ndvi_change(
path_imagem_t1,
path_imagem_t2,
banda_vermelha,
banda_nir,
path_saida_diff
)
Instruções para teste:

1. Instale as bibliotecas: pip install rasterio numpy matplotlib
2. Prepare seus dados: Obtenha as duas imagens de satélite (T1 e T2) da mesma área, co-registradas.
3. Edite o script:
● Atualize path_imagem_t1 e path_imagem_t2 com os caminhos corretos para seus arquivos
de imagem.
● Atualize banda_vermelha e banda_nir com os números de banda corretos para o sensor do
seu satélite. Lembre-se que rasterio usa indexação baseada em 1.
● Atualize path_saida_diff para onde você quer salvar o resultado da diferença de NDVI.
4. Execute o script: python seu_script.py (onde seu_script.py é o nome do arquivo que você salvou).
Interpretação e Discussão do Resultado (ndvi_difference.tif):
● Valores Positivos: Indicam um aumento no NDVI (provavelmente aumento da vegetação ou saúde
vegetal) entre T1 e T2.
● Valores Negativos: Indicam uma diminuição no NDVI (provavelmente perda de vegetação, estresse
hídrico, colheita, desmatamento) entre T1 e T2.
● Valores Próximos de Zero: Indicam pouca ou nenhuma mudança significativa na vegetação.
● Valores NaN (Not a Number): Representam áreas onde não foi possível calcular o NDVI em uma ou
ambas as datas (geralmente devido a nuvens, sombras ou ausência de dados - nodata).
Considerações e Análises Adicionais:
● Pré-processamento é Crucial: A qualidade do resultado depende enormemente da qualidade do pré-
processamento das imagens (correção atmosférica, co-registro preciso).
● Nuvens e Sombras: São grandes fontes de erro. Idealmente, use imagens sem nuvens ou aplique
máscaras de nuvem/sombra antes do cálculo.
● Outros Índices: Existem muitos outros índices espectrais para monitorar diferentes alvos (água -
NDWI, áreas queimadas - NBR, etc.). A estrutura do algoritmo seria similar, mudando apenas a fórmula e as
bandas usadas.
● Escala: Para grandes áreas ou longos períodos, considere bibliotecas mais avançadas
como xarray com dask para processamento paralelo e gerenciamento eficiente de memória, ou plataformas
como Google Earth Engine.
● Limiarização: Frequentemente, aplica-se um limiar (threshold) à imagem de diferença para classificar
as mudanças como "significativas" ou “não significativas”.
O algoritmo pode fornecer uma base sólida para START com o monitoramento geoespectral usando Python.

2. Alguns fundamentos teóricos para o monitoramento geoespectral, que formam a base para a
desenvolvimento de algoritmos usando Python.
1. Sensoriamento Remoto e Dados Geoespectrais:
● O que é? Sensoriamento remoto é a ciência e arte de obter informações sobre objetos ou fenômenos
sem fazer contato físico direto com eles. No contexto geoespacial, isso geralmente envolve sensores a bordo
de satélites, aeronaves ou drones.
● Dados Geoespectrais: São dados coletados por esses sensores que registram a interação
da radiação eletromagnética (REM) com a superfície da Terra em diferentes faixas (ou bandas) espectrais.
Cada pixel em uma imagem geoespectral contém informações sobre a intensidade da REM refletida ou emitida
pela área correspondente no solo, em comprimentos de onda específicos (ex: azul, verde, vermelho,
infravermelho próximo (NIR), infravermelho de ondas curtas (SWIR), infravermelho termal).
● Componentes da REM: A fonte primária de REM para sensores passivos (como Landsat, Sentinel-2)
é o Sol. A energia solar viaja pela atmosfera, interage com a superfície e é refletida de volta para o sensor,
passando novamente pela atmosfera. Sensores ativos (como RADAR) emitem sua própria energia e medem o
retorno.
2. Interação da Radiação Eletromagnética com a Matéria:
● Base Física: Quando a REM atinge um objeto na superfície (vegetação, solo, água, construções), ela
pode ser:
● Refletida: A energia "quica" na superfície. A quantidade e os comprimentos de onda
refletidos dependem das propriedades do material.
● Absorvida: A energia é retida pelo material (frequentemente convertida em calor).
● Transmitida: A energia passa através do material (importante para alvos como água ou
folhas finas).

● Lei de Conservação de Energia: A soma da energia refletida, absorvida e transmitida é igual à energia
incidente em um determinado comprimento de onda.
● Importância: A forma como diferentes materiais interagem com a REM em diferentes comprimentos
de onda é a chave para diferenciá-los e analisar suas propriedades.
3. Assinaturas Espectrais:
● O que são? Uma assinatura espectral é o padrão de refletância (ou
absorbância/transmitância/emissividade) de um material em função do comprimento de onda. É como uma
"impressão digital" espectral.
● Exemplos Clássicos:
● Vegetação Saudável: Absorve fortemente a luz azul e vermelha (devido à clorofila para
fotossíntese), reflete a luz verde (por isso a vemos verde) e reflete muito fortemente o infravermelho
próximo (NIR) devido à estrutura celular das folhas.
● Água Limpa: Reflete um pouco no azul/verde e absorve fortemente o vermelho e quase toda
a energia NIR e SWIR.
● Solo Exposto: Geralmente tem uma refletância que aumenta gradualmente do visível para o
SWIR, com variações dependendo da composição (minerais, matéria orgânica) e umidade (solo
úmido reflete menos).
● Nuvens: Altamente refletoras em quase todas as faixas do visível e infravermelho refletido.
● Base do Monitoramento: As mudanças nas condições da superfície (ex: crescimento ou estresse da
vegetação, aumento da umidade do solo, urbanização, ocorrência de incêndios) alteram suas assinaturas
espectrais.
4. Índices Espectrais:
● Por que usar? Analisar múltiplas bandas espectrais individualmente pode ser complexo. Índices
espectrais combinam matematicamente os valores de refletância de duas ou mais bandas para:
● Realçar características específicas de interesse (ex: vigor da vegetação, teor de água, área
queimada).
● Reduzir a dimensionalidade dos dados (combinar várias bandas em uma única camada de
informação).
● Normalizar os dados, reduzindo efeitos de iluminação e topografia (parcialmente).
● Exemplo (NDVI): NDVI = (NIR - Red) / (NIR + Red)
● Fundamento: Explora o contraste acentuado entre a alta refletância da vegetação no NIR e
sua baixa refletância no vermelho (absorção pela clorofila).

● Interpretação: Valores altos (próximos a +1) indicam vegetação densa e saudável. Valores
baixos (próximos a 0 ou negativos) indicam solo exposto, água, ou vegetação esparsa/estressada.
● Outros Índices: Existem dezenas de índices para diferentes finalidades: NDWI (água), NBR (área
queimada), EVI (vegetação, com correções atmosféricas), SAVI (vegetação em áreas com solo exposto), etc.
A escolha depende do objetivo do monitoramento.
5. Monitoramento e Detecção de Mudanças:
● Conceito Central: Comparar dados geoespectrais (imagens brutas, refletâncias corrigidas ou índices
espectrais) da mesma área adquiridos em momentos diferentes (T1 e T2) para identificar onde e como
ocorreram mudanças.
● Abordagens Comuns:
● Diferença de Imagens (Image Differencing): Subtrair os valores de pixel de uma imagem (ou
índice) da outra (T2 - T1). Simples e direto para avaliar a magnitude da mudança. Requer imagens
perfeitamente co-registradas e, idealmente, normalizadas/corrigidas.
● Comparação Pós-Classificação: Classificar as imagens T1 e T2 independentemente em
classes temáticas (floresta, água, urbano, etc.) e depois comparar os mapas de classificação para
identificar transições ("de-para", ex: floresta para agricultura).
● Análise de Séries Temporais: Usar uma sequência longa de imagens para modelar
tendências, sazonalidade e detectar anomalias ou pontos de quebra (mudanças abruptas). Mais
robusto contra variações pontuais, mas requer mais dados e técnicas mais complexas.
6. Pré-processamento (Essencial para Comparabilidade):
● Calibração Radiométrica: Converter os números digitais (DN) brutos registrados pelo sensor em
unidades físicas significativas (radiância ou refletância). Absolutamente necessário para comparar imagens de
datas diferentes ou sensores diferentes.
● Correção Atmosférica: Remover os efeitos de espalhamento e absorção causados pela atmosfera.
Essencial para obter a refletância real da superfície e para comparações temporais precisas, especialmente
em estudos de longo prazo ou que usam diferentes sensores.
● Correção Geométrica / Co-registro: Garantir que os pixels de imagens diferentes correspondam
exatamente à mesma localização geográfica no terreno. Qualquer desalinhamento (mesmo de uma fração de
pixel) pode levar a falsas detecções de mudança, especialmente em áreas com bordas nítidas.
7. O Papel do Python:
● Python, com seu rico ecossistema de bibliotecas científicas e geoespaciais, atua como a ferramenta
computacional para implementar esses fundamentos teóricos:
● Leitura/Escrita de Dados: rasterio, gdal - Acessar e manipular arquivos raster (GeoTIFF,
etc.).

● Computação Numérica: numpy - Realizar operações matemáticas eficientes em arrays
(essencial para cálculos de índices e diferenças).
● Manipulação de Dados: pandas, xarray - Organizar e analisar dados, especialmente séries
temporais.
● Processamento Geoespacial: geopandas, shapely, pyproj - Trabalhar com dados vetoriais
(máscaras, limites de áreas de estudo).
● Visualização: matplotlib, seaborn, rasterio.plot - Criar mapas e gráficos para análise e
comunicação dos resultados.
● Machine Learning: scikit-learn, tensorflow, pytorch - Implementar algoritmos de classificação
ou detecção de anomalias mais avançados.
● Processamento Paralelo/Distribuído: dask, multiprocessing - Lidar com grandes volumes de
dados de forma eficiente.

De forma geral, o monitoramento geoespectral se baseia na Física da interação luz-matéria e nas assinaturas
espectrais únicas dos alvos. Além disso, os Índices espectrais simplificam a análise, e técnicas de comparação
temporal revelam mudanças. O pré-processamento otimiza a validade das análises comparativas, e Python oferece as
estruturas computacionais para executar todas essas etapas, para desenvolvimento de um algoritmo otimizado.
Tags