Skip to content

Instantly share code, notes, and snippets.

@YanCheng-go
Last active February 20, 2019 20:14
Show Gist options
  • Save YanCheng-go/6f692136ab05e1f2345892fd0abb03dc to your computer and use it in GitHub Desktop.
Save YanCheng-go/6f692136ab05e1f2345892fd0abb03dc to your computer and use it in GitHub Desktop.
Detect clouds and cloud shadows for PlanetScope imagery (a monthly threshold-based decision tree)
import ee
ee.Initialize()
import numpy as np
import matplotlib.pyplot as plt
import re
import pandas as pd
import matplotlib.ticker as mticker
def hist_data(image_date, stack_dict = None,
plot = None, band_selection = None, bar_num = None, save_plot = None, path_plot = None, geom_shp = None):
if save_plot is None:
save_plot = False
if plot is None:
plot = 'other'
if band_selection is None:
band_selection = False
if bar_num is None:
bar_num = 70
if geom_shp is None:
geom = ee.FeatureCollection("users/ychengnl/Kapiti_shp").geometry()
else:
geom = ee.FeatureCollection("users/ychengnl/few_cloud_veg_shp/"+geom_shp).geometry()
if stack_dict is None:
image = ee.Image("users/ychengnl/image_null/" + image_date)
stack = image
else:
stack = stack_dict[image_date]
# compute the histogram
# set the geometry of the image to use as region in the function reduceRegion
base_image = ee.Image("users/ychengnl/20170303")
# geom = image.geometry()
# set the original scale of the image
scale = base_image.projection().nominalScale()
# compute the histogram
bfreq = stack.reduceRegion(
reducer = ee.Reducer.frequencyHistogram(), #.unweighted(),
geometry = geom,
scale = 3,
maxPixels = 400000000
# ,tileScale = 2
).getInfo()
# print(stack)
band_names = [x for x in bfreq.keys()]
# The output of reduceRegion is a dictionary with the format:
# {'bandname': {'key':value}}
# We will build series for x values and y values in order to build the histogram
# define two dictionaries for frequencies and values respectively
freqs = {}
vals = {}
title = band_names
color = ['b', 'g', 'r', 'purple', 'yellow']
i = 0
# def func(aaa, plot):
# populate dictionaries
if band_selection is False:
aaa = bfreq.keys()
else:
aaa = band_selection
for l in aaa:
d = bfreq[l]
# print(d)
freq = []
val = []
for k,v in d.items():
if not(k == 'null'):
if abs(float(k)) < 1:
# print('times 10000.0')
k = float(k)*10000.0
else:
k = k
val.append(int(float(k)))
freq.append(int(float(v)))
freqs[l] = freq
vals[l] = val
# print('Minimum and maximum value for %s is %.2f %.2f' % (l, np.min(val), np.max(val) ))
if plot is 'initial':
f, ax1 = plt.subplots(1,1)
ax1.bar( vals[l] ,freqs[l],color= color[i],edgecolor= color[i])
ax1.set_title('Histogram of ' + title[i], fontsize=9)
ax1.set_xlabel('Values', fontsize=8)
ax1.set_ylabel('Count', fontsize=8)
ax1.tick_params( labelsize =8)
ax1.set_xlim(0,np.max(val))
plt.show()
if save_plot is True:
f.savefig(path_plot + image_date + '_' + title[i])
i = i+1
if plot is 'simplified':
freqs_ = []
vals_ = []
freqs_ = freqs_+freq
vals_ = vals_+val
df = pd.concat([pd.DataFrame(freqs_),pd.DataFrame(vals_)],axis =1)
df.columns = ['freqs','vals']
hist = df.groupby(['vals'], as_index=False).sum()
max_val = np.max(val)
min_val = np.min(val)
step = int(float((max_val - min_val)/bar_num))
bins = np.arange(start = min_val, stop = max_val, step = step)
labels = bins[1:]
hist['binned'] = pd.cut(hist['vals'], bins = bins, labels = labels)
df_ = hist[['freqs','binned']]
hist_ = df_.groupby(['binned'], as_index=False).sum()
fig, ax = plt.subplots()
ax.bar(hist_['binned'].astype(str), hist_['freqs'])
ax.set_title('Histogram of ' + l + ' on ' + image_date, fontsize=9)
myLocator = mticker.MultipleLocator(int(float(len(labels)/5)))
ax.xaxis.set_major_locator(myLocator)
plt.show()
if save_plot is True:
fig.savefig(path_plot + image_date + '_' + title[i])
i = i+1
return freqs,vals,band_names
def hist_agg(cloud_free, period, stack_dict = None, plot = None, band_selection = None, geom_shp_list = None, save_plot = None, path_plot = None):
# if plot is None:
# plot = 'other'
# if save_plot is None:
# save_plot_ is False
if period is 'all':
cloud_free_ = cloud_free
# print(cloud_free_, '\n')
else:
cloud_free_ = []
for i in period:
r = re.compile('^'+i+'')
cloud_free_ = cloud_free_ + list(filter(r.match, cloud_free))
# print(cloud_free_, '\n')
if stack_dict is None:
stack_dict = None
dict_ = {}
hist_dict = {}
# idx = 0
for i in cloud_free_:
if geom_shp_list is None:
geom_shp = None
else:
idx = cloud_free.index(i)
geom_shp = geom_shp_list[idx]
# print(geom_shp)
# print(i)
freqs_, vals_, band_names = hist_data(image_date = i, stack_dict = stack_dict, plot = plot, band_selection = band_selection, geom_shp = geom_shp, save_plot = save_plot, path_plot = path_plot)
dict_[i] = {'freqs': freqs_,'vals': vals_}
for j in band_names:
a = []
b = []
for i in cloud_free_:
a = a+dict_[i]['freqs'][j]
b = b+dict_[i]['vals'][j]
df = pd.concat([pd.DataFrame(a),pd.DataFrame(b)],axis =1)
df.columns = ['freqs','vals']
hist_ = df.groupby(['vals'], as_index=False).sum()
hist_dict[j] = {'vals': hist_['vals'].tolist(), 'freqs': hist_['freqs'].tolist()}
# print(hist_dict)
if plot is not None:
fig, ax = plt.subplots()
ax.bar(hist_['vals'], hist_['freqs'])
ax.set_title('Histogram of ' + j + ' in ' + ' '.join(str(e) for e in period), fontsize=9)
ax.set_xlim(left=0)
plt.show()
if save_plot is True:
fig.savefig(path_plot + ' '.join(str(e) for e in period) + '_' +j)
return hist_dict,band_names
def hist_threshold(hist_dict, band_name, percentile_lower, percentile_upper):
hist_df = pd.DataFrame({'vals':hist_dict[band_name]['vals'],'freqs':hist_dict[band_name]['freqs']})
hist_df["freqs_cum"] = hist_df.freqs.cumsum()
hist_df['cum_perc'] = 100*hist_df.freqs_cum/hist_df.freqs.sum()
# print('lower threshold: \n', hist_df.loc[hist_df['cum_perc'] >= percentile_lower].iloc[0], '\n')
# print('upper threshold: \n', hist_df.loc[hist_df['cum_perc'] >= percentile_upper].iloc[0], '\n')
if percentile_lower == 0:
threshold_lower = hist_df.iloc[0,0]
else:
threshold_lower = hist_df.loc[hist_df['cum_perc'] >= percentile_lower].iloc[0,0]
if percentile_upper == 100:
threshold_upper = hist_df.iloc[-1,0]
else:
threshold_upper = hist_df.loc[hist_df['cum_perc'] >= percentile_upper].iloc[0,0]
return threshold_lower, threshold_upper
def get_thresholds(cloud_free, percentile_lower, percentile_upper, math_equation_,
glcm_bands_, changed_eq_ = None, band_selection = None, geom_shp_list = None):
lower_ = []
upper_ = []
hist_dict,band_names = hist_agg(cloud_free = cloud_free, period = 'all', band_selection = band_selection,
geom_shp_list = geom_shp_list)
for j in band_names:
threshold_lower, threshold_upper = hist_threshold(hist_dict = hist_dict, band_name = j,
percentile_lower = percentile_lower,
percentile_upper = percentile_upper)
lower_.append(threshold_lower)
upper_.append(threshold_upper)
print('band names: ',band_names)
print('threshold_lower_list: ',lower_)
print('threshold_upper_list: ',upper_)
if len(math_equation_) != 0:
idx = 0
for i in math_equation_:
upper_ = []
lower_ = []
stack_dict = {}
changed_eq = changed_eq_[idx]
for j in cloud_free:
if changed_eq_ is None:
stack_dict[j] = band_math(image_date = j, equation = i)
else:
stack_dict[j] = band_math(image_date = j, equation = i, changed_eq = changed_eq)
hist_dict,band_names = hist_agg(cloud_free = cloud_free, stack_dict = stack_dict, period = 'all',
geom_shp_list = geom_shp_list)
for j in band_names:
threshold_lower, threshold_upper = hist_threshold(hist_dict = hist_dict, band_name = j,
percentile_lower = percentile_lower,
percentile_upper = percentile_upper)
lower_.append(threshold_lower)
upper_.append(threshold_upper)
print('thresholds of ', i)
print('threshold_lower_list: ',lower_)
print('threshold_upper_list: ',upper_)
idx = idx+1
if len(glcm_bands_) != 0:
for i in glcm_bands_:
upper_ = []
lower_ = []
stack_dict = {}
for j in cloud_free:
stack_dict[j] = glcm(image_date = j, band_names = i)
hist_dict,band_names = hist_agg(cloud_free = cloud_free, stack_dict = stack_dict, period = 'all',
geom_shp_list = geom_shp_list)
for j in band_names:
threshold_lower, threshold_upper = hist_threshold(hist_dict = hist_dict, band_name = j,
percentile_lower = percentile_lower,
percentile_upper = percentile_upper)
lower_.append(threshold_lower)
upper_.append(threshold_upper)
print('thresholds of ', i)
print('threshold_lower_list: ',lower_)
print('threshold_upper_list: ',upper_)
# # Test
# # Visuallize histogram
# hist_data(image_date = '20170307', plot = 'simplified', band_selection = ['b1'], bar_num = 50)
# # set values
# cloud_free = ['20170307','20170314','20170526','20170707','20170708_1','20170708_2','20170712','20170716','20170718','20170827_1',
# '20170827_2','20170918','20170922_1','20170925','20171003','20171017','20171210','20171224','20171227','20171230'
# ,'20180108','20180114','20180123','20180125','20180127','20180129','20180202','20180204','20180208','20180209',
# '20180213','20180224','20180226','20180323','20180528','20180529','20180717','20180803_2','20180807']
# percentile_lower = 2
# percentile_upper = 98
# period_list = ['201703','201705','201707','201708','201709','201710','201712','201801',
# '201802','201803','201805','201807','201808']
# # combine all data
# hist_dict,band_names = hist_agg(cloud_free = cloud_free, period = 'all')
# for j in band_names:
# threshold_lower, threshold_upper = hist_threshold(hist_dict = hist_dict, band_name = j,
# percentile_lower = percentile_lower,
# percentile_upper = percentile_upper)
# print('In band',j,':')
# print('threshold_lower: ', threshold_lower)
# print('threshold_upper: ', threshold_upper,'\n')
# # combine all data in the same month
# for i in period_list:
# print('In ' + i)
# hist_dict,band_names = hist_agg(cloud_free = cloud_free, period = [i])
# for j in band_names:
# threshold_lower, threshold_upper = hist_threshold(hist_dict = hist_dict, band_name = j,
# percentile_lower = percentile_lower,
# percentile_upper = percentile_upper)
# print('In band',j,':')
# print('threshold_lower: ', threshold_lower)
# print('threshold_upper: ', threshold_upper,'\n')
## cloud detection (classiification) was conducted in google earth engine
## https://code.earthengine.google.com/97e92f502f14e0110e66c3ae29cba021
# b2 and b4 and gdal
from osgeo import gdal, gdal_array
import numpy as np
from tqdm import tqdm_notebook
import os
def cloud_detection(b2_tds, b4_tds, time, date_cloud, date_cloud_free, work_dir, input_dir, output_dir = None):
if output_dir is None:
# work_dir = Path(input_dir).parent
# output_dir = str(work_dir) + '\output\merge'
output_dir = work_dir+'\\cloud_mask'
if os.path.exists(output_dir) == False:
os.mkdir(output_dir)
print('The output will be saved in this directory: ' + output_dir)
def cloud(date):
YM = date[0:6]
idx = time.index(YM)
b2_td = b2_tds[idx]
b4_td = b4_tds[idx]
image = input_dir+'\\'+date +'.tif'
output = output_dir +'\\'+date +'.tif'
# Open band 1 as array
ds = gdal.Open(image)
b4 = ds.GetRasterBand(4)
b2 = ds.GetRasterBand(2)
b2_arr = b2.ReadAsArray()
b4_arr = b4.ReadAsArray()
data = np.zeros_like(b4_arr).astype(np.uint16)
b4_data = np.where(((b4_arr < b4_td[0]) & (b4_arr > 0)), 1, data)
b4_data = np.where(((b4_arr >= b4_td[0]) & (b4_arr < b4_td[1])), 3, b4_data)
b4_data = np.where((b4_arr >= b4_td[1]), 2, b4_data)
b2_data = np.where(((b2_arr < b2_td[0]) & (b2_arr > 0)), 1, data)
b2_data = np.where(((b2_arr >= b2_td[0]) & (b2_arr < b2_td[1])), 3, b2_data)
b2_data = np.where((b2_arr >= b2_td[1]), 2, b2_data)
a = b2_data
b = b4_data
data = np.where((a==3)|(b==3),3,data)
data = np.where((b==1),1,data)
data = np.where((a==2),2,data)
data = np.where(((a==1)&(b==2)),3,data)
# save array, using ds as a prototype
gdal_array.SaveArray(data, output, "GTIFF", ds)
ds = None
list(map(cloud, tqdm_notebook(list(date_cloud), total=len(date_cloud), unit='file', desc = 'cloud detection')))
def cloud_free(date):
base_image = r'D:\Kapiti\cloud_mask\20170303.tif'
input_dir = r'D:\Kapiti\merge_clip'
output_dir = r'D:\Kapiti\cloud_mask'
image = input_dir+'\\'+date +'.tif'
output = output_dir +'\\'+date +'.tif'
# Open band 1 as array
ds = gdal.Open(base_image)
b1 = ds.GetRasterBand(1)
b1_arr = b1.ReadAsArray()
data = np.zeros_like(b1_arr).astype(np.uint16)
data = np.where((((b1_arr==1)|(b1_arr==2))|(b1_arr==3)),3,data)
# save array, using ds as a prototype
gdal_array.SaveArray(data, output, "GTIFF", ds)
ds = None
list(map(cloud_free, tqdm_notebook(date_cloud_free, total=len(date_cloud_free), unit='file', desc = 'cloud detection')))
# b2_tds = [[661,1474],[789,2732],[413,1681],[681,2076],[656,1757],[698,1640],
# [756,1782],[648,1725],[623,2581],[719,1733],[672,1716],[781,1962],[453,1602],
# [639,1356],[417,1688],[528,1591],[542,1422],[687,1940],[685,1555],[685,1555]];
# b4_tds = [[1635,2925],[1829,4018],[1899,3627],[2095,4250],[1814,3167],
# [1658,3141],[1688,3201],[1618,3164],[1708,4243],[1943,3361],[1592,3356],
# [1668,3411],[1765,3265],[2197,4042],[2532,5613],[2566,5330],[2579,5022],
# [2172,4014],[1941,3149],[1941,3149]]
# time = ['201703','201704','201705','201706','201707','201708','201709'
# ,'201710','201711','201712','201801','201802','201803','201804','201805'
# ,'201806','201807','201808','201809','201810']
# work_dir = r'D:\Kapiti'
# input_dir = r'D:\Kapiti\merge_clip'
# # output_dir = r'D:\Kapiti\cloud_mask'
# cloud_detection(b2_tds, b4_tds, time, date_cloud, date_cloud_free, work_dir, input_dir)
import ee
ee.Initialize()
def cloud_detection(b2Dict,b4Dict,b2savgDict,b4savgDict, date_cloud, date_cloud_free, imageCollection, cutline,
layer, folder_name = None,index = None, suffix = None):
if suffix is None:
suffix = ''
Kapiti_shp = ee.FeatureCollection(cutline);
# collection = ee.ImageCollection(imageCollection)
# imageCollection = collection.toList(collection.size())
date_all = list(set(date_cloud+date_cloud_free))
date_all.sort()
def cloud(date):
# index = date_all.index(date)
datePath = date
# image = ee.Image(imageCollection.get(index))
image = ee.Image(imageCollection+datePath)
# print(image)
YM = datePath[0:6];
b2Low = ee.List(b2Dict.get(YM)).get(0)
b2Up = ee.List(b2Dict.get(YM)).get(1)
b4Low = ee.List(b4Dict.get(YM)).get(0)
b4Up = ee.List(b4Dict.get(YM)).get(1)
b2savgLow = ee.List(b2savgDict.get(YM)).get(0)
b2savgUp = ee.List(b2savgDict.get(YM)).get(1)
b4savgLow = ee.List(b4savgDict.get(YM)).get(0)
b4savgUp = ee.List(b4savgDict.get(YM)).get(1)
features = ['b1','b2','b3','b4','b1_savg','b2_savg','b4_savg','b1Db3Ab4']
lower = [-999,b2Low,-999,b4Low,-999,b2savgLow,b4savgLow,-999];
upper = [-999,b2Up,-999,b4Up,-999,b2savgUp,b4savgUp,-999]
glcm = image.glcmTexture()
b1Db3Ab4 = image.expression('float(b1)/(float(b3)+float(b4))*10000.0',{
'b3': image.select(['b3']),
'b4': image.select(['b4']),
'b1': image.select(['b1'])
}).select(['b1'],['b1Db3Ab4'])
stack = image.addBands(glcm.select(['b1_savg'])).addBands(glcm.select(['b2_savg'])).addBands(glcm.select(['b4_savg'])).addBands(b1Db3Ab4.select(['b1Db3Ab4']));
# Classification based on one band
def func3(i):
cloudMask = stack.select(features[i]).gte(ee.Number(upper[i])).clip(Kapiti_shp.geometry())
shadowMask = stack.select(features[i]).lt(ee.Number(lower[i])).clip(Kapiti_shp.geometry())
vegMask1 = stack.select(features[i]).lt(ee.Number(upper[i])).clip(Kapiti_shp.geometry())
vegMask2 = stack.select(features[i]).gte(ee.Number(lower[i])).clip(Kapiti_shp.geometry())
vegMask = vegMask1.addBands(vegMask2)
vegMask = vegMask.expression('(a==1&&b==1)?1:0',{
'a': vegMask.select(0),
'b': vegMask.select(1)
}).clip(Kapiti_shp.geometry())
shadowMask = shadowMask.remap([0,1],[0,1],defaultValue=-9999).select(['remapped'],['shadowMask'])
cloudMask = cloudMask.remap([0,1],[0,2],defaultValue=-9999).select(['remapped'],['cloudMask'])
vegMask = vegMask.remap([0,1],[0,3],defaultValue=-9999).select(['remapped'],['vegMask'])
image2 = stack.addBands(shadowMask).addBands(cloudMask).addBands(vegMask)
image2 = image2.select(image2.bandNames(),stack.bandNames().add('shadowMask').add('cloudMask').add('vegMask'));
classified = image2.expression('a>b&&a>c?a:(b>a&&b>c?b:c)',{
'a': image2.select('shadowMask'),
'b': image2.select('cloudMask'),
'c': image2.select('vegMask')
}).clip(Kapiti_shp.geometry())
return classified
classified_b2 = func3(1)
classified_b4 = func3(3)
classified_b2savg = func3(5)
classified_b4savg = func3(6)
# Classification based on b2, b4, b2_savg and b4_savg
classified_stack3 = classified_b4.addBands(classified_b2).addBands(classified_b4savg).addBands(classified_b2savg)
classified_final3 = classified_stack3.expression('(b==1||d==1)?1'+':(b==3||d==3)&&(a!=2&&c!=2)?3'+':((a==1||c==1)&&(b!=2||d!=2))?1'+':a==2||c==2?2'+':((a==3||c==3)&&(b!=1||d!=1))?3'+':((a==1||c==1)&&(b==2||d==2))?3'+':a',{
'a': classified_stack3.select(1),
'b': classified_stack3.select(0),
'c': classified_stack3.select(3),
'd': classified_stack3.select(2)
}).clip(Kapiti_shp.geometry())
# time_now = str(datetime.now())
# time_now.replace(" ", "_")
# if folder_id is None:
# folder_metadata = {
# 'name': 'folder_'+time_now,
# 'mimeType': 'application/vnd.google-apps.folder'
# }
# file = drive_service.files().create(body=folder_metadata,
# fields='id').execute()
# folder_name = folder_metadata['name']
# print('Save files in folder: %s' % folder_name)
# else:
# folder_name = folder_id
if layer == 'cloudMask':
mytask = ee.batch.Export.image.toDrive(image=ee.Image(classified_final3),description=datePath+'_cloudMask'+suffix, folder=folder_name,scale=3)
ee.batch.data.startProcessing(mytask.id, mytask.config)
if layer == 'NDVI_cloudMask':
Mask_final = classified_final3.remap([-9999,1,2,3],[0,0,0,1],defaultValue=0).select(['remapped'],['Mask'])
NDVI = image.normalizedDifference(['b4','b3']).select(['nd'],['NDVI'])
stack = NDVI.addBands(Mask_final);
NDVI_cloudMask = stack.expression('a*b',{
'a': stack.select(0),
'b': stack.select(1),
}).clip(Kapiti_shp.geometry())
mytask = ee.batch.Export.image.toDrive(image=ee.Image(NDVI_cloudMask),description=datePath+'_NDVI_cloudMask'+suffix, folder=folder_name,scale=3)
ee.batch.data.startProcessing(mytask.id, mytask.config)
if index is None:
list(map(cloud, tqdm_notebook(date_cloud, total=len(date_cloud), unit='file', desc = 'cloud detection')))
# else:
# Cloud-free image preprocessing
def cloud_free(date):
# index = date_all.index(date)
datePath = date
# image = ee.Image(imageCollection.get(index))
image = ee.Image(imageCollection+datePath).clip(Kapiti_shp.geometry())
if layer == 'cloudMask':
cloudMask = image.expression('a?3:0',{
'a': image.select(0)
}).clip(Kapiti_shp.geometry());
mytask = ee.batch.Export.image.toDrive(image=ee.Image(cloudMask),description=datePath+'_cloudMask'+suffix, folder=folder_name,scale=3)
ee.batch.data.startProcessing(mytask.id, mytask.config)
if layer == 'NDVI_cloudMask':
NDVI_cloudMask = image.normalizedDifference(['b4','b3']).select(['nd'],['NDVI']).clip(Kapiti_shp.geometry())
mytask = ee.batch.Export.image.toDrive(image=ee.Image(NDVI_cloudMask),description=datePath+'_NDVI_cloudMask'+suffix, folder=folder_name,scale=3)
ee.batch.data.startProcessing(mytask.id, mytask.config)
if index is None:
list(map(cloud_free, tqdm_notebook(date_cloud_free, total=len(date_cloud_free), unit='file', desc = 'cloud detection')))
# else:
# cloud_free(index)
# # Define monthly thresholds of important bands
# b2 = [[661,1474],[789,2732],[413,1681],[681,2076],[656,1757],[698,1640],
# [756,1782],[648,1725],[623,2581],[719,1733],[672,1716],[781,1962],[453,1602],
# [639,1356],[417,1688],[528,1591],[542,1422],[687,1940],[685,1555],[685,1555]]
# b4 = [[1635,2925],[1829,4018],[1899,3627],[2095,4250],[1814,3167],
# [1658,3141],[1688,3201],[1618,3164],[1708,4243],[1943,3361],[1592,3356],
# [1668,3411],[1765,3265],[2197,4042],[2532,5613],[2566,5330],[2579,5022],
# [2172,4014],[1941,3149],[1941,3149]]
# b2savg = [[1326,2934],[1585,5461],[833,3337],[1372,4140],[1318,3507],
# [1401,3257],[1518,3541],[1303,3431],[1248,5156],[1442,3451],[1349,3407],
# [1569,3901],[943,2918],[1280,2669],[842,2462],[1061,3172],[1091,2812],
# [1379,3851],[1374,3095],[1374,3095]]
# b4savg = [[3277,5830],[3663,8031],[3808,7237],[4203,8483],[3635,6318],
# [3323,6262],[3382,6382],[3243,6303],[3418,8467],[3892,6708],[3187,6691],
# [3340,6802],[3635,7355],[4398,8055],[5080,9532],[5144,10650],[5175,10038],
# [4355,8014],[3890,6287],[3890,6287]]
# time = ['201703','201704','201705','201706','201707','201708','201709'
# ,'201710','201711','201712','201801','201802','201803','201804','201805'
# ,'201806','201807','201808','201809','201810']
# b2Dict = ee.Dictionary.fromLists(time, b2)
# b4Dict = ee.Dictionary.fromLists(time, b4)
# b2savgDict = ee.Dictionary.fromLists(time, b2savg)
# b4savgDict = ee.Dictionary.fromLists(time, b4savg)
# cutline ="users/ychengnl/Kapiti_shp"
# imageCollection = "users/ychengnl/image_null/"
# layer = 'NDVI_cloudMask'
# # index = 0
# folder_name = 'cloudMask'
# # date_cloud= ['20171007_1', '20171007_2', '20171013', '20171016', '20171024', '20171028', '20171106', '20171109', '20171116', '20171117', '20171124_1', '20171124_2', '20171125', '20171126', '20171127', '20171129', '20171202', '20171203', '20171204', '20171210', '20171212', '20171213', '20171215', '20171216', '20171227', '20180107', '20180108', '20180117', '20180118', '20180202', '20180213', '20180218', '20180222', '20180226', '20180228', '20180305', '20180306', '20180308', '20180323', '20180324', '20180326', '20180401', '20180409', '20180420', '20180506', '20180514', '20180515', '20180516', '20180523', '20180524', '20180526', '20180529', '20180530_1', '20180530_2', '20180602', '20180606', '20180611_1', '20180611_2', '20180622', '20180623', '20180628', '20180701', '20180703', '20180705', '20180706', '20180709', '20180716', '20180718', '20180719', '20180722', '20180723', '20180727', '20180730', '20180802', '20180803_1', '20180803_2', '20180806', '20180807', '20180808', '20180809', '20180812_1', '20180812_2', '20180814', '20180822', '20180824', '20180825', '20180830', '20180905', '20180907', '20180908_1', '20180908_2', '20180909', '20180910', '20180911', '20180912_1', '20180912_2', '20180913', '20180915', '20180920', '20180921', '20180926', '20180928', '20180929', '20181001', '20181003']
# date_cloud_free= ['20171017','20171224','20171230','20171231','20180114','20180123','20180125','20180127',
# '20180129','20180204','20180208','20180209','20180224','20180528','20180717','20180916',
# '20180930_1','20180930_2']
# cloud_detection(b2Dict,b4Dict,b2savgDict,b4savgDict, date_cloud, date_cloud_free, imageCollection, cutline,
# layer,folder_name, index = None, suffix = None)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment