Algorithm 有没有办法在谷歌地球引擎中使用像STARFM这样的融合算法?

Algorithm 有没有办法在谷歌地球引擎中使用像STARFM这样的融合算法?,algorithm,resolution,google-earth-engine,satellite-image,landsat,Algorithm,Resolution,Google Earth Engine,Satellite Image,Landsat,陆地卫星和MODIS产品都有各自的优势。具有高空间分辨率的陆地卫星和具有高时间分辨率的MODIS。我读过很多关于下载文件并在本地使用诸如Python中的STARFM之类的算法进行融合的文章。有没有办法在Google Earth引擎中直接融合这两个集合以节省计算时间?GitHub中有Google Earth引擎代码。链接如下: /**** Start of imports. If edited, may not auto-convert in the playground. ****/ var l

陆地卫星和MODIS产品都有各自的优势。具有高空间分辨率的陆地卫星和具有高时间分辨率的MODIS。我读过很多关于下载文件并在本地使用诸如Python中的STARFM之类的算法进行融合的文章。有没有办法在Google Earth引擎中直接融合这两个集合以节省计算时间?

GitHub中有Google Earth引擎代码。链接如下:

/**** Start of imports. If edited, may not auto-convert in the playground. ****/
var l8 = ee.ImageCollection("LANDSAT/LC08/C01/T1_SR"),
    modis = ee.ImageCollection("MODIS/006/MOD09GQ"),
    geometry4 = /* color: #d63000 */ee.Geometry.Polygon(
        [[[-116.004638671875, 42.809506838324204],
          [-115.59539794921875, 42.78129125156276],
          [-115.499267578125, 43.004647127794435],
          [-115.499267578125, 43.28920196020127],
          [-116.00189208984375, 43.35114690203121],
          [-116.19415283203125, 43.07691312608711]]]),
    geometry = /* color: #98ff00 */ee.Geometry.Polygon(
        [[[-115.93391418457031, 43.09346209534859],
          [-115.80276489257812, 43.095718426590174],
          [-115.80276489257812, 43.161366298103566],
          [-115.9332275390625, 43.16086543618915]]]);
/***** End of imports. If edited, may not auto-convert in the playground. *****/
// based on script by Faye Peters, University of Louisville
// modified by Megan Gallagher, Boise State University
// for code inquiries, or adjustments please email megangallagher@u.boisestate.edu
// code exists for: 
//    landsat 5,7, and 8 NDVI merging with MODIS Terra daily
//    MODIS Terra and Sentinel-2
//    Landsat pre tier and modis daily terra - works with base R code
//    Landsat 8 and Sentinel-2
////////////////////////////////////////Variables//////////////////////////////////////////////
// import Landsat 8 and MODIS daily terra surface reflectance 250m
var region = geometry; //region you want to export 
var bounds = geometry4 //outer bounds of image to catch boundary effect, make larger than region
var date_begin = '2016-03-02' //start date of data collection, must be a landsat image date
var date_end ='2016-10-13' // end date of data collection, must be the day AFTER last landsat image

var csv_title = '2016_Dates_BOP' //title of csv output
var ls_title = '2016_landsat'   // title of landsat tif file
var mod_title = '2016_mod'      // title of modis tif file

/////////////////////////////////////////Code////////////////////////////////////////////////////////////////////////

