百里屠苏top  

本期导读

介绍如何使用GEE中的数据集和功能来绘制大规模的农业地图。示例:绘制美国中西部作物类型,美国中西部是世界上主要的产粮区之一。也可绘制其他农业特征的能力,如产量和管理实践。

主要内容

  • 使用耕地数据层(CDL)作为标签对美国中西部某县的作物类型进行分类。
  • 利用ee.Reducer.linearRegression对作物时间序列拟合二阶调和回归,提取调和系数。
  • 利用叶绿素植被指数(GCVI)进行作物类型分类。
  • 训练随机森林根据调和系数对作物类型进行分类。
  • 将训练好的随机森林分类器应用于研究区域并评估其性能。

section1 :调出研究区所有的Landsat数据

section2 :给Landsat影像 Add Bands 为谐波分析(Harmonic Regression)做准备

谐波分析(Harmonic Regression)是常用的云缺失填补方法, 它是一种频域时序列分析,从原始时间序列数据的正弦和余弦函数重构周期/季节性波。对遥感特征指数使用谐波分析,有利于反映特征的周期性。

section3 :对每一个像素拟合谐波回归

section4 :训练和评估一个随机森林分类器

 

//========================section 1=====================================================
// 定义研究区域。
var TIGER = ee.FeatureCollection('TIGER/2018/Counties'); 
var region = ee.Feature(TIGER 
    .filter(ee.Filter.eq('STATEFP', '17')) 
    .filter(ee.Filter.eq('NAME', 'McLean')) 
    .first()); 
var geometry = region.geometry(); 

Map.centerObject(region); 
Map.addLayer(region, { 
    'color': 'red' 
}, 'McLean County'); 

// 导入陆地卫星图像。 
var landsat7 = ee.ImageCollection('LANDSAT/LE07/C02/T1_L2'); 
var landsat8 = ee.ImageCollection('LANDSAT/LC08/C02/T1_L2'); 

//定义了一些函数,使处理陆地卫星数据变得更容易
// 波段重命名(这里是对所有波段,也可先筛选波段再重命名)
function renameL7(img) { 
    return img.rename(['BLUE', 'GREEN', 'RED', 'NIR', 'SWIR1', 
        'SWIR2', 'TEMP1', 'ATMOS_OPACITY', 'QA_CLOUD', 
        'ATRAN', 'CDIST', 'DRAD', 'EMIS', 'EMSD', 'QA', 'TRAD', 'URAD', 
        'QA_PIXEL', 'QA_RADSAT' 
    ]); 
}

function renameL8(img) { 
    return img.rename(['AEROS', 'BLUE', 'GREEN', 'RED', 'NIR', 
        'SWIR1', 'SWIR2', 'TEMP1', 'QA_AEROSOL', 'ATRAN', 'CDIST', 
        'DRAD', 'EMIS', 'EMSD', 'QA', 'TRAD', 'URAD', 'QA_PIXEL', 'QA_RADSAT' 
    ]); 
} 

// 云掩膜、阴影和其他不需要的特征的函数。 
function addMask(img) { 
    // Bit 0: Fill 
    // Bit 1: Dilated Cloud 
    // Bit 2: Cirrus (high confidence) (L8) or unused (L7) 
    // Bit 3: Cloud 
    // Bit 4: Cloud Shadow 
    // Bit 5: Snow 
    // Bit 6: Clear 
    //        0: Cloud or Dilated Cloud bits are set 
    //        1: Cloud and Dilated Cloud bits are not set 
    // Bit 7: Water 
    var clear = img.select('QA_PIXEL').bitwiseAnd(64).neq(0); 
    clear = clear.updateMask(clear).rename(['pxqa_clear']); 
    
    var water = img.select('QA_PIXEL').bitwiseAnd(128).neq(0); 
    water = water.updateMask(water).rename(['pxqa_water']);
    
    var cloud_shadow = img.select('QA_PIXEL').bitwiseAnd(16).neq(0); 
    cloud_shadow = cloud_shadow.updateMask(cloud_shadow).rename([ 'pxqa_cloudshadow' ]); 
    
    var snow = img.select('QA_PIXEL').bitwiseAnd(32).neq(0); 
    snow = snow.updateMask(snow).rename(['pxqa_snow']); 
    
    var masks = ee.Image.cat([ clear, water, cloud_shadow, snow ]); 
    
    return img.addBands(masks); 
} 

function maskQAClear(img) { 
    return img.updateMask(img.select('pxqa_clear')); 
} 

// Function to add GCVI as a band. 
function addVIs(img){ 
    var gcvi = img.expression('(nir / green) - 1', { 
        nir: img.select('NIR'), 
        green: img.select('GREEN') 
    }).select([0], ['GCVI']); 
    
    return ee.Image.cat([img, gcvi]); 
} 

