or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

cloud-masking.mdcollection-operations.mdcompositing.mdexport-download.mdimage-processing.mdindex.mdinitialization.md

cloud-masking.mddocs/

0

# Cloud Masking

1

2

Specialized cloud and shadow masking for Landsat and Sentinel-2 imagery with configurable algorithms and thresholds. Geedim provides automatic detection of image collection types and applies appropriate masking methods.

3

4

## Capabilities

5

6

### Cloud Mask Methods

7

8

Enumeration of available cloud masking methods for Sentinel-2 imagery.

9

10

```python { .api }

11

class CloudMaskMethod(Enum):

12

"""Enumeration for Sentinel-2 cloud masking methods."""

13

14

cloud_prob = 'cloud-prob'

15

"""

16

Threshold the Sentinel-2 Cloud Probability.

17

18

Deprecated since version 1.9.0: Please use the cloud_score method.

19

"""

20

21

qa = 'qa'

22

"""

23

Bit mask the QA60 quality assessment band.

24

25

Deprecated since version 1.9.0: Please use the cloud_score method.

26

"""

27

28

cloud_score = 'cloud-score'

29

"""

30

Threshold the Sentinel-2 Cloud Score+.

31

32

Uses the GOOGLE_CLOUD_SCORE_PLUS_V1_S2_HARMONIZED dataset.

33

"""

34

```

35

36

### Cloud Score Bands

37

38

Enumeration for Sentinel-2 Cloud Score+ bands used with the cloud_score method.

39

40

```python { .api }

41

class CloudScoreBand(Enum):

42

"""Enumeration for Sentinel-2 Cloud Score+ bands."""

43

44

cs = 'cs'

45

"""

46

Pixel quality score based on spectral distance from a clear reference.

47

"""

48

49

cs_cdf = 'cs_cdf'

50

"""

51

Cumulative distribution function value of possible cs values.

52

"""

53

```

54

55

### Masking Parameters

56

57

Cloud masking parameters vary by image collection type:

58

59

#### Landsat Parameters

60

61

```python { .api }

62

def addMaskBands(

63

mask_cirrus: bool = True,

64

mask_shadows: bool = True,

65

**kwargs

66

) -> ee.Image:

67

"""

68

Add mask bands for Landsat imagery.

69

70

Parameters:

71

- mask_cirrus (bool): Whether to mask cirrus clouds (valid for Landsat 8-9)

72

- mask_shadows (bool): Whether to mask cloud shadows

73

- **kwargs: Additional masking parameters

74

"""

75

```

76

77

#### Sentinel-2 Parameters

78

79

```python { .api }

80

def addMaskBands(

81

method: CloudMaskMethod = CloudMaskMethod.cloud_score,

82

prob: float = 0.6,

83

cloud_dist: float = 1000.0,

84

band: CloudScoreBand = CloudScoreBand.cs_cdf,

85

**kwargs

86

) -> ee.Image:

87

"""

88

Add mask bands for Sentinel-2 imagery.

89

90

Parameters:

91

- method (CloudMaskMethod): Cloud masking method

92

- prob (float): Cloud probability threshold (0.0-1.0)

93

- cloud_dist (float): Maximum cloud distance in meters

94

- band (CloudScoreBand): Cloud Score+ band to use

95

- **kwargs: Additional masking parameters

96

"""

97

```

98

99

### Mask Band Types

100

101

Different mask bands are automatically added based on image type:

102

103

```python { .api }

104

# Common mask bands

105

FILL_MASK: ee.Image # Valid data mask

106

CLOUDLESS_MASK: ee.Image # Cloud-free pixels mask

107

CLOUD_DIST: ee.Image # Distance to nearest cloud (meters)

108

109

# Landsat-specific bands

110

QA_MASK: ee.Image # Quality assessment mask

111

SHADOW_MASK: ee.Image # Cloud shadow mask

112

CIRRUS_MASK: ee.Image # Cirrus cloud mask

113

114

# Sentinel-2 specific bands

115

CLOUD_PROB: ee.Image # Cloud probability (0-100)

116

CLOUD_SCORE: ee.Image # Cloud Score+ value

117

```

118

119

### Coverage Statistics

120

121

Calculate cloud coverage and fill statistics for regions:

122

123

```python { .api }

124

def set_mask_portions(

125

ee_image: ee.Image,

126

region: dict | ee.Geometry = None,

127

scale: float = None

128

) -> ee.Image:

129

"""

130

Set FILL_PORTION and CLOUDLESS_PORTION properties.

131

132

Parameters:

133

- ee_image (ee.Image): Image to analyze

134

- region (dict | ee.Geometry, optional): Analysis region

135

- scale (float, optional): Analysis scale in meters

136

137

Returns:

138

ee.Image: Image with portion properties set

139

"""

140

```

141

142

## Usage Examples

143

144

### Landsat Cloud Masking

145

146