var starfm = function(modis, l8){

//Preliminary filtering of MODIS and Landsat
var filt_mod = modis.filterDate(date_begin, date_end);
var filt_l8 = l8.filterDate(date_begin, date_end)
              .filterBounds(bounds);

//add bounds to subset area
var subset_bounds = bounds.transform('EPSG:4326', 30).bounds().getInfo();


// get rid of bad pixels but keep metadata date information
var removeBadObservations = function(image){
    var valid_data_mask = ee.Image(image).select('pixel_qa').bitwiseAnd(2).neq(0);
var numberBandsHaveData =
  image.mask().reduce(ee.Reducer.sum());
var allOrNoBandsHaveData =
 numberBandsHaveData.eq(0).or(numberBandsHaveData.gte(9));
 var allBandsHaveData = allOrNoBandsHaveData;

 //Make sure no band is just under zero
 var allBandsGT = image.reduce(ee.Reducer.min()).gt(-0.001);
 var result = ee.Image(image).mask(image.mask().and(valid_data_mask).and(allBandsHaveData).and(allBandsGT));
 return result.copyProperties(ee.Image(image),['system:time_start']);
};
//NDVI functions for Landsat and MODIS
var getNDVI_mod = function(image){
return image
    .addBands(image.normalizedDifference(['sur_refl_b02','sur_refl_b01']).multiply(10000).rename('NDVI'));}; 

var getNDVI_l8= function(image){
var ndvi = ee.Image(image).normalizedDifference(['B5','B4']);
return ndvi.copyProperties(ee.Image(image),['system:time_start']);
};


var filt2_l8= filt_l8.filterBounds(subset_bounds).aside(print).map(removeBadObservations).map(getNDVI_l8);
// update mask for different areas
var subset_mask = ee.Image().byte().paint(geometry4, "id").add(1);

var filtered_modis = filt_mod.filterBounds(subset_bounds).aside(print).map(getNDVI_mod);

// Pull out the date:
var extract_modis_date = function(row) {
var d = ee.Date(row.get('system:time_start'));
var d2 = ee.Date.fromYMD(d.get('year'), d.get('month'), d.get('day'));
var result = ee.Feature(null, {'date': d2});
result = result.set({'date': d2});
return result;
};

var getQABits = function(image, start, end, newName) {
 //// Compute the bits we need to extract.
var pattern = 0;
  for (var i = start; i <= end; i++) {
 pattern += Math.pow(2, i);
 }
 //// Return a single band image of the extracted QA bits, giving the band a new name.
return image.select([0], [newName])
 .bitwiseAnd(pattern)
 .rightShift(start); };
 
print(filtered_modis);

filtered_modis = filtered_modis.map(function(image){
var quality = getQABits(image.select(2), 4, 5, 'QAMask');
quality = quality.eq(3).not();
return image.clip(subset_bounds).mask(image.mask().multiply(subset_mask).multiply(quality));
 });

filtered_modis = filtered_modis.select('NDVI'); //Take only NDVI band
 
 var modis_multiband = ee.Image(filtered_modis.filterDate(date_begin, date_end).iterate( function(x, modis_multiband) {
 return ee.Image(modis_multiband).addBands(ee.Image(x));
 }, filtered_modis.first()));

var dates_modis = filtered_modis.map(extract_modis_date);
 print(dates_modis.getInfo());
 
var filt2_l8_ndvi = filt2_l8.map(function(image) {
return ee.Image(image)
 .clip(subset_bounds)
.mask(ee.Image(image).mask().multiply(subset_mask));
 });
 
//use this to choose the range of days, and check for overlap
var day_expand = 1;

var reduceLandsatNDVI = function(MODISdate) {
 MODISdate = ee.Date(MODISdate.get('date'));
 
var ndvi_subset = ee.ImageCollection(filt2_l8_ndvi).filterDate( MODISdate,
 MODISdate.advance(day_expand, 'day') );
 
 ndvi_subset = ndvi_subset.map(function (image) {
  var diff = MODISdate.difference(ee.Date(ee.Image(image).get('system:time_start')), 'day').abs();
  return ee.Image(image).set('diff', diff);
 });
 
ndvi_subset = ndvi_subset.sort('diff');
 var ndvi_first = ndvi_subset.reduce('first');
 var ndvi_mean = ndvi_subset.reduce('mean');

return ee.Algorithms.If(
 ndvi_first.bandNames(),
 ndvi_first.eq(0).multiply(ndvi_mean).add(ndvi_first),
 ee.Image(0)
 );
 };
 
 var extract_landsat_date = function(MODISdate) {
 MODISdate = ee.Date(MODISdate.get('date'));
 
var ndvi_subset =
 ee.ImageCollection(filt2_l8_ndvi).filterDate( MODISdate,
 MODISdate.advance(day_expand, 'day') );

ndvi_subset = ndvi_subset.map(function (image) {
 var diff = MODISdate.difference(ee.Date(ee.Image(image).get('system:time_start')), 'day').abs();
return ee.Image(image).set('diff', diff);
 });

 ndvi_subset = ndvi_subset.sort('diff');
 var d = ndvi_subset.aggregate_first('system:time_start');
 var count = ndvi_subset.aggregate_count('system:time_start');
 
 d = ee.Algorithms.If(
 ee.Number(count).gt(0),
 ee.Date(d),
 ee.Date('1971-01-01')
 );
 d = ee.Date(d);

 var d2 = ee.Date.fromYMD(d.get('year'), d.get('month'),
 d.get('day'));

 var result = ee.Feature(null, {'LSdate': d2, 'MODISdate':
 MODISdate, 'CountLSScenes': count});
 result = result.set({'LSdate': d2, 'MODISdate': MODISdate,
 'CountLSScenes': count});
 return result;
 };

var ls_collection = dates_modis.map(reduceLandsatNDVI);
print(ls_collection,'ls collection');


var dates_landsat = dates_modis.map(extract_landsat_date);


Export.table(dates_landsat, csv_title);

var ls_multiband = ls_collection.iterate( function(x,
 ls_multiband) 
{ return ee.Image(ls_multiband).addBands(ee.Image(x));
}, ls_collection.first());

ls_multiband = ee.Image(ls_multiband).multiply(10000).int16(); 
ls_multiband = ls_multiband.mask(ls_multiband.mask().multiply(ls_multiband.neq(0))); 


//remove repeated first layer
var ls_multiband2=ee.Image(ls_multiband.slice(1))
var modis_multiband2=ee.Image(modis_multiband.slice(1))


Export.image.toDrive({
  image: modis_multiband2,
  description: mod_title,
  crs:'EPSG:4326 ',
 region:region,
 scale:30
});


Export.image.toDrive({
  image: ls_multiband2, 
  description: ls_title, 
  crs:'EPSG:4326',
  region:region,
  scale:30
});

return 'Done!'
}

