利用GEE对季节性地物进行分类的代码实现

news2024/11/28 9:29:40

采样点的选取

如果你采用监督学习的话,那就手动打标签
或者可以了解一下非监督学习
在这里插入图片描述

合成多季节多波段影像

首先,制作一个包含多波段的影像,每个波段作为随机森林分类器的一个feature输入,提升feature的丰富度以保证分类精度。

1、对landsat5用的云掩膜函数:

// cloud mask
var cloudMaskL457 = function(image) {
  var qa = image.select('pixel_qa');
  // If the cloud bit (5) is set and the cloud confidence (7) is high
  // or the cloud shadow bit is set (3), then it's a bad pixel.
  var cloud = qa.bitwiseAnd(1 << 5)
                  .and(qa.bitwiseAnd(1 << 7))
                  .or(qa.bitwiseAnd(1 << 3));
  // Remove edge pixels that don't occur in all bands
  var mask2 = image.mask().reduce(ee.Reducer.min());
  return image.updateMask(cloud.not()).updateMask(mask2);
};

2、构建正向指标和反指标

// indicators
// landsat 5
function NDWI(img){
  var nir = img.select('B4');
  var green = img.select('B2');
  var ndwi = img.expression(
    '(B2-B4)/(B2+B4)',
    {
      'B4':nir,
      'B2':green
    });
    return ndwi;
}

function MNDWI(img){
  var swir1 = img.select('B5');
  var green = img.select('B2');
  var mndwi = img.expression(
    '(B2-B5)/(B2+B5)',
    {
      'B5':swir1,
      'B2':green
    });
    return mndwi;
}

function EWI(img){
  var swir1 = img.select('B5')
  var nir = img.select('B4');
  var green = img.select('B2');
  var ewi = img.expression(
    '(B2-B4-B5)/(B2+B4+B5)',
    {
      'B5':swir1,
      'B4':nir,
      'B2':green
    });
    return ewi;
}

function NDBI(img){
  var swir1 = img.select('B5');
  var nir = img.select('B4');
  var ndbi = img.expression(
    '(B5-B4)/(B5+B4)',
    {
      'B5':swir1,
      'B4':nir
    });
    return ndbi;
}

function NDVI(img){
  var nir = img.select('B4');
  var red = img.select('B3');
  var ndvi = img.expression(
    '(B4-B3)/(B4+B3)',
    {
      'B4':nir,
      'B3':red
    });
    return ndvi;
}

3、选取我们的影像数据源,这里用的是landsat5,如果更换数据源的话云掩膜函数和指标计算也要一并调整。影像源代码如下:

// satellite data
var l8_col = ee.ImageCollection("LANDSAT/LT05/C01/T1_SR");

4、开始合成季节影像。
这里我做的分类是1990年的,但是因为landsat的重返周期太长了,尺度稍微大点的话会碰上很多云,掩膜的话又都掩膜没了,所以我使用1989到1991三年的合成,其中冬是12月1日到3月1日、春是3月1日到6月1日、夏是6月1日到9月1日、秋是9月1日到12月1日,可以根据自己的需求调整。另外,为了避免云掩膜出现的孔洞,所以我用unmask函数把孔洞赋值为0以填补出现的孔洞。具体代码如下:


// winter
var img_winter = ee.List([])
for (var i=1989; i<1991; i++){
  var winter = ee.Image(l8_col.filterBounds(roi)
                              .filterDate(i+"-12-1", (i+1)+"-3-1")
                              .filter(ee.Filter.lt('CLOUD_COVER', 100))
                              .map(cloudMaskL457)
                              .mean());
}
img_winter = img_winter.add(winter);
img_winter = ee.ImageCollection(img_winter).mean().unmask(0);
// spring
var img_spring = ee.List([])
for (var i=1989; i<1991; i++){
  var spring = ee.Image(l8_col.filterBounds(roi)
                              .filterDate(i+"-3-1", i+"-6-1")
                              .filter(ee.Filter.lt('CLOUD_COVER', 100))
                              .map(cloudMaskL457)
                              .mean());
}
img_spring = img_spring.add(spring);
img_spring = ee.ImageCollection(img_spring).mean().unmask(0);
// summer
var img_summer = ee.List([])
for (var i=1989; i<1991; i++){
  var summer = ee.Image(l8_col.filterBounds(roi)
                              .filterDate(i+"-6-1", i+"-9-1")
                              .filter(ee.Filter.lt('CLOUD_COVER', 100))
                              .map(cloudMaskL457)
                              .mean());
}
img_summer = img_summer.add(summer);
img_summer = ee.ImageCollection(img_summer).mean().unmask(0);
// fall
var img_fall = ee.List([])
for (var i=1989; i<1991; i++){
  var fall = ee.Image(l8_col.filterBounds(roi)
                              .filterDate(i+"-9-1", i+"-12-1")
                              .filter(ee.Filter.lt('CLOUD_COVER', 100))
                              .map(cloudMaskL457)
                              .mean());
}
img_fall = img_fall.add(fall);
img_fall = ee.ImageCollection(img_fall).mean().unmask(0);

5、为了确保分类成功率,我引入GEE中现成的几个产品。
这些产品可以根据需要灵活调整,这里就不多介绍了。依然地,使用unmask函数填补掩膜孔洞,代码如下:

// referring image data
var impervious = ee.Image("Tsinghua/FROM-GLC/GAIA/v10").clip(roi).unmask(-1);
var water = ee.Image('JRC/GSW1_2/GlobalSurfaceWater').clip(roi).unmask(-1);

6、之前合成了landsat5季节影像,别忘记上面我们写下了各种指数
这里就要使用这些合成影像计算指数生成各指数的波段,并进行命名,代码如下:


var ndwi_wi = NDWI(img_winter).rename('ndwi_wi');
var mndwi_wi = MNDWI(img_winter).rename('mndwi_wi');
var ewi_wi = EWI(img_winter).rename('ewi_wi');
var ndbi_wi = NDBI(img_winter).rename('ndbi_wi');
var ndvi_wi = NDVI(img_spring).rename('ndvi_wi');
var ndwi_sp = NDWI(img_spring).rename('ndwi_sp');
var mndwi_sp = MNDWI(img_spring).rename('mndwi_sp');
var ewi_sp = EWI(img_spring).rename('ewi_sp');
var ndbi_sp = NDBI(img_spring).rename('ndbi_sp');
var ndvi_sp = NDVI(img_spring).rename('ndvi_sp');
var ndwi_su = NDWI(img_summer).rename('ndwi_su');
var mndwi_su = MNDWI(img_summer).rename('mndwi_su');
var ewi_su = EWI(img_summer).rename('ewi_su');
var ndbi_su = NDBI(img_summer).rename('ndbi_su');
var ndvi_su = NDVI(img_summer).rename('ndvi_su');
var ndwi_fa = NDWI(img_fall).rename('ndwi_fa');
var mndwi_fa = MNDWI(img_fall).rename('mndwi_fa');
var ewi_fa = EWI(img_fall).rename('ewi_fa');
var ndbi_fa = NDBI(img_fall).rename('ndbi_fa');
var ndvi_fa = NDVI(img_fall).rename('ndvi_fa');

7、上面的指数是作为波段的形式。然后我们把引用的产品中的波段也提出并进行重命名,代码如下:

var imperchange = impervious.select('change_year_index').rename('imperchange');
var waterocc = water.select('occurrence').unmask(-1).rename('waterocc');
var waterchange = water.select('change_norm').unmask(-150).rename('waterchange');

8、然后,我们从每幅季节合成影像中提取波段1-7,并且加入同一幅影像,代码如下:


// add bands into images
var image = img_winter.addBands([ndwi_wi, mndwi_wi, ewi_wi, ndbi_wi, ndvi_wi,
                                  img_spring.select('B1').rename('B1_sp'), img_spring.select('B2').rename('B2_sp'), img_spring.select('B3').rename('B3_sp'), img_spring.select('B4').rename('B4_sp'), img_spring.select('B5').rename('B5_sp'),
                                  ndwi_sp, mndwi_sp, ewi_sp, ndbi_sp, ndvi_sp,
                                  img_summer.select('B1').rename('B1_su'), img_summer.select('B2').rename('B2_su'), img_summer.select('B3').rename('B3_su'), img_summer.select('B4').rename('B4_su'), img_summer.select('B5').rename('B5_su'),
                                  ndwi_su, mndwi_su, ewi_su, ndbi_su, ndvi_su,
                                  img_fall.select('B1').rename('B1_fa'), img_fall.select('B2').rename('B2_fa'), img_fall.select('B3').rename('B3_fa'), img_fall.select('B4').rename('B4_fa'), img_fall.select('B5').rename('B5_fa'),
                                  ndwi_fa, mndwi_fa, ewi_fa, ndbi_fa, ndvi_fa,
                                  imperchange, waterocc, waterchange]);


分类器参数设置

上面我们合成了一个含有51波段的影像,我们现在就需要选取我们分类器需要输入的波段了,代码如下:


// select bands
var bands = ['B1', 'B2', 'B3', 'B4', 'B5', 'B6', 'B7',
            'ndwi_wi', 'mndwi_wi', 'ewi_wi', 'ndbi_wi', 'ndvi_wi',
            'B1_sp', 'B2_sp', 'B3_sp', 'B4_sp', 'B5_sp',
            'ndwi_sp', 'mndwi_sp', 'ewi_sp', 'ndbi_sp', 'ndvi_sp',
            'B1_su', 'B2_su', 'B3_su', 'B4_su', 'B5_su',
            'ndwi_su', 'mndwi_su', 'ewi_su', 'ndbi_su', 'ndvi_su',
            'B1_fa', 'B2_fa', 'B3_fa', 'B4_fa', 'B5_fa',
            'ndwi_fa', 'mndwi_fa', 'ewi_fa', 'ndbi_fa', 'ndvi_fa',
            'imperchange', 'waterocc', 'waterchange'];

用merge函数把各分类合成一整个集合,然后它们的波段是value,然后把训练集和测试集按90%和10%分开。代码如下:


// set training data
var SP = Water.merge(Ponds).merge(Mud).merge(Others);
var training = image.select(bands).sampleRegions({
  collection: SP,
  properties:['value'],
  scale: 30
});
// set varified data
var withRandom = training.randomColumn('random');
var split = 0.9;
var trainingP = withRandom.filter(ee.Filter.lt('random', split)); // 90% training data
var testingP = withRandom.filter(ee.Filter.gte('random', split)); // 10% verified data

监督分类的实现与分类精度计算

得到一个分类后的影像


// classification
var class_img = image.select(bands).classify(classifier);

光有分类结果不行,还需要知道分类精度。把测试集也分类一下,然后用GEE自带的函数求转移矩阵并且计算overall accuracy和kappa,这些会打印在console里,代码如下:

// testing
var test = testingP.classify(classifier);

// confusion matrix
var confusionMatrix = test.errorMatrix('value', 'classification')
print('confusionMatrix',confusionMatrix);//面板上显示混淆矩阵
print('overall accuracy', confusionMatrix.accuracy());//面板上显示总体精度
print('kappa accuracy', confusionMatrix.kappa());//面板上显示kappa值

最后,当然要显示季节影像和分类后的影像,RGB波段组合还是色带什么的可以根据需要自行调整。如果选择手点的话,可以先随便点几个点,然后再根据显示的季节影像和分类影像再增加数据集,慢慢达到精度,代码如下:


// show images
var class_color = {
  min: 0,
  max: 3,
  palette: ['ffffff', '0049ff', '00ffca', '97422c']
};

Map.addLayer(img_winter.clip(roi.geometry()), {bands: ["B4", "B3", "B2"], min:0, max:2000}, "winter");
Map.addLayer(img_spring.clip(roi.geometry()), {bands: ["B4", "B3", "B2"], min:0, max:2000}, "spring");
Map.addLayer(img_summer.clip(roi.geometry()), {bands: ["B4", "B3", "B2"], min:0, max:2000}, "summer");
Map.addLayer(img_fall.clip(roi.geometry()), {bands: ["B4", "B3", "B2"], min:0, max:2000}, "fall");
Map.addLayer(class_img.clip(roi.geometry()), class_color, 'classifed')

Map.centerObject(roi, 7)

最后是保存在云盘里,下载


