Procesamiento de imágenes satelitales para redes neuronales convolucionales
En este posteo vamos a mostrar cómo crear un conjunto de datos de imágenes satelitales para poder aplicarles el modelo de clasificación basado en redes neuronales convolucionales.
Se estima que en ciencia de datos, el 80% del tiempo se lo lleva el armado del conjunto de datos. Si a esto le sumamos la complejidad de la información geoespacial (en particular las imágenes satelitales), sospechamos que ese porcentaje se queda corto.
Para resolver esto, en Dymaxion Labs desarrollamos un conjunto de librerías de código abierto que permiten agilizar el armado de los datasets, para de ese modo concentrar nuestro esfuerzo en tener la mejor estrategia para resolver el problema. En este posteo vamos a trabajar con una de esas librerías: satproc. Con ella podremos preparar el set de datos y dejarlo listo para ejecutar el modelo detección de área quemada que describiremos en este post.
El área de interés que vamos a trabajar está ubicada en el norte de la Provincia de Corrientes, Argentina. Esta zona es muy rica en biodiversidad y, a su vez, experimenta una de las peores sequías en décadas. Lamentablemente, actualmente los incendios en Corrientes ya alcanzan el 10% del área total.
Esta guía comprende desde el procesamiento inicial de la imágenes para obtener el índice NBR hasta la generación de los conjuntos de datos para trabajar con la red neuronal. La imagen original es del sensor Sentinel-2 tomada la primera semana de Febrero de 2022 en la provincia de Corrientes, Argentina. La imagen en formato TIF puede descargarse desde este link.
Obtención de índice Normalizado de Área Quemada
¿Cómo calcular el NBR?
El índice Normalizado de Área Quemada (Normalized Burn Ratio por sus siglas en inglés) permite detectar áreas quemadas en amplias zonas. Su fórmula combina las bandas de infrarrojo cercano con las bandas de infrarrojo de onda corta (near-infrared o NIR y Short-wave infrared o SWIR respectivamente).
La firma espectral característica de la vegetación sana presenta valores de reflectancia altos en el NIR pero bajos en el SWIR. En cambio, cuando la vegetación es afectada por el fuego se observan cambios significativos en su firma espectral: un área recientemente quemada mostrará valores de reflectancia bajos en el NIR pero altos en el SWIR. De esta manera, la diferencia normalizada entre ambos valores es un gran indicador de este fenómeno, donde valores altos de NBR indican vegetación sana mientras que valores bajos representan áreas de suelo desnudo o recientemente quemadas.
Severidad del área quemada
La diferencia entre el NBR obtenido antes y luego de un incendio es utilizado para calcular el delta del índice normalizado de área quemada (delta Normalized Burn Ratio). Cuanto mayor es el dNBR, mayor es la severidad del daño, mientras que las áreas con valores negativos del dNBR podrían estar indicando una recuperación de la vegetación posterior al evento. Para más información sobre este punto, te invitamos a visitar este enlace.
Dado que la imagen que descargamos es del sensor Sentinel-2, el índice normalizado se utilizará con las bandas 8A y 12. Vamos a calcularlo con la librería GDAL, a partir del script gdal_calc.py:
gdal_calc.py \
-A ./img/s2/sample_corrientes.tif --A_band=8 \
-B ./img/s2/sample_corrientes.tif --B_band=12 \
--calc="(A-B)/(A+B)" \
--outfile=./img/NBR_img/NBR_s2.tif
Generación de chips
Ahora que tenemos el índice que usa el modelo, vamos a trabajar en generar el conjunto de datos necesario para poder hacer la predicción.
Para instalar satproc, basta con ejecutar `pip install pysatproc`. Estos son los parámetros más comunes para su uso:
pip install pysatproc
Con la instalación de la librería se instalan una serie de scripts para el procesamiento de imágenes:
satproc_extract_chips
: Extrae chips de imágenes rasterizadas, creando opcionalmente máscaras para cada chip mediante un archivo vectorial de etiquetas.satproc_make_masks
: Crea máscaras desde imágenes rasterizadas y un archivo vectorial de etiquetas.satproc_polygonize
: Poligoniza o vectoriza imágenes de chips en un sólo archivo vectorial de polígonos.satproc_generalize
: Generaliza los archivos vectoriales simplificando y suavizando las líneas del límite de los polígonos.satproc_smooth_stitch
: Suaviza chips solapados, util para mejorar el resultado de predicción con solapamiento.satproc_scale
: Cambia la escala de los valores de las imágenes rasterizadassatproc_match_histograms
: Busca alinear los histogramas de imágenes raster a partir de una imagen de referencia.
En este posteo nos concentraremos en satproc_extract_chips
.
Algunos de los los argumentos disponibles son:
optional arguments:
-h, --help show this help message and exit
--size SIZE size of image tiles, in pixels (default: 256)
--step-size STEP_SIZE
step size (i.e. stride), in pixels (default: 128)
--sliding-windows-mode {exact,whole,whole_overlap}
mode of sliding windows (default: whole_overlap)
--labels LABELS inpul label shapefile (default: None)
--label-property LABEL_PROPERTY
label property to separate in classes (default: class)
--classes CLASSES [CLASSES ...]
specify classes order in result mask. (default: None)
--masks {extent,boundary,distance} [{extent,boundary,distance} ...], -m {extent,boundary,distance} [{extent,boundary,distance} ...]
--mask-type {single,class,instance}
--aoi AOI Filter by AOI vector file (default: None)
--within only create chip is it is within AOI (if provided)
(default: False)
--no-within create chip if it intersects with AOI (if provided)
(default: False)
Puede accederse a la documentación online en este link.
Ejemplo para la obtención de chips: caso práctico
Este caso consiste en la generación de los chips con el tamaño adecuado para la red neuronal entrenada. A partir de allí el modelo podrá ser aplicado para estimar la superficie quemada en el área de interés.
satproc_extract_chips \
./img/NBR_img/NBR_s2.tif \
-o ./img/NBR_img/chips/160_80/ \
--size 160 \
--step-size 80
Como se ve allí, no intervienen los parámetros relacionados con las clases y el área de interés, puesto que buscamos predecir sobre estas imágenes.
Los chips resultantes quedan disponibles en el directorio indicado como salida, siguiendo esta nomenclatura:
images/<nombre imagen de entrada>_<fila>_<columna>
Por ejemplo:
NBR_s2_0_0.tif
NBR_s2_0_7.tif
NBR_s2_1_6.tif
NBR_s2_2_5.tif
Otras funcionalidades de Satproc
Veamos ahora algunas funcionalidades que sirvan para optimizar el uso de la librería según el caso de uso.
- Dentro de un área de interés (AOI)
Podría suceder que tenemos una imagen de un territorio en particular, pero queremos extraer chips solamente en un área específica. En ese caso, tenemos que indicar la ruta al archivo vectorial con el área de interés. El comando queda:
satproc_extract_chips \
./img/NBR_img/NBR_s2.tif \
-o ./img/NBR_img/chips/aoi/160_80/ \
--size 160 \
--step-size 80 \
--aoi ./shp/aoi/aoi_sample.geojson
Vemos en la siguiente imagen el resultado:
2. Mejora de contraste:
En algunos casos, realzar ciertos atributos de la imagen puede ayudar a mejorarla performance del modelo. Este paso suele pertenecer a la etapa de pre-procesamiento de los datos. Sin embargo, puede calcularse también usando satproc. Esta funcionalidad puede resultar de suma utilidad a la hora de automatizar la metodología de modelado.
satproc_extract_chips \
./img/NBR_img/NBR_s2.tif \
-o ./img/NBR_img/chips/160_80/ \
--size 160 \
--step-size 80 \
--rescale \
--rescale-mode percentiles \
--upper-cut 98 --lower-cut 2
Existen diferentes modos de reescalado, incluso pueden ser customizados por el usuario. En la documentación se presenta la lista de los que vienen ya implementados.
3. Obtención de footprints en formato vectorial
Este ejemplo es útil cuando se quiere conocer el contorno de cada chip resultante. Por ejemplo, para combinarlo con otras fuentes de información espacial de interés. Basta con agregar el parámetro — write-footprints.
satproc_extract_chips \
./img/NBR_img/NBR_s2.tif \
-o ./img/NBR_img/chips/aoi/160_80/ \
--size 160 \
--step-size 80 \
--write-footprints
La capa vectorial resultante luce así:
Conclusión
Dentro del desarrollo de modelos de clasificación de imágenes, suele pasar que, a la hora de aplicar el modelo en grandes extensiones territoriales, nos enfrentamos al problema de automatizar el análisis.
Utilizando la librería de código abierto satproc, podremos realizarlo de manera estandarizada y customizable al análisis que estemos ejecutando, sin perder de vista lo principal que es resolver el problema (y no luchar con los datos geoespaciales que sirvan para resolverlo).
El código para reproducir este ejemplo puede encontrarse en este Google Colab