```python

147

import ee

148

import geedim

149

150

geedim.Initialize()

151

152

# Load Landsat 8 image

153

image = ee.Image('LANDSAT/LC08/C02/T1_L2/LC08_173083_20200601')

154

155

# Add mask bands with custom parameters

156

masked_image = image.gd.addMaskBands(

157

mask_cirrus=True, # Mask cirrus clouds

158

mask_shadows=True # Mask cloud shadows

159

)

160

161

# Apply cloud masking

162

cloud_free = masked_image.maskClouds()

163

164

# Check cloud coverage

165

region = ee.Geometry.Point(-122.4194, 37.7749).buffer(10000)

166

coverage_image = masked_image.gd.set_mask_portions(region=region, scale=30)

167

168

# Get coverage statistics from image properties

169

fill_portion = coverage_image.get('FILL_PORTION').getInfo()

170

cloudless_portion = coverage_image.get('CLOUDLESS_PORTION').getInfo()

171

172

print(f"Fill portion: {fill_portion}%")

173

print(f"Cloudless portion: {cloudless_portion}%")

174

```

175

176

### Sentinel-2 Cloud Masking

177

178

```python

179

# Load Sentinel-2 image

180

s2_image = ee.Image('COPERNICUS/S2_SR_HARMONIZED/20200601T185751_20200601T185931_T10SEG')

181

182

# Add mask bands using Cloud Score+ method

183

masked_s2 = s2_image.gd.addMaskBands(

184

method=geedim.CloudMaskMethod.cloud_score,

185

prob=0.65, # 65% cloud probability threshold

186

cloud_dist=2000, # 2km maximum cloud distance

187

band=geedim.CloudScoreBand.cs_cdf # Use CDF band

188

)

189

190

# Apply cloud masking

191

cloud_free_s2 = masked_s2.maskClouds()

192

193

# Alternative: Use legacy methods (deprecated)

194

legacy_masked = s2_image.gd.addMaskBands(

195

method=geedim.CloudMaskMethod.qa, # QA60 band method

196

prob=0.6

197

)

198

```

199

200

### Collection-Wide Cloud Masking

201

202

```python

203

# Load image collection

204

collection = ee.ImageCollection('LANDSAT/LC08/C02/T1_L2') \

205

.filterDate('2020-01-01', '2020-12-31') \

206

.filterBounds(region)

207

208

# Add mask bands to entire collection

209

masked_collection = collection.gd.addMaskBands(

210

mask_cirrus=True,

211

mask_shadows=True

212

)

213

214

# Apply cloud masking to all images

215

cloud_free_collection = masked_collection.maskClouds()

216

217

# Filter by cloud coverage

218

low_cloud_collection = collection.gd.search(

219

start_date='2020-06-01',

220

end_date='2020-09-30',

221

cloudless_portion=80, # Minimum 80% cloud-free

222

fill_portion=95 # Minimum 95% valid data

223

)

224

```

225

226

### Advanced Masking Configuration

227

228

```python

229

# Custom cloud distance calculation

230

def custom_cloud_masking(image):

231

# Add mask bands with custom parameters

232

masked = image.gd.addMaskBands(

233

method=geedim.CloudMaskMethod.cloud_score,

234

prob=0.5, # Lower threshold for more aggressive masking

235

cloud_dist=5000, # 5km cloud buffer

236

band=geedim.CloudScoreBand.cs # Use raw cloud score

237

)

238

239

# Get cloud distance band for analysis

240

cloud_dist = masked.select('CLOUD_DIST')

241

242

# Apply masking

243

return masked.maskClouds()

244

245

# Apply to collection

246

custom_masked = collection.map(custom_cloud_masking)

247

```

248

249

### Mask Quality Assessment

250

251

```python

252

# Analyze mask quality for a region

253

def assess_mask_quality(image, region, scale=30):

254

# Add mask bands and calculate portions

255

masked = image.gd.addMaskBands().gd.set_mask_portions(

256

region=region,

257

scale=scale

258

)

259

260

# Extract mask statistics

261

stats = {

262

'image_id': image.get('system:id').getInfo(),

263

'fill_portion': masked.get('FILL_PORTION').getInfo(),

264

'cloudless_portion': masked.get('CLOUDLESS_PORTION').getInfo(),

265

'date': image.date().format('YYYY-MM-dd').getInfo()

266

}

267

268

return stats

269

270

# Assess collection

271

region = ee.Geometry.Rectangle([-122.5, 37.7, -122.3, 37.8])

272

collection_list = collection.limit(10).getInfo()['features']

273

274

quality_stats = []

275

for img_info in collection_list:

276

img = ee.Image(img_info['id'])

277

stats = assess_mask_quality(img, region)

278

quality_stats.append(stats)

279

280

# Print results

281

for stats in quality_stats:

282

print(f"{stats['date']}: {stats['cloudless_portion']:.1f}% cloud-free")

283

```