var running = starfm(modis,l8)
print(running)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////

我复制的代码如下:

/**** Start of imports. If edited, may not auto-convert in the playground. ****/
var l8 = ee.ImageCollection("LANDSAT/LC08/C01/T1_SR"),
    modis = ee.ImageCollection("MODIS/006/MOD09GQ"),
    geometry4 = /* color: #d63000 */ee.Geometry.Polygon(
        [[[-116.004638671875, 42.809506838324204],
          [-115.59539794921875, 42.78129125156276],
          [-115.499267578125, 43.004647127794435],
          [-115.499267578125, 43.28920196020127],
          [-116.00189208984375, 43.35114690203121],
          [-116.19415283203125, 43.07691312608711]]]),
    geometry = /* color: #98ff00 */ee.Geometry.Polygon(
        [[[-115.93391418457031, 43.09346209534859],
          [-115.80276489257812, 43.095718426590174],
          [-115.80276489257812, 43.161366298103566],
          [-115.9332275390625, 43.16086543618915]]]);
/***** End of imports. If edited, may not auto-convert in the playground. *****/
// based on script by Faye Peters, University of Louisville
// modified by Megan Gallagher, Boise State University
// for code inquiries, or adjustments please email megangallagher@u.boisestate.edu
// code exists for: 
//    landsat 5,7, and 8 NDVI merging with MODIS Terra daily
//    MODIS Terra and Sentinel-2
//    Landsat pre tier and modis daily terra - works with base R code
//    Landsat 8 and Sentinel-2
////////////////////////////////////////Variables//////////////////////////////////////////////
// import Landsat 8 and MODIS daily terra surface reflectance 250m
var region = geometry; //region you want to export 
var bounds = geometry4 //outer bounds of image to catch boundary effect, make larger than region
var date_begin = '2016-03-02' //start date of data collection, must be a landsat image date
var date_end ='2016-10-13' // end date of data collection, must be the day AFTER last landsat image

var csv_title = '2016_Dates_BOP' //title of csv output
var ls_title = '2016_landsat'   // title of landsat tif file
var mod_title = '2016_mod'      // title of modis tif file

/////////////////////////////////////////Code////////////////////////////////////////////////////////////////////////

var starfm = function(modis, l8){

//Preliminary filtering of MODIS and Landsat
var filt_mod = modis.filterDate(date_begin, date_end);
var filt_l8 = l8.filterDate(date_begin, date_end)
              .filterBounds(bounds);

//add bounds to subset area
var subset_bounds = bounds.transform('EPSG:4326', 30).bounds().getInfo();


// get rid of bad pixels but keep metadata date information
var removeBadObservations = function(image){
    var valid_data_mask = ee.Image(image).select('pixel_qa').bitwiseAnd(2).neq(0);
var numberBandsHaveData =
  image.mask().reduce(ee.Reducer.sum());
var allOrNoBandsHaveData =
 numberBandsHaveData.eq(0).or(numberBandsHaveData.gte(9));
 var allBandsHaveData = allOrNoBandsHaveData;

 //Make sure no band is just under zero
 var allBandsGT = image.reduce(ee.Reducer.min()).gt(-0.001);
 var result = ee.Image(image).mask(image.mask().and(valid_data_mask).and(allBandsHaveData).and(allBandsGT));
 return result.copyProperties(ee.Image(image),['system:time_start']);
};
//NDVI functions for Landsat and MODIS
var getNDVI_mod = function(image){
return image
    .addBands(image.normalizedDifference(['sur_refl_b02','sur_refl_b01']).multiply(10000).rename('NDVI'));}; 

var getNDVI_l8= function(image){
var ndvi = ee.Image(image).normalizedDifference(['B5','B4']);
return ndvi.copyProperties(ee.Image(image),['system:time_start']);
};


var filt2_l8= filt_l8.filterBounds(subset_bounds).aside(print).map(removeBadObservations).map(getNDVI_l8);
// update mask for different areas
var subset_mask = ee.Image().byte().paint(geometry4, "id").add(1);

var filtered_modis = filt_mod.filterBounds(subset_bounds).aside(print).map(getNDVI_mod);

// Pull out the date:
var extract_modis_date = function(row) {
var d = ee.Date(row.get('system:time_start'));
var d2 = ee.Date.fromYMD(d.get('year'), d.get('month'), d.get('day'));
var result = ee.Feature(null, {'date': d2});
result = result.set({'date': d2});
return result;
};

var getQABits = function(image, start, end, newName) {
 //// Compute the bits we need to extract.
var pattern = 0;
  for (var i = start; i <= end; i++) {
 pattern += Math.pow(2, i);
 }
 //// Return a single band image of the extracted QA bits, giving the band a new name.
return image.select([0], [newName])
 .bitwiseAnd(pattern)
 .rightShift(start); };
 
print(filtered_modis);

filtered_modis = filtered_modis.map(function(image){
var quality = getQABits(image.select(2), 4, 5, 'QAMask');
quality = quality.eq(3).not();
return image.clip(subset_bounds).mask(image.mask().multiply(subset_mask).multiply(quality));
 });

filtered_modis = filtered_modis.select('NDVI'); //Take only NDVI band
 
 var modis_multiband = ee.Image(filtered_modis.filterDate(date_begin, date_end).iterate( function(x, modis_multiband) {
 return ee.Image(modis_multiband).addBands(ee.Image(x));
 }, filtered_modis.first()));

var dates_modis = filtered_modis.map(extract_modis_date);
 print(dates_modis.getInfo());
 
var filt2_l8_ndvi = filt2_l8.map(function(image) {
return ee.Image(image)
 .clip(subset_bounds)
.mask(ee.Image(image).mask().multiply(subset_mask));
 });
 
//use this to choose the range of days, and check for overlap
var day_expand = 1;

var reduceLandsatNDVI = function(MODISdate) {
 MODISdate = ee.Date(MODISdate.get('date'));
 
var ndvi_subset = ee.ImageCollection(filt2_l8_ndvi).filterDate( MODISdate,
 MODISdate.advance(day_expand, 'day') );
 
 ndvi_subset = ndvi_subset.map(function (image) {
  var diff = MODISdate.difference(ee.Date(ee.Image(image).get('system:time_start')), 'day').abs();
  return ee.Image(image).set('diff', diff);
 });
 
ndvi_subset = ndvi_subset.sort('diff');
 var ndvi_first = ndvi_subset.reduce('first');
 var ndvi_mean = ndvi_subset.reduce('mean');

return ee.Algorithms.If(
 ndvi_first.bandNames(),
 ndvi_first.eq(0).multiply(ndvi_mean).add(ndvi_first),
 ee.Image(0)
 );
 };
 
 var extract_landsat_date = function(MODISdate) {
 MODISdate = ee.Date(MODISdate.get('date'));
 
var ndvi_subset =
 ee.ImageCollection(filt2_l8_ndvi).filterDate( MODISdate,
 MODISdate.advance(day_expand, 'day') );

ndvi_subset = ndvi_subset.map(function (image) {
 var diff = MODISdate.difference(ee.Date(ee.Image(image).get('system:time_start')), 'day').abs();
return ee.Image(image).set('diff', diff);
 });

 ndvi_subset = ndvi_subset.sort('diff');
 var d = ndvi_subset.aggregate_first('system:time_start');
 var count = ndvi_subset.aggregate_count('system:time_start');
 
 d = ee.Algorithms.If(
 ee.Number(count).gt(0),
 ee.Date(d),
 ee.Date('1971-01-01')
 );
 d = ee.Date(d);

 var d2 = ee.Date.fromYMD(d.get('year'), d.get('month'),
 d.get('day'));

 var result = ee.Feature(null, {'LSdate': d2, 'MODISdate':
 MODISdate, 'CountLSScenes': count});
 result = result.set({'LSdate': d2, 'MODISdate': MODISdate,
 'CountLSScenes': count});
 return result;
 };

var ls_collection = dates_modis.map(reduceLandsatNDVI);
print(ls_collection,'ls collection');


var dates_landsat = dates_modis.map(extract_landsat_date);


Export.table(dates_landsat, csv_title);

var ls_multiband = ls_collection.iterate( function(x,
 ls_multiband) 
{ return ee.Image(ls_multiband).addBands(ee.Image(x));
}, ls_collection.first());

ls_multiband = ee.Image(ls_multiband).multiply(10000).int16(); 
ls_multiband = ls_multiband.mask(ls_multiband.mask().multiply(ls_multiband.neq(0))); 


//remove repeated first layer
var ls_multiband2=ee.Image(ls_multiband.slice(1))
var modis_multiband2=ee.Image(modis_multiband.slice(1))


Export.image.toDrive({
  image: modis_multiband2,
  description: mod_title,
  crs:'EPSG:4326 ',
 region:region,
 scale:30
});


Export.image.toDrive({
  image: ls_multiband2, 
  description: ls_title, 
  crs:'EPSG:4326',
  region:region,
  scale:30
});

return 'Done!'
}

