Google Earth Engine城市水体提取

大家都知道城市水体提取相比较于山区,丘陵的地区,肯定是比较难的,为什么呢,因为城市水体有很多高层建筑导致的阴影,这个就非常复杂了,而且现在很多高分影像只有可见光和近红外波段,那么我们如何准确提取城市水体呢?

Remoe Sensing2018年刊发了一篇城市水体高分影像自动提取算法(Two-Step Urban Water Index (TSUWI): A New Technique for High-Resolution Mapping of Urban SurfaceWater [J]Remote Sensing,2018),初步看来,效果还行,在高分二号上面效果不错,我再想,如果对于开源的哨兵、Landsat如何?这些是中等分辨率影像,能做到吗?

话不多说,利用GEE,直接编码,实验结果如下(以2018年10月的北京某景Sentinel2影像为例):

(a) 这是原始影像

(b) 这是城市水体指数

(c) 这是城市阴影指数

(d) 这是城市水体提取结果,蓝色为水体

其中城市水体指数和城市阴影指数计算公式如下所示:

我把最终成果发布成了APPengine(https://wang749195.users.earthengine.app/view/urbanwaterextraction),大家可以直接在web上看,总的来说,实验结果还是不错的,去掉了阴影现象,这篇文章出自中科院遥感所,在此申明,值得一读,后续我会发布C++软件版本,Matlab版本,以及Python版本。我个人的开发思路是,首先用GEE实现,如果GEE不好实现,就用matlab或者python实现第一遍,效果可以,能工程应用,立马就用GDAL+C++打包成工程源代码,我感觉这样会节省时间,且不会造成时间浪费。

接着上面讲,我们用c++来实现一遍,使用GDAL读写影像,先把这两个函数写上来:

/*栅格影像读取,返回数据指针
* imgPath:图像位置
* 返回float类型的数据指针
*/
void readImage(char *imgpath, imgData *IMG, int bandindex) { GDALDataset *img = (GDALDataset*)GDALOpen(imgpath, GA_ReadOnly);
if (img != NULL) { int imgWidth = img->GetRasterXSize(); //图像宽度,特别注意:对应matlab中的行
int imgHeight = img->GetRasterYSize(); //图像高度,特别注意:对应matlab中的列
int bandNum = img->GetRasterCount(); //波段数 IMG->imgH = imgHeight;
IMG->imgW = imgWidth; GDALRasterBand *poBand; poBand = img->GetRasterBand(bandindex); //灰度一个波段 img->GetGeoTransform(IMG->adfGeoTransform); // 变换参数 int size = imgWidth*imgHeight;
IMG->pData = new float[size]; //分配缓冲区空间 //读取
poBand->RasterIO(GF_Read, , , imgWidth, imgHeight, IMG->pData,
imgWidth, imgHeight, GDT_Float32, , ); GDALClose(img); // 释放内存
}
} /*写出栅格影像
* imgPath:输出影像位置
* adfGeoTransform:变换参数
* IMG:导出的影像数组
*/
void writeImage(char *imgPath, float *Img, int nImgSizeX, int nImgSizeY, int nBandCount, double *adfGeoTransform) {
GDALDataset *poDataset2; //待创建的GDAL数据集
GDALDriver *poDriver; //驱动,用于创建新的文件 //创建新文件
poDriver = GetGDALDriverManager()->GetDriverByName("GTiff"); //获取格式类型
char **papszMetadata = poDriver->GetMetadata(); //特别注意,数据类型要与后面的写出类型要保持一致
poDataset2 = poDriver->Create(imgPath, nImgSizeX, nImgSizeY, nBandCount, GDT_Float32, papszMetadata);
//坐标赋值
poDataset2->SetGeoTransform(adfGeoTransform); //将图像数据写入新图像中
poDataset2->RasterIO(GF_Write, , , nImgSizeX, nImgSizeY,
Img, nImgSizeX, nImgSizeY, GDT_Float32, nBandCount, , , , ); GDALClose(poDataset2);
delete poDriver;
}

然后就是我们的USI,UWI计算公式,贴上来:

// 计算UWI指数
void UWI_cal(float *rband, float *gband, float *nirband,float *UWI,int width,int length) {
int Length = width*length; for (int i = ; i < Length; i++) {
UWI[i] = (gband[i] - 1.1*rband[i] - 5.2*nirband[i] + 0.4) /
abs(gband[i] - 1.1*rband[i] - 5.2*(nirband[i]));
}
} // 计算USI指数
void USI_cal(float *rband, float *gband, float *bband, float *nirband, float *USI, int width, int length) {
int Length = width*length; for (int i = ; i < Length; i++) {
USI[i] = 0.25*gband[i] / rband[i] - 0.57*nirband[i] /
gband[i] - 0.83*bband[i] / gband[i] + 1.0; }
}

然后就是我们的影像数据结构:

/*可见光与近红外波段数据结构
*/
struct imgData {
float *pData; int imgH;
int imgW;
double adfGeoTransform[];
};

last but not least,就是我们的main函数:

int main()
{
//必须先注册一个!
GDALAllRegister();
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); char *ImgPath = "C:\\Users\\Administrator\\Desktop\\UrbanWater\\SentinelImg.tif"; // 读取蓝波段
imgData *B = new imgData;
readImage(ImgPath, B, ); // 读取绿波段
imgData *G = new imgData;
readImage(ImgPath, G, ); // 读取红波段
imgData *R = new imgData;
readImage(ImgPath, R, ); // 读取近红外波段
imgData *NIR = new imgData;
readImage(ImgPath, NIR, ); printf("读取影像成功!\n"); int width = B->imgW;
int height = B->imgH; float *USI = new float[width*height];
float *UWI = new float[width*height]; UWI_cal(R->pData, G->pData, NIR->pData, UWI, width, height);
USI_cal(R->pData, G->pData, B->pData, NIR->pData, USI, width, height); float T1 = -0.1;
float T2 = -0.2;
float *UrbanWater = new float[width*height];
UrbanWaterExtraction(T1, T2, UWI, USI, UrbanWater, width, height); char *savePath = "C:\\Users\\Administrator\\Desktop\\UrbanWater\\urbanwater.tif";
writeImage(savePath, UrbanWater, width, height, , R->adfGeoTransform);
printf("提取水体成功!\n"); // 清空内存
delete []NIR->pData;
delete []R->pData;
delete []G->pData;
delete []B->pData;
delete []UrbanWater;
delete []USI;
delete []UWI;
delete NIR, R, G, B;
system("pause"); }