Export.image.toDrive({
        image:  class_img,//分类结果
        description: 'test_season_1990',//文件名
        folder: '111',
        scale: 30,//分辨率
        region: roi,//区域
        crs:"EPSG:4326",
        maxPixels:1e13//此处值设置大一些,防止溢出
      });

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1166544.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

虚拟机保护工具:Zerto Virtual Replication 10.0 U1 Crack

Zerto虚拟复制是为需要保护虚拟机和应用程序的企业设计的产品。通过通过连接到广域网或云到远程站点的复制来保护虚拟机。Zerto VR 2.0还可以与vCloud Director一起将虚拟机或虚拟机组复制到云端&#xff08;或从云端&#xff09;。 事实上&#xff0c;Zerto与33家云提供商合作…

map的operator[]原理

目录 一.map的insert函数 二.map的operator[]实现 三.operator[]的多重功能 一.map的insert函数 要想了解operator[]的实现原理&#xff0c;就要先看看insert。我们关注的是第一个insert的返回值&#xff0c;即pair<iterator, bool> 大意就是&#xff0c;返回一个pair对…

操作系统学习笔记(学习中)

计算机系统概述 1.操作系统概念 管理系统软/硬件资源&#xff0c;为程序提供服务 2.发展与分类 3.操作系统的运行环境 运行机制 指令&#xff1a;&#xff08;二进制机器指令&#xff09;&#xff0c;CPU能识别&#xff0c;执行的最基本命令 应用程序&#xff1a;程序员写…

qt6-error: invalid use of incomplete type ‘class Ui::Widget‘

背景 昨晚刚建立qt工程&#xff0c;点击运行&#xff0c;工作可以直接使用&#xff0c;但是早上点开工作&#xff0c;就出现type类型错误。有点奇怪。问题页面显示&#xff0c;问题主要就是ui::widget的类型错误。 这篇文章提醒我&#xff0c;昨晚因为在尝试修改一些参数时&a…

Flutter 手把手国际化

1.导入依赖 flutter:sdk: flutterflutter_localizations:sdk: flutterintl: any2.安装插件Flutter Intl Android Studio > File > Settings > Plugins 搜索Flutter Intl 并安装和重启Android Studio生效 3.通过插件初始化并配置语言 Android Studio > Tools >…

【已解决】在linux部署出现java文件操作报错:java.io.FileNotFoundException

1.报错场景&#xff1a; 其中的 ip2region.xdb 文件是放在 resources 文件夹中的&#xff0c;然后在一个工具类里面读取这个文件&#xff0c;在开发环境中的是这样读取的&#xff1a; ClassPathResource resource new ClassPathResource("ip2region.xdb");//获取真…

NI-9505 嵌入式行业领先的流量校准测量算法

NI-9505 嵌入式行业领先的流量校准测量算法 基岩自动化公司&#xff0c;基岩OSA自动化平台的制造商&#xff0c;已经将流量计算机功能集成到OSA平台中。奥萨流程系列嵌入流量校准基岩自动化平台中的测量应用。Flow-Cal的软件是流量测量和生产核算数据的选择。 奥萨所有基岩控…

基于Python的豆瓣电影排行榜,可视化系统

1 简介 基于Python flask 的豆瓣电影数据获取&#xff0c;数据可视化系统&#xff0c;本系统朱亚奥包括了影视系统的爬虫与分析。影视是人们娱乐、放松心情的重要方式之一&#xff0c;因此对影视的分析具有重要的现实意义。通过采用Python编程语言&#xff0c;使用flask框架搭…

内部福利!双11百度文心一言底层的千帆大模型免费试用!

内部福利&#xff0c;现在可以免费试用&#xff0c;而且额度超高。双11福利 个人大模型平台新用户&#xff1a;50元&#xff1b;限量1000张&#xff1b;限时一个月使用 企业大模型平台新用户&#xff1a;200元&#xff1b;限量200张&#xff1b;限时一个月使用 EB4对标GPT4 …

GoLong的学习之路(十七)基础工具之GORM(操作数据库)(更新Update)

书接上回&#xff0c;上回写道&#xff0c;GORM的查询和创建&#xff08;插入数据&#xff09;&#xff0c;这回继续些增删改查的改和删的操作。 文章目录 更新update修改单个列修改多个列修改选定字段批量更新新阻止全局更新 使用 SQL 表达式更新注意 根据子查询进行更新不使用…

