Cómo quitar nubes de imágenes Sentinel 2 en RStudio paso a paso

Esa tarde de invierno la lluvia no paraba de golpear el techo de zinc de mi casa aquí en Valdivia, un ruido rítmico que a veces me distrae de lo que estoy haciendo en la pantalla pero que ese día servía de banda sonora perfecta para mi frustración. Tenía RStudio abierto, el mate ya se había enfriado y en la pantalla, en vez de ver el verde profundo del bosque nativo que tanto quería estudiar, solo veía una mancha blanca gigante, una especie de algodón de azúcar digital que lo cubría todo. Resulta que, por muy potentes que sean los satélites, no pueden ver a través de nuestras nubes sureñas, y ahí estaba yo, mirando píxeles blancos cuando lo que necesitaba era ver suelo firme.

Llevo unos diez meses en esto de la teledetección, aprendiendo a tropezones los fines de semana, y si algo he descubierto es que en el sur de Chile (y en cualquier lugar con clima rebelde), el primer paso para cualquier mapa no es analizar los datos, sino aprender a limpiar lo que el cielo nos oculta. Descargué gigabytes de información de Copernicus pensando que sería llegar y usar, pero el 90% de la imagen era puro ruido atmosférico. Y entonces, entre tutoriales que no entendía y foros en inglés, me di cuenta de que no era la única que peleaba contra este muro blanco.

El problema de las nubes y la paciencia del satélite

Lo primero que me voló la cabeza fue entender que la misión Sentinel-2 de la ESA no es solo una cámara sacando fotos desde arriba. Es una constelación de dos satélites que pasan por el mismo punto cada 5 días. Uno pensaría que con esa frecuencia de revisita voy a tener imágenes de sobra, pero en Valdivia pueden pasar tres semanas seguidas lloviendo y, por ende, tres pasadas del satélite donde lo único que captó fueron capas y capas de nubes. Es un ejercicio de paciencia absoluta.

Pantalla de laptop mostrando una imagen satelital con nubes y código de RStudio

Cuando por fin logré descargar imágenes Sentinel para procesar en RStudio fácilmente, me encontré con que incluso en los días que parecen despejados, siempre hay alguna nube pequeña o sombras que arruinan los cálculos de los índices de vegetación. Lo que más me costaba entender era que esos píxeles blancos no son solo 'nada', sino que tienen valores que confunden a R. Si intentas calcular algo con una nube encima, el resultado va a ser cualquier cosa menos la realidad del bosque.

Recuerdo que un sábado por la mañana, después de varias semanas de errores en la consola que me hacían querer cerrar la laptop y salir a caminar por el barro, descubrí que las imágenes Sentinel vienen con un 'regalo' escondido: la banda QA60. Es una capa de control de calidad que el mismo sistema del satélite genera para decirnos: 'Oye, Javiera, en este píxel hay una nube opaca' o 'Cuidado, aquí hay un cirrus'. Entender eso fue como encontrar la piedra rosetta de mis mapas.

La famosa banda QA60 y los bits que nos salvan

Aquí es donde la cosa se pone un poco técnica, pero no se asusten, que yo tampoco soy programadora. Resulta que la banda QA60 funciona con bits. Para los que, como yo, venían de cero, imaginen que es una cinta con interruptores. El interruptor número 10 es el que nos importa: cuando está encendido, significa que hay una nube opaca. En el lenguaje de R, ese valor del bit 10 en la banda QA60 para nubes opacas se traduce en el número 1024.

Para poder usar esta información, tuve que aprender a usar el paquete terra, que es el que ahora se usa para manejar rasters (esos archivos que son como fotos pero con datos). Al principio intentaba cargar la imagen completa y procesarla de una, pero mi pobre computadora no daba más. Me aparecía ese texto rojo horrible de 'Memory Exhausted' que me hacía saltar el corazón. Aprendí a la mala que antes de intentar quitar nubes, primero hay que recortar. Si te ha pasado lo mismo, te recomiendo ver cómo recortar un raster con un shapefile en RStudio fácilmente para que no se te pegue el computador como a mí.

Una vez que tienes tu área de estudio pequeñita, el proceso de 'enmascarar' las nubes se vuelve mucho más fluido. Básicamente le dices a R: 'Mira la banda QA60, busca donde el valor sea 1024 (o 2048 para los cirrus) y dile a esos píxeles que ahora son NA (Not Available)'. Es como borrar con una goma digital lo que no nos sirve para que abajo aparezca el verdadero valor de la reflectancia del bosque, que en las bandas visibles e infrarrojo cercano de Sentinel-2 tiene una resolución espacial de 10 metros. ¡Es increíble pensar que puedo ver cambios cada 10 metros desde mi escritorio!

Proceso de enmascaramiento de nubes en RStudio mostrando el antes y después

El momento en que todo cuadró (y el código funcionó)

Hace un par de meses, un domingo por la tarde, estaba probando una función de máscara que había copiado de un foro y adaptado a mis archivos. Estaba tan nerviosa que ni siquiera miraba la pantalla, solo escuchaba el ventilador de la laptop esforzándose mientras la barra de progreso avanzaba lentamente. Y de repente, el silencio. No hubo error rojo. No hubo 'crash'.

Cuando grafiqué el resultado, fue mágico. Donde antes había una mancha blanca, ahora había 'huecos' transparentes. Podía ver el verde de los arrayanes y los coigües asomándose justo en las partes donde no había nubes. Por fin, la máscara estaba funcionando. Entendí que quitar nubes no es 'borrarlas' y que aparezca lo que hay debajo por arte de magia (ojalá fuera así), sino que es limpiar el ruido para quedarnos solo con la información pura.

Sin embargo, ahí me topé con otra duda existencial de aprendiz: ¿qué hago con los huecos? Muchos tutoriales sugieren hacer algo llamado 'interpolación temporal', que es básicamente rellenar esos huecos usando fotos de días anteriores o posteriores. Pero aquí en Valdivia, entre que una foto está limpia y la siguiente también, el bosque puede haber cambiado mucho, o quizás hubo un incendio o una tala. Me di cuenta de que la interpolación temporal suele degradar la precisión espectral en zonas que cambian rápido, y para mis estudios de bosque nativo, eso era un riesgo. A veces es preferible integrar bandas de radar (como las de Sentinel-1) para obtener datos reales que atraviesan las nubes, en lugar de inventar datos sintéticos que podrían estar mintiéndome.

Consejos de alguien que se equivoca seguido

Si estás empezando con esto en RStudio, mi mayor consejo es que no te desesperes cuando los archivos no carguen. A veces el problema no es tu código, sino que el archivo es demasiado pesado. Yo pasé tardes enteras frustrada antes de encontrar la solución a errores comunes al cargar rasters pesados en R, y de verdad que te cambia la vida entender cómo R maneja la memoria interna.

Mapa impreso y laptop con resultados de procesamiento de imágenes satelitales

Al final del día, la teledetección en lugares como este es el arte de saber limpiar. Es aprender a ver a través de lo que el clima nos impone. Hoy, cuando miro mis mapas del bosque cerca de casa, ya no me asustan esos parches blancos. Sé que son parte del paisaje y sé cómo decirles a R que los ignore para que me deje ver lo que realmente importa: el verde que sobrevive bajo la lluvia.

Todavía me falta mucho por aprender, y seguro que el próximo fin de semana me encontraré con un error nuevo que no sabré resolver a la primera. Pero así es esto, un aprendizaje lento, de a poquito, guardando cada pequeño logro en un script para no olvidar el camino recorrido. Si yo pude pasar de no saber qué era un raster a lograr mi primera máscara de nubes en un invierno valdiviano, tú también puedes. Solo necesitas un buen termo de café (o mate), paciencia y no tenerle miedo a los mensajes en rojo de la consola.

Artículos relacionados