1 起因
凡事都有个起因,为什么要做这件事,首先是看了GeoTalks公众号(非广告,本篇博文也会投稿此家,不知道会不会发出来),有一篇是基于GEE的自动阈值分割影像来提取水体,大津法自动阈值,文中简略介绍了实现方法,我发现也不是很难,就百度了一下,网上C++版本多得很(大多基于Opencv),所以我基本上是对C++版本的一个IDL翻译,并且主要是结合了遥感影像进行优化了下。
2 探索过程
主要是两方面实现与优化。算法主要看了这篇博文:
http://blog.csdn.net/guoyk1990/article/details/7606032
介绍得很详细,还有C++(opencv)版本,这里截取博文的部分:
实现无非是计算直方图,在计算类间差即可,而直方图计算在IDL中就有直接的函数可以调用,方便了不少(自己实现也不难),还有一个就是网上的大多都是处理图片的,所谓图片与遥感影像差别这里不多说,就说一点,就是图片是8比特,数值是0-255,而遥感影像就行影像分割,那么大多数要用到各种指数,比如NDVI,NDWI等等,都是浮点型数据,且值得范围是-1到1。这也不怪他们,毕竟他们是处理图片,而不是遥感数据。
核心代码如下:
除非代码外,还开发了一个ENVI的小工具来计算这个阈值,这样更大众化一些,即使不会IDL的也会使用这个工具来求阈值:
以下来以MODIS L1B数据提取水体进行演示:
MODIS真彩图,从图中可以看出,MODIS这么多年来,仪器老化严重,尤其是Terra。
计算MNDWI:
(R_0.55-R_1.6)/(R_0.55+R_1.6)
R代表反射率,最好是地表反射率,当然表观反射率也是可以的
MNDWI是增强型水体指数,可以用来表征水体,值越大,越可能是水。
从图中红框中可以看出,水体与陆地肯定可以被一个值分开,但是这个值具体是多少不知道,一般情况下,可以使用ENVI的ROI进行确定(ENVI下是可以动态确定的),这个是试探法,有很大的主观性,现在用我的这个小工具就可以直接确定出阈值:
图(6)确定的阈值
有了这个阈值怎么把水体提取出来呢?两种方法:使用ROI工具,使用Bandmath工具,由于之前的一篇博文就是使用ROI提取(传送门:
https://www.ixxin.cn/2016/11/29/mndwiwater/),那今天就用Bandmath进行提取,ENVI下使用Bandmath工具:
依据上面的阈值输入公式:(b1 lt 0.205229)*0+(b1 ge 0.205229)*b1
其中b1就是MNDWI,提取结果:
是不是很难看,我们把0值忽略:
水体是不是提取出来了呢?
针对IDL开发者,我的函数是可以直接调用的:
直接导入我的sav文件或者编译源代码就可以调用了,函数很简单:
OTSU_IDL_PRO,data,t = t
Data是输入的数据,t是得出的阈值,有了这个函数是不是可以进行批量提取水体了呢?
还有此段小代码禁止用于商业用途哦
!
3 最后/下载
还是上传到CSDN,包括源码,编译好的ENVI工具。设置门槛是5积分下载,对于需要的人,这根本不是门槛,
当然此段代码不能用于商业用途哦
!下载地址:http://download.csdn.net/download/wudixinxin/10171508
作者:山东科技大学 XXIN
联系方式:s_xxin@qq.com
个人博客:https://www.ixxin.cn
转载请注明出处:https://www.ixxin.cn/2017/12/24/otsu_idl/