I have the task to mask out cloud cover in approximately 20 landsat 8 scenes. Creating the cloud mask for the "white part" is easy, but I need help in addressing the clouds shadow.

General information about the shadow is that it occurs in a particular direction/distance from the cloud dependent on height/topography etc.

All I need to know is if there is a easy/automated way to shift my original cloud (white part) mask by a certain distance and direction to generally cover the shadowed area?

Any suggestions guys?

Many thanks in advance!


There is a simple way you could do this using a python script, however it does not truly create a cloud shadow. For more information on creating a cloud shadow see this paper by Zhu and Woodcock (2014) and the associated literature.

EDIT: There are most probably built-on methods to shift data in most GIS software;.

If you manage to replicate the result from the paper then please post an update.

In order to estimate how to shift the cloud pixels you will hqve to look at the LANDSAT metadata file for sun angles or just estimate from image.

To move your cloud shadow 2 pixels north:

import numpy as np

cloud_mask = np.random.randint(0,2,(24,24)) # create random cloud mask
cloud_mask = cloud_mask*2
shadow_mask = np.zeros(cloud_mask.shape)

x_shift = -2
y_shift = 0

x_inds = np.where(cloud_mask>0)[0] # indices  
y_inds = np.where(cloud_mask>0)[1]
x_inds_shift = x_inds + x_shift
y_inds_shift = y_inds + y_shift

x_inds_shift[np.where(x_inds_shift<0)] = 0 # shift indices

shadow_mask[x_inds_shift, y_inds] = 1

both_mask = cloud_mask+shadow_mask
both_mask[np.where(both_mask==3)] = 2 # shadows == 1, clouds == 2

Cloud Mask:

Randomly generated cloud mask

Shadow Mask:

Shadow mask created by moving cloud pixels up 2 pixels

Combination mask:

Combining the cloud and shadow mask


As mentioned by @nicholaschris, Zhu et al's paper is nice, and they have a tool associated with it. Note that the shift is a function of 1) the position of the sun (doesn't vary on one image), 2) the position (XYZ) of the cloud and 3) the elevation of the ground (2 and 3 do vary). So that a unique shift could not be enough.

To answer the question with ArcGIS, I would use the focal stat tool with a custom weighted kernel

for instance, if you create a 3 by 3 kernel with the bottom right value to 1 and the other values to 0, your output will be shifted from one pixel to the top and one pixel to the left. Here is the text file (.txt) that needs to be created). Remember that the value will be assigned at the central pixel.

3 3
0 0 0
0 0 0
0 0 1

for 3 pixels down, it would be

7 7

0 0 0 1 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0
0 0 0 0 0 0 0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.