Showing results for 
Search instead for 
Do you mean 

Landsat 8 Top of Atmosphere Reflectance Conversion

by Technical Evangelist on ‎05-05-2016 08:22 AM - edited Monday by Community Manager (12,149 Views)


Download model




This model implements the formulas published by the USGS for converting the quantized and calibrated scaled Digital Numbers (DN) representing multispectral image data acquired by Landsat 8 Operational Land Imager (OLI, bands 1 to 9)  to Top of Atmosphere (ToA) Reflectance. 


The conversion formulas require values stored in the metadata for each image (usually an ancillary file with a name such as <image>.met, or <image>_MTL.txt).


The published formula for TOA Reflectance is: 


R l' = MlQcal + Ar



Rl' = TOA planetary reflectance without correction for solar angle.

Ml = Band-specific multiplicative rescaling factor from the metadata (REFLECTANCE_MULT_BAND_x, where x is the band number)

Qcal = Quantized and calibrated standard product pixel values (DN)

Ar = Band-specific additive rescaling factor from the metadata (REFLECTANCE_ADD_BAND_x, where x is the band number)


TOA reflectance can be corrected for the sun angle by:


Rl = Rl' / cos(solar zenith angle) OR Rl = rl' / sin(solar elevation angle) 



Rl = TOA planetary reflectance

Rl' = product of TOA reflectance without correction

Solar Elevation angle = local sun elevation from the metadata (SUN_ELEVATION)  NOTE: SUN_ELEVATION is unique to each Landsat 8 Scene

Solar Zenith angle = 90 - Solar Elevation angle




Input parameters:


Landsat 8 MSI: Select the input Landsat 8 image to be converted to reflectance. This could be a multispectral image representing bands 1 to 7, a single band Panchromatic image (band 8), a single band Cirrus image (band 9) or a combination thereof (including individual band files). It should not be the Thermal bands (Bands 10 and 11) or the QA band.

Landsat 8 Reflectance: Name of the output image file containing the ToA Reflectance values. This will be a 32-bit Float data type.

REFLECTANCE_MULT_BAND: Enter a single Reflectance Multiplier correction value to be applied to every input band. The default is 0.00002, but the <image>_MTL.txt metadata file should be reviewed to determine the correct value.

REFLECTANCE_ADD_BAND: Enter a single Reflectance Additive correction value to be applied to every input band. The default is -0.1, but the <image>_MTL.txt metadata file should be reviewed to determine the correct value.

SUN_ELEVATION: Enter a single value for the Sun's elevation (in degrees) above the horizon at the time of image acquisition. This value is unique for every Landsat 8 image and can be determined by finding the SUN_ELEVATION keyword in the input image's <image>_MTL.txt metadata file.






Most Landsat 8 imagery provided by the USGS download site appears to have already been corrected to ToA Reflectance, but has subsequently had a consistent scale and offset applied to every band to fully utilize an unsigned 16-bit integer data range. Consequently the Reflectance_Mult_Band_n isusually 0.00002 and the Reflectance_Add_Band_n is usually -0.1 for every band in the image. So the current incarnation of the model both defaults to those values, and only has a single input to apply to every band.


If a review of the <image>_MTL.txt metadata file indicates that these values actually vary per band, you would need to either:


  1. Process each band individually, or
  2. Modify the model to prompt for inputs for all the Multiplier and Additive values, as suggested in the screenshot below (with a similar Table for the Additives), or
  3. Upgrade to ERDAS IMAGINE 2016 and make use of the model which will be posted separately which uses a Python script to parse the metadata file, create a Dictionary of metadata values (including Sun Elevation) and automatically correct all bands based on those values. See the article entitled Using the Python Script operator to ingest sensor metadata


 How to modify the model for varying Multipliers and Additives:




by Technical Evangelist
‎06-13-2017 09:47 AM - edited ‎06-13-2017 09:49 AM

Sounds like you may not have declared the calculation as Float. If you want to see how NDVI (or any of several dozen other indices) are performed in Spatial Modeler go to the Raster tab, Classification group, Unsupervised pulldown and select NDVI (or Indices). In the Indices dialog click the View... button to bring up the relevant Model in the Spatial Model Editor.




Note that the Raster Input has been declared as Float (even if the input image were unsigned 8 or 16 bit), so that the raster stream flowing down the model is already float and therefore the band math calculations (especially the Divide) will be performed in floating point precision. You could also do this by inserting a Float operator into the stream, like this:




Although, to be honest, if you used the Landsat 8 TOA Reflectance Conversion model as-is, it should have been producing data that was already Float and so you wouldn't need to perform this type of declaration. If you could provide a screenshot of your model it would help figure out what the issue might be. You may also want to take the discussion to the Support discussion forum - there are likely more people there who can help.





by Wali
on ‎06-13-2017 09:55 AM

Dear Sir,


Thank you very much for providing such a detailed answer. My problem has solved. The produced NDVI image needed some NDVI Bug Fix opperations. 





by Forest
on ‎07-20-2018 02:23 AM



This model is very helpful to my work, but after this step, when i stack the bands, i don't khow how to set the value in the command, and how to use the reflectance value to calculate NDVI, it seem out of range between -1 and 1, or it's my error.


by Technical Evangelist
on ‎07-20-2018 06:13 AM



I'm afraid you're going to need to provide more information on what it is you're trying to do please. You may alo want to start a thread in the ERDAS IMAGINE Discussions forum to see if anyone can assist.




by mando
on ‎12-21-2018 11:12 AM

hello sir,

thanks for your effort , but when i applied this model the results showed values in negative and mor than 1

and i dont know why?

It came out like this :