Empecemos por el principio.
Cómo funciona la teledetección por satélite
Los satélites llevan a cabo sensores que puede medir brillo a diferentes longitudes de onda (depende del sensor)
Por ejemplo,
Landsat 8 lleva una carga útil de dos sensores: el Operational Land Imager (OLI), construido por Ball Aerospace & Technologies Corporation; y el sensor infrarrojo térmico (TIRS), construido por el Centro de Vuelo Espacial Goddard de la NASA (GSFC) ( https://landsat.usgs.gov/landsat-8-l8-data-users-handbook-section-2 )
El sensor OLI mide la radiancia en 9 longitudes de onda diferentes y el TIRS en 2 longitudes de onda diferentes:
La primera medición del sensor (datos brutos) se toma en Números Digitales y se convierte en radiancia basándose en los factores de reescalado proporcionados en el archivo de metadatos.
Dependiendo del sensor, el resultado tipo de datos pueden diferir. Los datos brutos de Landsat 1 a 7 son de 8 bits (cada banda), por lo que los valores pueden ir de 0 a 255 (256 opciones). Los datos brutos de Landsat 8 son de 16 bits, por lo que los valores pueden ir de 0 a 65535 (65536 opciones).
Si miras la descripción de LANDSAT/LC08/C01/T1
(en bruto) en el motor de Google Earth verás
Valores de DN de Landsat 8 Collection 1 Tier 1, que representan la radiancia a escala calibrados en el sensor. ( https://developers.google.com/earth-engine/datasets/catalog/LANDSAT_LC08_C01_T1 )
Y puede comprobar el tipos de datos en el editor de código:
var c = Map.getCenter()
var L5RAW = ee.ImageCollection('LANDSAT/LT05/C01/T1').filterBounds(c)
var L8RAW = ee.ImageCollection('LANDSAT/LC08/C01/T1').filterBounds(c)
print('Landsat 5 RAW', L5RAW.first().getInfo()['bands'])
print('Landsat 8 RAW', L8RAW.first().getInfo()['bands'])
Correcciones radiométricas
La energía que registran los sensores a bordo de las aeronaves o los satélites puede diferir de la energía real emitida o reflejada por una superficie en el suelo. Esto se debe al acimut y la elevación del sol y a las condiciones atmosféricas que pueden influir en la energía observada. Por lo tanto, para obtener la irradiancia real del suelo o reflectancia, hay que corregir los errores radiométricos. ( http://gsp.humboldt.edu/olm_2015/courses/gsp_216_online/lesson4-1/radiometric.html )
Una vez corregidos los datos, la salida depende del proceso realizado y puede estar en un tipo de datos como por ejemplo 16-bit unsigned integer
, floating point
etc. (No he podido encontrar una buena fuente de referencia para esto).
Puede comprobarlo en el motor de Google Earth
var c = Map.getCenter()
var L8TOA = ee.ImageCollection("LANDSAT/LC08/C01/T1_TOA").filterBounds(c)
var L8SR = ee.ImageCollection("LANDSAT/LC08/C01/T1_SR").filterBounds(c)
print('Landsat 8 TOA', L8TOA.first().getInfo()['bands'])
print('Landsat 8 SR', L8SR.first().getInfo()['bands'])
Como se puede ver en los resultados, Landsat 8 TOA tiene un float
lo que significa que los datos van de 0 a 1, y SR tiene un signed int 16
lo que significa que los datos van de -32768 a 32767. Sin embargo, este último tiene una particularidad, los valores reales van de 0 a 10000 (no hay valores inferiores a 0 ni superiores a 10000).
Finalmente,
Cómo funciona un monitor
Para crear un píxel de un solo color, una pantalla LCD utiliza tres subpíxeles con filtros rojo, verde y azul. Mediante un cuidadoso control y variación del voltaje aplicado, la intensidad de cada subpíxel puede variar en 256 tonos. La combinación de los subpíxeles produce un posible una paleta de 16,8 millones de colores (256 tonos de rojo x 256 tonos de verde x 256 tonos de azul). ( https://computer.howstuffworks.com/monitor4.htm )
Así, si un píxel tiene los valores Rojo: 0, Azul: 0, Verde: 0, el color del píxel será negro, y si los valores son Rojo: 255, Azul: 255, Verde: 255, el color del píxel será blanco.
Hay muchos sitios para jugar con esto, como este: https://www.w3schools.com/colors/colors_picker.asp
Poniendo todo junto
Su monitor sólo puede mostrar tres colores: Rojo, Verde y Azul (RGB). Así que, para visualizar una trama, primero hay que elegir qué bandas representarán esos colores. Ese es el parámetro bands
de Map.addLayer
. Luego, hay que indicarle al monitor qué valor (fuera del rango) representará el 0 (mínimo) y cuál el 255 (máximo). Estos son los parámetros min
y max
de Map.addLayer
. También puede especificar diferentes min
y max
para cada banda utilizando una lista de tres valores en lugar de un solo valor.
Digamos que quieres visualizar una imagen Landsat 8 TOA como si estuvieras sentado encima del satélite (color real). Entonces, tienes que decirle al monitor que utilice la banda roja (banda 4) de la trama para el subpíxel rojo del monitor, la banda verde (banda 3) para el subpíxel verde y la banda azul (banda 2) para el subpíxel azul. Luego, hay que decirle al monitor cómo estirar los valores del raster, que como hemos visto para el Landsat 8 TOA puede ir de 0 a 1 (porque es un float
), a los valores de los subpíxeles (que van de 0 a 255). Así,
var c = Map.getCenter()
var L8TOA = ee.ImageCollection("LANDSAT/LC08/C01/T1_TOA").filterBounds(c)
Map.addLayer(L8TOA.first(), {bands:['B4', 'B3', 'B2'], min:0, max:1}, 'L8 TOA Real Color')
Pero descubrirás que la imagen se ve "demasiado oscura" para ese estiramiento (depende del reflectancia de los objetos que está viendo), así que haga la max
más pequeño para verlo más "brillante", por ejemplo, max:0.4
Os dejo una sencilla aplicación que he hecho para mostrar esto: https://fitoprincipe.users.earthengine.app/view/stretch
fuente: https://code.earthengine.google.com/cdf508ac8ae98a35364758d4c585bba2
Si quieres ver la misma escena de Landsat desde otras colecciones tienes que saber cómo se presentan los datos en cada colección.
Por último, existen algunos métodos para estirar los valores automáticamente utilizando el histograma de trama, como Desviaciones estándar, Mínimo-Máximo, Recorte porcentual, Sigmoide, etc. ( http://desktop.arcgis.com/en/arcmap/latest/manage-data/raster-and-images/stretch-function.htm ). Earth Engine le permite utilizar algunos