// 定义时间。
var start_date = '2020-01-01'; 
var end_date = '2020-12-31'; 
// 在研究区域的开始日期和结束日期之间调取陆地卫星7号和8号的图像。 
var landsat7coll = landsat7 
    .filterBounds(geometry) 
    .filterDate(start_date, end_date) 
    .map(renameL7); 
    
var landsat8coll = landsat8 
    .filterDate(start_date, end_date) 
    .filterBounds(geometry) 
    .map(renameL8); 
 

// 合并Landsat 7和8收集。
var landsat = landsat7coll.merge(landsat8coll) .sort('system:time_start'); 

// Mask out non-clear pixels, add VIs and time variables. 
landsat = landsat.map(addMask) 
    .map(maskQAClear) 
    .map(addVIs); 
    
   
// 可视化一个点位的 时间序列GCVI  
var point = ee.Geometry.Point([-88.81417685576481, 40.579804398254005 ]); 
var landsatChart = 
ui.Chart.image.series(landsat.select('GCVI'), point) 
    .setChartType('ScatterChart') 
    .setOptions({ 
        title: 'Landsat GCVI time series', 
        lineWidth: 1, 
        pointSize: 3, 
    }); 
print(landsatChart); 

// Get crop type dataset. 
var cdl = ee.Image('USDA/NASS/CDL/2020').select(['cropland']); 
Map.addLayer(cdl.clip(geometry), {}, 'CDL 2020'); 

//========================section 2  =====================================================
// 定义函数:为图像添加时间波段. 
function addTimeUnit(image, refdate) { 
    var date = image.date(); 
    
    var dyear = date.difference(refdate, 'year'); 
    var t = image.select(0).multiply(0).add(dyear).select([0], ['t']) .float();
    
    var imageplus = image.addBands(t); 
    return imageplus; 
} 


// 定义函数addHarmonics: 为图像添加谐波分析参数omega
function addHarmonics(image, omega, refdate) { 
    image = addTimeUnit(image, refdate); 
    var timeRadians = image.select('t').multiply(2 * Math.PI * omega); 
    var timeRadians2 = image.select('t').multiply(4 * Math.PI * omega); 
    
    return image 
        .addBands(timeRadians.cos().rename('cos')) 
        .addBands(timeRadians.sin().rename('sin')) 
        .addBands(timeRadians2.cos().rename('cos2')) 
        .addBands(timeRadians2.sin().rename('sin2')) 
        .addBands(timeRadians.divide(timeRadians) 
            .rename('constant')); 
} 

// 对影像应用addHarmonics函数
var omega = 1; 
var landsatPlus = landsat.map( 
    function(image) { 
        return addHarmonics(image, omega, start_date); 
    }); 
print('Landsat collection with harmonic basis: ', landsatPlus); 


//========================section 3  对每一个像素拟合谐波回归=====================================================
//In the previous section, we added the harmonic basis (cosine, sine, and constant 
//terms) to each image in our Landsat collection. 
//前面部分,我们给每一幅影像添加了谐波回归参数(sin,cos,和常数项)
//现在,我们可以用这个基作为自变量进行线性回归,Landsat波段和GCVI作为因变量。
//继续定义几个函数,我们完成这个回归。

//定义函数arrayimgHarmonicRegr,对图像运行线性回归
function arrayimgHarmonicRegr(harmonicColl, dependent, independents) { 
    independents = ee.List(independents); 
    dependent = ee.String(dependent); 
    
    var regression = harmonicColl .select(independents.add(dependent)) 
        .reduce(ee.Reducer.linearRegression(independents.length(), 1));
        
    return regression; 
} 


//定义函数imageHarmonicRegr,提取和重命名回归系数.
function imageHarmonicRegr(harmonicColl, dependent, independents) { 
    var hregr = arrayimgHarmonicRegr(harmonicColl, dependent, independents); 
    
    independents = ee.List(independents); 
    dependent = ee.String(dependent); 
    
    var newNames = independents.map(function(b) { 
        return dependent.cat(ee.String('_')).cat(ee.String( b)); 
    }); 
    
    var imgCoeffs = hregr.select('coefficients') 
        .arrayProject([0]) 
        .arrayFlatten([independents]) 
        .select(independents, newNames); 
         
    return imgCoeffs; 
} 


//定义函数getHarmonicCoeffs,应用imageHarmonicRegr并创建一个多波段图像。
function getHarmonicCoeffs(harmonicColl, bands, independents) { 
    var coefficients = ee.ImageCollection.fromImages(bands.map( 
        function(band) { 
            return imageHarmonicRegr(harmonicColl, band, independents); 
        })); 
        
    return coefficients.toBands(); 
}