Spring boot 整合 JWT

系列文章目录 第一章 Java线程池技术应用 第二章 CountDownLatch和Semaphone的应用 第三章 Spring Cloud 简介 第四章 Spring Cloud Netflix 之 Eureka 第五章 Spring Cloud Netflix 之 Ribbon 第六章 Spring Cloud 之 OpenFeign 第七章 Spring Cloud 之 GateWay 第八章 Sprin…

【WinForm详细教程六】WinForm中的GroupBox和Panel 、TabControl 、SplitContainer控件

文章目录 1.GroupBox和Panel2.TabControl3.SplitContainer 1.GroupBox和Panel GroupBox&#xff1a;是一个分组容器&#xff0c;提供一个框架将相关的控件组织在一起&#xff0c;它有标题、边框&#xff0c;但没有滚动条。 Panel&#xff1a;也是一个容器控件&#xff0c;用来…

Git GitHub同步失败

文章目录 错误解决方案第一步第二步第三步第四步第六步第七步 错误 昨天晚上提交代码到GitHub时遇到了这个错误。 remote: Support for password authentication was removed on August 13, 2021. Please use a personal access token instead.字面大体意思就是你原先的密码凭…

预约按摩小程序开发优势;

在快节奏和高压社会中&#xff0c;按摩已成为许多人缓解压力和保持健康的重要方式&#xff0c;各地的按摩店也是随处可见&#xff0c;而为了能够更好地提供服务&#xff0c;很多按摩店都引入了小程序应用。今天我们就主要了解一下按摩店小程序具体有什么用&#xff0c;能够提供…

【iOS免越狱】利用IOS自动化WebDriverAgent实现自动直播间自动输入

1.目标 由于看直播的时候主播叫我发 666&#xff0c;支持他&#xff0c;我肯定支持他呀&#xff0c;就一直发&#xff0c;可是后来发现太浪费时间了&#xff0c;能不能做一个直播间自动发 666 呢&#xff1f;于是就开始下面的操作。 2.操作环境 iPhone一台 WebDriverAgent …

CAD操作技巧学习总结

1&#xff0c;已知一个圆&#xff0c;画该圆切线。 L命令画直线&#xff0c;再tan指令确定第一个点为切点&#xff0c;依次输入&#xff08;长度&#xff09;<&#xff08;角度&#xff09;&#xff0c;如55<-45,负号为顺时针。 2&#xff0c;中心点偏移。 O命令偏移&am…

再学一点mybatis(原理分析)

文章目录 [TOC](文章目录) 一、mybatis是什么&#xff1f;1. Mybatis的特点以及优缺点 二、mybatis架构1.基本架构2.重要组件 三、原理1. SQL解析2. Mapper接口3. 动态代理4. SQL执行4.1 Executor4.2 StatementHandler4.3 ParameterHandler4.4 ResultHandler 文章内容有点长&am…

【蓝桥每日一题]-二分精确(保姆级教程 篇4) #kotori的设备 #银行贷款 #一元三次方程求解

今天讲二分精确题型 目录 题目&#xff1a;kotori的设备 思路&#xff1a; 题目&#xff1a;银行贷款 思路&#xff1a; 题目&#xff1a;一元三次方程求解 思路&#xff1a; 题目&#xff1a;kotori的设备 思路&#xff1a; 求&#xff1a;设备最长使用时间 二分查找&#…

Linux难学?大神告诉你,Linux到底该怎么自学!

文章目录 前言一、明白这些道理&#xff0c;Linux 就不难学二、五步学会 Linux 命令行&#xff0c;用好这本手册三、Linux 学习进阶之路 前言 知乎上有一条热门问答&#xff0c;问题是 “Linux为什么那么难&#xff1f;” 从问题来看&#xff0c;提问者还处在初学阶段。但他显…

Centos7扩容

Centos7扩容 保证虚拟机关机且没有快照的情况下按照下图进行操作&#xff1a; 设置好后开机&#xff0c;查看分区情况&#xff1a; [rootlocalhost ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/mapper/centos-root 17G 12G 5.4G 69% / …