还是上一张c++搞出来的城市水体图吧:

可以看到,GEE与c++效果几乎一样,但是GEE的栅格渲染,还是非常值得国产软件学习!

(打个小广告,本文兼职软件开发,qq1044625113)。

Google Earth Engine城市水体提取的更多相关文章

  1. 基于google earth engine 云计算平台的全国水体变化研究

    第一个博客密码忘记了,今天才来开通第二个博客,时间已经过去两年了,三年的硕士生涯,真的是感慨良多,最有收获的一段时光,莫过于在实验室一个人敲着代码了,研三来得到中科院深圳先进院,在这里开始了新的研究生 ...

  2. Google Earth Engine学习资源分享

    最近在学习Google Earth Engine的使用,发现这个平台确实是一个非常好用.非常强大的平台.在GEE官网上找到了一些中文的学习资料,现在搬运过来分享给大家共同学习.教程分为两个部分 教程一 ...

  3. Google earth engine 绘制图像间散点图

    这段代码实现了在Google earth engine中绘制图像/波段间的散点图,得到相关关系.适用于探究数据间的相关性,进行数据的交叉验证. 代码来源于官方帮助:https://developers ...

  4. Google Earth Engine 中的位运算

    Google Earth Engine中的位运算 按位运算是编程中一个难点,同时也是在我们后续处理影像数据,尤其要使用影像自带的波段比如QA波段经常会用到的一个东西.通过按位运算我们可以筛选出我们想要 ...

  5. Google earth engine 中的投影、重采样、尺度

    本文主要翻译自下述GEE官方帮助 https://developers.google.com/earth-engine/guides/scale https://developers.google.c ...

  6. 基于google earth engine的中等分辨率全国水质反演

    我写博客的工作不像论文,假大空,我们直接上干货,之所以取一个这么大的名字,当然是我们能做到的... 不多说,我们对全国水体进行水质参数反演,不用MODIS,太粗,我们直接用哨兵,这样就可以直接做到大型 ...

  7. 使用google earth engine根据NDWI(归一化水指数)提取水体信息

    交流合作请联系: ab000c@163.com

  8. 基于Google Earth Engine的全国地表温度反演

    国内研究landsat8温度反演的人员很多,但是现有算法一般都是一景为例子,进行开展. 这有一个局限性,当研究的尺度很大时,就需要比较大的运算量了,例如全省温度,全国温度,全球温度,当然大家可能会说, ...

  9. 节能减排到底如何----google earth engine 告诉你!!

    (First,再次严谨说明,本人成果未经允许,切勿发表到相关学术期刊,如果有技术交流,qq1044625113,顺便打个广告,兼职GEE开发,欢迎联系!) 终于过了严寒的冬天,2017年的冬天中国南方 ...

随机推荐

  1. 你不从地址栏中增加曝光量所需的数据库ID方法

    <p><span style="font-size: 18px;"></span></p> 当你想隐藏数据库id时,你能够使用 Ha ...

  2. 第一次react-native项目实践要点总结 good

    今天完成了我的第一个react-native项目的封包,当然其间各种环境各种坑,同时,成就感也是满满的.这里总结一下使用react-native的一些入门级重要点(不涉及环境).注意:阅读需要语法基础 ...

  3. Android 项目编译过程

    Android 工程构建的持续集成,需要搭建一套编译和打包自动化流程,比如建立每日构建系统.自动生成发布文件等等.这些都需要我们对Android工程的编译和打包有一个比较深入的理解,例如知道它的每一步 ...

  4. python3获取天气预报

    #!/usr/local/bin/python3 #coding=utf-8 ''' Created on 2011-2-25 @author: http://www.cnblogs.com/txw1 ...

  5. 关于 Swift 2.0 - 语言新特性与革新

    随着刚刚结束的 WWDC 2015 苹果发布了一系列更新,这其中就包括了令人振奋的 Swift 2.0. 这是对之前语言特性的一次大幅的更新,加入了很多实用和方便的元素,下面我们就一起来看看这次更新都 ...

  6. WPF- 模拟触发Touch Events

    原文:WPF- 模拟触发Touch Events 基于API: [DllImport("User32.dll")] public static extern bool Initia ...

  7. jquery QQ微博

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. dotnet core 跨平台编译发布

    vs2017 建立的项目,在项目目录 ,执行 dotnet publish -r ubuntu.15.04-x64 dotnet publish -r linux-x64 dotnet publish ...

  9. android中优雅实现recyclerview

    在慕课网上看了Abner_泥阿布老师不一样的RecyclerView优雅实现复杂列表布局这个视频课程,本人在Ubuntu16.04LTS下使用android studio2.2.3按照老师讲解写的代码 ...

  10. VS2015设置VS2017的“快速操作”快捷键Alt+Enter

    选项 -  环境 - 键盘 - 视图.快速操作和重构 添加“Alt+Enter (文本编辑器)”