在Gee上尝试实现时空融合算法ESTARFM
Google Earth Engine 是一个强大的遥感计算平台,在这个平台上无需下载数据,直接就能调取众多免费遥感数据,且有强大的计算集群支撑你的运算,能够快速得到想要的结果,简直是做遥感应用的一大利器。
但是由于Gee高度集成化,无法像传统图像处理一样用for循环遍历图像,且由于是并行运算,map、reduce的函数只能做重复的操作,这对于需要在每个像元的邻域窗口内选取相似像元的ESTARFM来说是一个挑战。
那么我们换个思路,因为选取相似像元是通过判断窗口内的像元减去中心像元的绝对值是否小于某个阈值,我们可以从影像的角度转换到波段的角度,使用gee里面的卷积操作对图像进行卷积
image.convolve(kernel)
假设我们是3*3的窗口,那么就有八个不同的核,第一个核的形式为:
[[1,0,0],
[0,-1,0],
[0,0,0]]
第二个核的形式为:
[[0,1,0],
[0,-1,0],
[0,0,0]]
以此类推,对图像进行八次卷积操作,就能得到八个波段,每个波段代表了对应着窗口内的第i个元素与中心像元的差值,这样就可以通过阈值来判断相似像元的位置,有了这个表示相似像元的imagecollection,我们就可以计算对应中心像元的相关系数r、转换系数v等等,然后计算每个相似像元的权重,最终加权的到融合影像。
但是问题来了,如何自适应的构造这些kernel呢,假如窗口大小为n*n,就需要有n*n-1个kernel,手写不现实,本来的想法是本地生成kernel,复制到浏览器上转为list,然后使用map操作,但是窗口一大,kernel大小能够达到好几兆,复制到浏览器上就崩溃了。。。然后实在想不出什么好方法了,就不得不使用for循环来构造kernel
先使用js本地方法构造一个数组
var arr = new Array(_size);
for(var i = 0;i < _size; i++){
arr[i] = new Array(_size);
//init array to 0
for(var l=0;l<_size;l++){
for(var n=0;n<_size;n++){
arr[l][n] = 0;
}
然后使用for循环去修改数组的值再做卷积
arr[parseInt(_size/2)][parseInt(_size/2)]=-1;
for (var i=0;i<_size;i++)
for(var j=0;j<_size;j++)
if(i!=parseInt(_size/2)||j!=parseInt(_size/2))
arr[i][j]=1;
var kernel = ee.Kernel.fixed(_size,_size,arr,-1 ,-1, false);
image_con = _image1.convolve(kernel).rename("L1").reproject(_image1.projection()) ;