var running = starfm(modis,l8)
print(running)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/****开始导入。如果已编辑,则可能无法在操场中自动转换****/
var l8=ee.图像采集(“陆地卫星/LC08/C01/T1_SR”),
modis=ee.ImageCollection(“modis/006/MOD09GQ”),
geometry4=/*颜色:#d63000*/ee.Geometry.Polygon(
[[[-116.004638671875, 42.809506838324204],
[-115.59539794921875, 42.78129125156276],
[-115.499267578125, 43.004647127794435],
[-115.499267578125, 43.28920196020127],
[-116.00189208984375, 43.35114690203121],
[-116.19415283203125, 43.07691312608711]]]),
几何体=/*颜色:#98ff00*/ee.geometry.Polygon(
[[[-115.93391418457031, 43.09346209534859],
[-115.80276489257812, 43.095718426590174],
[-115.80276489257812, 43.161366298103566],
[-115.9332275390625, 43.16086543618915]]]);
/*****进口结束。如果已编辑,则可能无法在操场中自动转换*****/
基于Faye Peters的脚本,路易斯威尔大学
//由博伊西州立大学Megan Gallagher修改
//有关代码查询或调整,请发送电子邮件megangallagher@u.boisestate.edu
//代码存在于:
//陆地卫星5、7和8 NDVI与MODIS Terra每日合并
//MODIS Terra和哨兵-2
//陆地卫星pre-tier和modis daily terra-使用基本R代码
//陆地卫星8号和哨兵2号
////////////////////////////////////////变数//////////////////////////////////////////////
//导入Landsat 8和MODIS每日地表反射率250m
var区域=几何体//要导出的区域
var bounds=geometry4//图像的外部边界要捕捉边界效果,请使其大于区域
var date_begin='2016-03-02'//数据收集的开始日期必须是陆地卫星图像日期
var date_end='2016-10-13'//数据收集的结束日期,必须是最后一张陆地卫星图像的第二天
var csv_title='2016_Dates_BOP'//csv输出的标题
var ls_title='2016_陆地卫星'//陆地卫星tif文件的标题
var mod_title='2016_mod'//modis tif文件的标题
/////////////////////////////////////////代码////////////////////////////////////////////////////////////////////////
var starfm=功能(modis,l8){
//MODIS和Landsat的初步滤波
var filt\u mod=modis.filterDate(开始日期、结束日期);
变量filt\u l8=l8.filterDate(开始日期、结束日期)
.filterBounds(边界);
//向子集区域添加边界
var subset_bounds=bounds.transform('EPSG:4326',30).bounds().getInfo();
//去除坏像素,但保留元数据日期信息
var removeBadObservations=函数(图像){
var valid_data_mask=ee.Image(Image)。选择('pixel_qa')。按位和(2)。neq(0);
var NumberBandData=
image.mask().reduce(ee.Reducer.sum());
var Allornoband数据=
numberBandsHaveData.eq(0)或(numberBandsHaveData.gte(9));
var allBandsHaveData=allOrNoBandsHaveData;
//确保没有波段刚好低于零
var allBandsGT=image.reduce(ee.Reducer.min()).gt(-0.001);
var result=ee.Image(Image).mask(Image.mask()和(valid_data_mask).和(allBandsHaveData).和(allBandsGT));
返回result.copyProperties(ee.Image(Image),['system:time_start']);
};
//陆地卫星和MODIS的NDVI功能
var getNDVI_mod=函数(图像){
返回图像
.addBands(image.normalizedDifference(['sur_refl_b02','sur_refl_b01'))。multiply(10000)。重命名('NDVI'));
var getNDVI_l8=函数(图像){
var ndvi=ee.Image(Image).normalizedDifference(['B5','B4']);
返回ndvi.copyProperties(ee.Image(Image),['system:time_start']);
};
var filter2_l8=filt_l8.filterBounds(子集边界).aside(print).map(removeBadObservations.map(getNDVI_l8);
//更新不同区域的遮罩
var subset_mask=ee.Image().byte().paint(geometry4,“id”).add(1);
var filtered_modis=filt_mod.filterBounds(子集边界).aside(打印).map(getNDVI_mod);
//拿出日期:
var extract_modis_date=函数(行){
var d=ee.Date(row.get('system:time\u start');
var d2=ee.Date.fromYMD(d.get('year')、d.get('month')、d.get('day');
var result=ee.Feature(null,{'date':d2});
result=result.set({'date':d2});
返回结果;
};
var getQABits=函数(图像、开始、结束、新名称){
////计算我们需要提取的位。
var模式=0;
对于(var i=开始;i