//调用函数getHarmonicCoeffs.
var bands = ['NIR', 'SWIR1', 'SWIR2', 'GCVI']; 
var independents = ee.List(['constant', 'cos', 'sin', 'cos2', 'sin2']); 
var harmonics = getHarmonicCoeffs(landsatPlus, bands, independents); 

harmonics = harmonics.clip(geometry); 
harmonics = harmonics.multiply(10000).toInt32(); 

//计算拟合值。
var gcviHarmonicCoefficients = harmonics 
    .select([ 
         '3_GCVI_constant', '3_GCVI_cos', 
         '3_GCVI_sin', '3_GCVI_cos2', '3_GCVI_sin2' 
    ]) 
    .divide(10000); 
    
var fittedHarmonic = landsatPlus.map(function(image) { 
    return image.addBands( 
        image.select(independents) 
        .multiply(gcviHarmonicCoefficients) 
        .reduce('sum') 
        .rename('fitted') 
    ); 
});

//在图表中可视化拟合的谐波。
var harmonicsChart = ui.Chart.image.series( fittedHarmonic.select( 
    ['fitted', 'GCVI']), point, ee.Reducer.mean(), 30) 
    .setSeriesNames(['GCVI', 'Fitted']) 
    .setOptions({ 
        title: 'Landsat GCVI time series and fitted harmonic regression values', 
        lineWidth: 1, 
        pointSize: 3, 
    }); 
    
print(harmonicsChart); 

//将CDL作为band添加到谐波中。
var harmonicsPlus = ee.Image.cat([harmonics, cdl]);


// Export image to asset. 
var filename = 'McLean_County_harmonics'; 
Export.image.toAsset({ 
    image: harmonicsPlus, 
    description: filename, 
    assetId: 'your_asset_path_here/' + filename, 
    dimensions: null, 
    region: region, 
    scale: 30, 
    maxPixels: 1e12 
}); 


//在地图上显示谐波系数。
var visImage = ee.Image.cat([ 
    harmonics.select('3_GCVI_cos').divide(7000).add(0.6), 
    harmonics.select('3_GCVI_sin').divide(7000).add(0.5), 
    harmonics.select('3_GCVI_constant').divide(7000).subtract( 0.6) 
]); 


Map.addLayer(visImage, { 
    min: -0.5, 
    max: 0.5 
}, 'Harmonic coefficient false color');



//========================section 4  训练和评估一个随机森林分类器=====================================================
// Define a random forest classifier. 
var rf = ee.Classifier.smileRandomForest({ 
    numberOfTrees: 50, 
    minLeafPopulation: 10, 
    seed: 0 
}); 


// Get harmonic coefficient band names. 
var bands = harmonicsPlus.bandNames(); 
bands = bands.remove('cropland').remove('system:index'); 

// Transform CDL into a 3-class band and add to harmonics. 
var cornSoyOther = harmonicsPlus.select('cropland').eq(1) 
    .add(harmonicsPlus.select('cropland').eq(5).multiply(2)); 
    
var dataset = ee.Image.cat([harmonicsPlus.select(bands), cornSoyOther]); 

// Sample training points. 
var train_points = dataset.sample(geometry, 30, null, null, 100, 0); 
print('Training points', train_points);

// Train the model! 
var model = rf.train(train_points, 'cropland', bands); 
var trainCM = model.confusionMatrix(); 
print('Training error matrix: ', trainCM); 
print('Training overall accuracy: ', trainCM.accuracy()); 

// Sample test points and apply the model to them. 
var test_points = dataset.sample(geometry, 30, null, null, 50, 1); 
var tested = test_points.classify(model); 

// Compute the confusion matrix and accuracy on the test set. 
var testAccuracy = tested.errorMatrix('cropland', 'classification'); 
print('Test error matrix: ', testAccuracy); 
print('Test overall accuracy: ', testAccuracy.accuracy()); 


// Apply the model to the entire study region. 
var regionClassified = harmonicsPlus.select(bands).classify(model); 
var predPalette = ['gray', 'yellow', 'green']; 

Map.addLayer(regionClassified, { 
    min: 0, 
    max: 2, 
    palette: predPalette 
}, 'Classifier prediction'); 

// Visualize agreements/disagreements between prediction and CDL. 
Map.addLayer(regionClassified.eq(cornSoyOther), { 
    min: 0, 
    max: 1 
}, 'Classifier agreement'); 

  

 

 

 

posted on 2024-06-26 12:53  百里屠苏top  阅读(14)  评论(0编辑  收藏  举报