Skip to content

Instantly share code, notes, and snippets.

@scarlettlee
Last active March 5, 2021 19:43
Show Gist options
  • Select an option

  • Save scarlettlee/7beb591ba7d61bee06a5af9dd3e86cfb to your computer and use it in GitHub Desktop.

Select an option

Save scarlettlee/7beb591ba7d61bee06a5af9dd3e86cfb to your computer and use it in GitHub Desktop.
High quality Landsat 5 mosaic image production. After running this script, open https://code.earthengine.google.com/ and see tasks running procedure in the task window.
# Code for generating High-quality Landsat mosaics
# generated by Huan Li (huan.li@pku.edu.cn)
# Many thanks to the excellent GEE community for sample code sharing
# after run this script, open https://code.earthengine.google.com/ and see tasks running procedure in the task window
import ee
import time
ee.Initialize()
# global variables
NON_FILL = True
NON_SAT = True
CONFIDENCE = 1 # low 0 medium 1 high 2
SHADOW = True
CLIP_EDGE = False
EDGE_LENGTH = 7 # km
COMPOSITE = 1 # 0 mosaic top layer; 1 median mosaic; 2 mean mosaic
PARADIGM = 'pixel' # 'pixel' or 'scene'
# Function to clip image
def clip(im, distance):
geo = ee.Geometry(im.geometry());
small_geo = geo.buffer(ee.Number(distance).multiply(-1000));
return im.clip(small_geo);
# Mask bad pixels
def maskBad(img):
radsat_qa = img.select('radsat_qa');
qa = img.select('pixel_qa');
# fill
fillPixel = radsat_qa.bitwiseAnd(1); # fill bit
if NON_FILL:
img = img.updateMask(fillPixel.Not())
# saturated bands 1-7
satPixel = radsat_qa.bitwiseAnd(1 << 1)\
.Or(radsat_qa.bitwiseAnd(1 << 2))\
.Or(radsat_qa.bitwiseAnd(1 << 3))\
.Or(radsat_qa.bitwiseAnd(1 << 4))\
.Or(radsat_qa.bitwiseAnd(1 << 5))\
.Or(radsat_qa.bitwiseAnd(1 << 6))\
.Or(radsat_qa.bitwiseAnd(1 << 7))\
if NON_SAT:
img = img.updateMask(satPixel.Not())
# cloudy
cloudPixel = qa.bitwiseAnd(1 << 5) # cloud bit
if CONFIDENCE == 0: # low confidence
cloudPixel = cloudPixel.And(qa.bitwiseAnd(1 << 6))
elif CONFIDENCE == 1: # medium confidence
cloudPixel = cloudPixel.And(qa.bitwiseAnd(1 << 7))
else: # high confidence
cloudPixel = cloudPixel.And(qa.bitwiseAnd(3 << 7))
img = img.updateMask(cloudPixel.Not())
# shadow
shadowPixel = qa.bitwiseAnd(1 << 3) # shadow
if SHADOW:
img = img.updateMask(shadowPixel.Not())
# edge
if CLIP_EDGE:
img = clip(img, EDGE_LENGTH);
# Remove edge pixels that don 't occur in all bands # 0 invalid, 1 valid
edgeMsk = img.mask()\
.reduce(ee.Reducer.min()) # minimum of all bands
return img.updateMask(edgeMsk) # edge pixels
def ndvi(img):
return img.addBands(img.normalizedDifference(['nir', 'red']));
def CompositeStrategy(imgCol):
if COMPOSITE == 0:
return imgCol.mosaic();
elif COMPOSITE == 1:
return imgCol.median();
elif COMPOSITE == 2:
return imgCol.mean();
elif COMPOSITE == 3:
imgColNDVI = imgCol.map(ndvi)
return imgColNDVI.qualityMosaic('nd');
else:
return imgCol.qualityMosaic('temp');
def HQComposite(imgCol):
maskedImgCol = imgCol.sort('CLOUD_COVER', False).map(maskBad);
return CompositeStrategy(maskedImgCol)
def export_oneimage(img, folder, name, region, scale, crs):
task = ee.batch.Export.image(img, name, {
'driveFolder': folder,
'driveFileNamePrefix': name,
'region': region,
'scale': scale,
'crs': crs,
'maxPixels': 1e11
})
task.start()
while task.status()['state'] == 'RUNNING':
print 'Running...'
# Perhaps task.cancel() at some point.
time.sleep(10)
print 'Done.', task.status()
LT45_BANDS = ['B1', 'B2', 'B3', 'B4', 'B5', 'B7', 'B6', 'radsat_qa', 'pixel_qa'];
# LE7_BANDS = ['B1', 'B2', 'B3', 'B4', 'B5', 'B7', 'B6', 'radsat_qa', 'pixel_qa'];
# LC8_BANDS = ['B2', 'B3', 'B4', 'B5', 'B6', 'B7', 'B10', 'radsat_qa', 'pixel_qa'];
STD_NAMES = ['blue', 'green', 'red', 'nir', 'swir1', 'swir2', 'temp', 'radsat_qa', 'pixel_qa'];
# Poyang lake: 115.4745,28.2953,116.955,29.8416
Poyang = ee.Geometry.Rectangle(115.4745,28.2953,116.955,29.8416);
ee.Geometry.Polygon([[[34, -2],[34, -3],[35, -3],[35, -2]]])
imgCol = ee.ImageCollection('LANDSAT/LT05/C01/T1_SR').select(LT45_BANDS, STD_NAMES)\
.filterDate('2010-01-01', '2010-12-01')\
.filterBounds(Poyang) # Set temporal extent and spatial extent here
# print(imgCol.first().getInfo())
# mosaicImg = imgCol.mosaic().clip(Poyang).toFloat().getDownloadUrl({
# 'scale': 1000,
# 'crs': 'EPSG:4326',
# 'region': '[[115.4745, 29.8416], [116.955, 29.8416], [116.955, 28.2953], [115.4745, 28.2953]]'
# # })
# Producing high quality mosaic image
if PARADIGM == 'pixel':
mosaicImg = HQComposite(imgCol);
else:
mosaicImg = CompositeStrategy(imgCol.sort('CLOUD_COVER', False));
# print(mosaicImg)
# export parameters
outputFolder = 'HQExport'
outputFileName = 'L5_exportImg'
scale = 1000 # modify image resolution
crs = 'EPSG:4326'
# set export region
region = str([[115.4745, 29.8416], [116.955, 29.8416], [116.955, 28.2953], [115.4745, 28.2953]])
# export
export_oneimage(mosaicImg, outputFolder, outputFileName, region, scale, crs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment