GEE: Practice of applying spatio-temporal interpolation technology to remote sensing images (interpolation to fill in cloud voids)

 Author: CSDN@_Yakult_

This article introduces several code snippets commonly used in the Google Earth Engine (GEE) platform to deal with missing values ​​in remote sensing data. These codes can be used to linearly interpolate remote sensing images in time series to provide a more continuous and complete time series.

The first piece of code is a linear interpolation function that interpolates missing data in a collection of time-series images. This function uses the image collection operation function and image synthesis function in the GEE platform, and uses the linear interpolation method to process missing values, and finally returns an interpolated image collection. (This code can be applied and interpolated through time series data to fill image holes after cloud removal)

The second piece of code is a mask replacement function that replaces certain values ​​(such as missing values) in the original image with a new value. It uses the image manipulation functions in the GEE platform, processes the image with a mask, and finally returns the replaced image.

The third piece of code is a function to add time attributes, which will add a time band to the image for subsequent time series analysis. This function also uses the image manipulation function and metadata attribute acquisition function in the GEE platform.

The last piece of code is a function to extract quality control (QA) bits, which extracts QA bit data at a specified location from a multiband image. It uses bitwise and shift functions, and uses image manipulation functions from the GEE platform.


Table of contents

 1. Linear interpolation function

2. Mask replacement function

3. Add the function of time attribute

4. Extract quality control (QA) bit functions

5. Application Cases


 1. Linear interpolation function

When using it, directly call the image collection YourImageCollection to be interpolated. Note that a single-band image collection is required here, and you need to use the select('InterpBandName') function to filter it.

directly when calling

var nodata = -9999;
var frame = 8*4;
var bandname = 'InterpBandName';
var InterpedCollection = linearInterp(YourImageCollection, frame, nodata, bandname);

print('interped image collection:', InterpedCollection );

//线性插值填补无云像素
function linearInterp(imgcol, frame, nodata, bandname){
    frame  = frame  || 32;
    nodata = nodata || 0;

    var time   = 'system:time_start';
    imgcol = imgcol.map(addTimeBand);

    var maxDiff = ee.Filter.maxDifference(frame * (1000*60*60*24), time, null, time);
    var cond    = {leftField:time, rightField:time};

    // 待插影像之后的所有影像
    // Images after 按时间降序排列 (最近的是排序后最后一个)
    var f1 = ee.Filter.and(maxDiff, ee.Filter.lessThanOrEquals(cond));
    var c1 = ee.Join.saveAll({matchesKey:'after', ordering:time, ascending:false})
        .apply(imgcol, imgcol, f1);
    
    // 待插影像之前的所有影像
    // Images before, 按时间升序排序 (最近的是排序后最后一个)
    var f2 = ee.Filter.and(maxDiff, ee.Filter.greaterThanOrEquals(cond));
    var c2 = ee.Join.saveAll({matchesKey:'before', ordering:time, ascending:true})
        .apply(c1, imgcol, f2);
    
    var interpolated = ee.ImageCollection(c2.map(function(img) {
        img = ee.Image(img);
        var before = ee.ImageCollection.fromImages(ee.List(img.get('before'))).mosaic();
        var after  = ee.ImageCollection.fromImages(ee.List(img.get('after'))).mosaic();
        img = img.set('before', null).set('after', null);
        //替换空值,确认线性Interp有结果
        before = replace_mask(before, after, nodata);
        after  = replace_mask(after , before, nodata);
        //计算图像的时间之间的比率
        var x1 = before.select('time').double();
        var x2 = after.select('time').double();
        var now = ee.Image.constant(img.date().millis()).double();
        //待插影像时间减去前面的合成时间,除以后面的合成影像时间和前面的影像时间的差
        var ratio = now.subtract(x1).divide(x2.subtract(x1));  //x1 = x2时,为零
        //计算插值图像
        before = before.select(0); //移除时间波段
        after  = after.select(0);
        img    = img.select(0); 
        var interp = after.subtract(before).multiply(ratio).add(before).toFloat();
        var qc = img.mask().not().rename('qc');
        interp = replace_mask(img, interp, nodata).rename(bandname);
        //return interp.addBands(qc).copyProperties(img, img.propertyNames());
        return interp.copyProperties(img, img.propertyNames());
    }));
    return interpolated;
}

This code realizes the linear interpolation of the image collection to generate a time-continuous image sequence, so as to further analyze and process the time series. The following is a detailed description of the code:

  1. linearInterp(imgcol, frame, nodata, bandname): This function accepts four parameters, which are:
  • imgcol: Image collection, that is, the image sequence to be interpolated.
  • frame: Time window, that is, how many days to choose for image interpolation, the default value is 32.
  • nodata: Missing value, that is, the default value of the pixel that needs to be interpolated, and the default value is 0.
  • bandname: The band name after interpolation, the default value is the original band name.
  1. addTimeBand(img): This function is used to add a time attribute, that is, add a new band named "time" to the image, and the value of this band is the start time of the image.

  2. ee.Filter.maxDifference(frame * (1000*60*60*24), time, null, time): This statement is used to generate a temporal filter for grouping image collections for interpolation. frame * (1000*60*60*24)Indicates the threshold for time difference in milliseconds.

  3. ee.Join.saveAll({matchesKey:'after', ordering:time, ascending:false}).apply(imgcol, imgcol, f1): This statement is used to sort the image collection in descending order of time, and find the nearest image after it for each image. In this statement, matchesKeyit means to store the key value of the associated image, orderingmeans the sort key, and ascendingmeans whether to sort in ascending order.

  4. ee.Join.saveAll({matchesKey:'before', ordering:time, ascending:true}).apply(c1, imgcol, f2): This statement is used to sort the image collection in ascending order of time, and find the closest image before it for each image. In this statement, matchesKey, ordering, ascendinghave the same meaning as above.

  5. interpolated: This statement is a collection of images, each of which is a new image generated by linear interpolation. Specifically, for two adjacent images beforeand after, first use replace_maskthe function to replace missing values, and calculate the time ratio between them, and then generate a new image by linear interpolation according to the time ratio interp. Finally, rename the band name of the new image to bandname, and copy the properties of the original image.

In summary, the code implements linear interpolation of image sequences and returns a series of time-continuous image sequences, which provides an important basis for subsequent time series analysis.

2. Mask replacement function

//掩模替换               
function replace_mask(img, newimg, nodata) {
    nodata   = nodata || 0;
    var mask = img.mask();
    img = img.unmask(nodata);
    img = img.where(mask.not(), newimg);
    img = img.updateMask(img.neq(nodata));
    return img;
}

This code implements the function of mask replacement. The function's input parameters include an original image img, a new image to replace the invalid data with newimg, and an optional invalid data value nodata. The output is the image after mask replacement.

  • The first line in the function nodata = nodata || 0says that if no invalid data value is passed in nodata, the default value is 0.
  • Next, the function obtains img.mask()the mask of the original image, and then converts img.unmask(nodata)the invalid data of the original image (that is, nodatapixels with a value equal to it) to NaN for subsequent processing.
  • Then, the function is called img.where(mask.not(), newimg), which replaces the false pixels in the mask with newimgthe values ​​of the corresponding pixels in the new image. This operation is called mask replacement.
  • Finally, the function is called img.updateMask(img.neq(nodata)), which nodatareassigns the pixels in the original image whose values ​​are not equal to the mask, that is, the valid data area in the original image.

The final function returns the image after mask replacement and updated mask.

3. Add the function of time attribute

//添加时间属性
function addTimeBand(img) {
    /** 确保掩模一致 */
    var mask = img.mask();
    var time = img.metadata('system:time_start').rename("time").mask(mask);
    return img.addBands(time);
}

This code implements the function of adding time attributes to images. The input parameter of this function is an image img, and the output is the image after adding the time attribute.

  • The first step in the function is to obtain the mask of the image to ensure that the mask of the added time attribute is consistent with the original image. Specifically, the function img.mask()obtains the mask of the original image (mask).
  • Next, the function works by img.metadata('system:time_start')getting the start time of the original image, which is the time attribute of that image. The acquired temporal attributes are renamed to time, and are then .mask(mask)masked by aligning them with those of the original image. This ensures that the mask of the temporal attribute is consistent with the mask of the original image.
  • Finally, the function img.addBands(time)obtains a new image with temporal attributes by adding them as 1D bands to the original image.

This function is usually used when processing remote sensing images. Since remote sensing images generally contain time attributes, adding time attributes to remote sensing images can better perform time series analysis, such as classifying images and monitoring changes through time attributes.

4. Extract quality control (QA) bit functions

//返回提取的QA位的单波段图像
var getQABits = function(image, start, end) {
    var pattern = 0;
    for (var i = start; i <= end; i++) {
      pattern += 1 << i;
    }
    return image.bitwiseAnd(pattern).rightShift(start);
};

This code implements the function of extracting single-band images with QA (Quality Assurance) bits from multi-band images. The input parameters of this function include a multi-band image image, a start position representing the QA bit start, and a stop position representing the QA bit end. The output is a single-band image of the extracted QA bits.

The core operation in the function is to extract the QA bits through bit operations.

  • First, the function defines a variable patternand initializes it to 0. The function then shifts the 1 in the binary representation of each bit to the left by the corresponding number of bits by looping through all the bits from to , and finally adds them together to obtain a binary pattern representing the QA bit start. endSpecifically, this process is to shift a binary "1" to the left by a number of bits (the number of bits is idetermined by the number), and then patternadd it to the variable.
  • Next, the function obtains a new multiband image by image.bitwiseAnd(pattern)applying the binary mode to the input multiband image , in which only the pixel values ​​at the QA bits are preserved.image
  • Finally, the function obtains a single-band image by .rightShift(start)shifting the extracted QA bit to the right , which is the single-band image of the extracted QA bit.start

This function is usually used in remote sensing image processing, such as processing the QA information of Landsat images to determine which pixels are useful (such as clouds, shadows, water, etc.) and exclude useless pixels.

5. Application Cases

1. "GEE: Linear interpolation method to fill the cloud gap - taking Landsat and NDVI as examples"

2. "GEE: Linear interpolation method to fill the cloud gap - taking MCD43A4 and NDVI time series as an example" 

Guess you like

Origin blog.csdn.net/qq_35591253/article/details/130081978