Google Earth Engine(GEE)深度学习入门教程- GEE导出篇

news2024/11/25 18:53:38

GEE导出篇

官方教程:TFRecord 和地球引擎
Code_editor_diagram

在GEE的JS Code Editor中,我们按照我们的需要去处理对应的遥感影像,得到处理后Image影像。为了导出后读取数据,在导出前一定清楚每个波段的名称(不然没法读取)。深度学习数据集所需数据以为patch为单位,所以需要对整个遥感影像进行裁剪,我探索出来GEE能实现的裁剪方法的有2种滑窗裁剪、随机裁剪

随机裁剪:随机选择生成多个样点,然后裁剪样点周围的邻域,导出。用作构造数据集

滑窗裁剪:设定步幅和窗口大小,裁剪完整影像,导出。用作大范围推理验证

滑窗裁剪

TFRecord_diagram

导出有2个重要参数:patchSizekernelSize。patchSize 是指滑窗不重叠区域的大小,kernelSize是指滑窗重叠缓冲区的大小。例如:patchSize 为32,kernelSize为32,则导出的图像单个大小为64*64,中间的32*32为不重叠区域,边缘的16格像素为缓冲区大小。导出图像时,数据按通道、高度、宽度 (CHW) 排序。导出可以拆分为多个 TFRecord 文件,每个文件包含一个或多个 大小的 patches ,这是用户在导出中指定的。文件的大小(以字节为单位是用户在参数中指定的)。

代码如下:

Export.image.toCloudStorage({
    image : image.toFloat(),         //保证所有层数据类型统一,导出Image影像
    description : desc,              //任务名称
    bucket : BUCKET,                 //存储桶名称
    fileNamePrefix : FOLDER + '/' + desc,      //保存的路径及文件名
    region : ee.Feature(savePolys.get(g)).geometry(),//范围矢量
    scale : 10,                     //分辨率
    fileFormat : 'TFRecord',        //格式
    maxPixels : 1e13,                      
    formatOptions : {
      'patchDimensions': [32,32], //核心区大小
      'kernelSize': [32,32],     //缓冲区
      'compressed': true,
      'maxFileSize': 104857600*10 //400M 
      }
     });

导出结果:

image-20240108172111841

导出内容除了包含TFRecord格式的数据包之外,还有一个json格式文件,文件内部保存着影像的裁剪结果和地理位置信息,例如:

{
  "projection": {
    "crs": "EPSG:4326",
    "affine": {
      "doubleMatrix": [8.983152841195215E-5, 0.0, 116.04113446753695, 0.0, -8.983152841195215E-5, 33.789500591456914]
    }
  },
  "patchDimensions": [32, 32],
  "patchesPerRow": 19,
  "totalPatches": 285
}

其中:crs为投影坐标系、doubleMatrix为地理仿射变换矩阵、patchDimensions为不重叠区域大小、patchesPerRow为裁剪区域内每行得到的样本数量、totalPatches为总的patch数量。这些信息都是为了将裁剪后的普通图像恢复为遥感影像。

随机裁剪

随机生成样点,然后裁剪样点周围的邻域,导出。主要用作构造数据集,扩充数据集的样本量。

因为本文的使用的预处理过程比较复杂,数据量比较大,直接对整幅影像导出会导致GEE用户内存溢出,所以本文对研究区进行区块划分

划分训练、验证、测试区域的代码分为以下几个步骤:

  1. 确定划分区域的左下角和右上角的经纬度坐标(corner1、corner2)
  2. 设定横向纵向划分块数:sliceN = 10
  3. 生成区块
  4. 使用ee.Filter.isContained去除不被包含在研究区的区块
  5. 按照6:2:2比例划分区块为训练、验证、测试区块
  6. 导出区块矢量为geometryLayer并保存到Map.drawingTools()中

在这里插入图片描述

//将研究区划分为多个区域,并按照6:2:2的比例划分训练、验证、测试区域,
  //!!!仅需执行一次,手动将区域格式变化为featureColection
  var roi = ee.FeatureCollection('TIGER/2018/States').filter(ee.Filter.eq('NAME', 'Illinois'));
  // 将研究区域按照 10*10 的大小进行分割,循环处理子区域
  var corner1 = [-91.70112615545109, 36.986063288694794]
  var corner2 = [-87.30659490545109, 42.60259690092805]
  var sliceN = 10;
  var slicePolysList = ee.List([])
  for (var x = corner1[0]; x < corner2[0]; x += (corner2[0]-corner1[0])/sliceN) {
  for (var y = corner1[1]; y < corner2[1]; y += (corner2[1]-corner1[1])/sliceN) {
    var x2 = x+(corner2[0]-corner1[0])/sliceN
    var y2 = y+(corner2[1]-corner1[1])/sliceN
    var area = ee.Geometry.Rectangle(x, y, x2, y2);
    slicePolysList = slicePolysList.add(ee.Feature(area))
  }
  }
  var slicePolys = ee.FeatureCollection(slicePolysList)   // 去除不被完全包含的区域
                  .filter(ee.Filter.isContained({leftField: '.geo',rightValue: roi.geometry()}))
                  .randomColumn("random", 1)
  var trainPolys = slicePolys.filter(ee.Filter.rangeContains("random",0,0.6))
  var evalPolys = slicePolys.filter(ee.Filter.rangeContains("random",0.6,0.8))
  var testPolys = slicePolys.filter(ee.Filter.rangeContains("random",0.8,1))
  var geometryLayer = ui.Map.GeometryLayer({geometries: [trainPolys.geometry().getInfo()], name: 'trainPolys',color: 'green'});
  // 将 GeometryLayer 添加到地图
  Map.drawingTools().layers().add(geometryLayer);
  var geometryLayer = ui.Map.GeometryLayer({geometries: [evalPolys.geometry().getInfo()], name: 'evalPolys',color: 'red'});
  // 将 GeometryLayer 添加到地图
  Map.drawingTools().layers().add(geometryLayer);
  var geometryLayer = ui.Map.GeometryLayer({geometries: [testPolys.geometry().getInfo()], name: 'testPolys',color: 'blue'});
  // 将 GeometryLayer 添加到地图
  Map.drawingTools().layers().add(geometryLayer);

区块划分完成后,我们使用循环逐个区块随机采样并进行导出,单个样本大小为64*64。单次采样过多也会内存溢出,所以一个区块也要采样多次,每次采样少一点。

//此时需要让单次处理的区域尽可能小
//https://developers.google.com/earth-engine/guides/tf_examples
var BUCKET = 'yqs'
var FOLDER = 'yangfangVal'


var TRAINING_BASE = 'training_patches'
var EVAL_BASE = 'eval_patches'
var TEST_BASE = 'test_patches'

var BANDS  = ["B2","B3","B4","B5","B6","B7","B8","B8A","B11","B12"]
var RESPONSE = 'soya'
var FEATURES = BANDS.concat([RESPONSE])
print(FEATURES)

var N = 160       //单个区域内的采样数量。
var n = 16      //单区域采样次数。增大n,可以减少单次采样的数量,防止出现Computed value is too large.错误 !但是导出速度会变慢
var KERNEL_SIZE = 64    //减小此值可以防止出现采样时出现 Computed value is too large. 128导出数据包太大了
var KERNEL_SHAPE = [KERNEL_SIZE, KERNEL_SIZE]
var list = ee.List.repeat(1, KERNEL_SIZE)
var lists = ee.List.repeat(list, KERNEL_SIZE)
var kernel = ee.Kernel.fixed(KERNEL_SIZE, KERNEL_SIZE, lists)

trainPolys = trainPolys.toList(trainPolys.size());  // 将 FeatureCollection 转换为 FeatureList
evalPolys = evalPolys.toList(evalPolys.size());  
testPolys = testPolys.toList(testPolys.size());  

var savePolys = testPolys
var BASE = TEST_BASE//TRAINING_BASE;//EVAL_BASE//TEST_BASE
//为了保证内存不溢出,在处理图片的时候尽可能处理较小块的区域
for (var g = 0; g < savePolys.size().getInfo(); g++) {
  var geomSample = ee.FeatureCollection([]); // 用于存储采样点的 FeatureCollection
  // 数据集标签的加载函数,请根据自己需求对应修改。
  var soya = CDLlib.getCDL()
  //影像预处理函数,请根据自己需求对应修改。
  var S2 = S2lib.getS2Image(BANDS,ee.Feature(savePolys.get(g)).geometry())
  
  var image = S2.addBands([soya]).rename(FEATURES)
  //给多个数据包命名
  var desc = BASE + '_g' + g.toString();
  print(image)
  var arrays = image.toFloat().neighborhoodToArray(kernel)
  for (var i = 0; i < n; i++) {
  	var sample = arrays.sample({
       region: ee.Feature(savePolys.get(g)).geometry(),
       scale: 10,
       numPixels: N / n,
       seed: i,
       tileScale: 8
     });
  	// print(sample.size())
  	geomSample = geomSample.merge(sample); // 将采样点合并到 geomSample 中
  }
  
  // Map.addLayer(image,{bands: ['soya']},desc);//调试用
  // //print(geomSample.size())//调试用
  // Map.addLayer(ee.Feature(savePolys.get(g)).geometry().buffer(640),[],desc);//调试用
   
  var task = Export.table.toCloudStorage({
     collection: geomSample,
     description: desc,
     bucket: BUCKET,
     fileNamePrefix: FOLDER + '/' + desc,
     fileFormat: 'TFRecord',
   });
}

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

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

相关文章

掌握Lazada API接口:开启电商开发新篇章,引领业务增长潮流

一、概述 Lazada API接口是Lazada平台提供的软件开发工具包&#xff0c;它允许第三方开发者通过编程方式访问Lazada平台上的商品、订单、用户等数据&#xff0c;并执行相关操作。通过使用Lazada API接口&#xff0c;开发者可以快速构建与Lazada平台集成的应用程序&#xff0c;…

三维轮廓测量仪:革命性技术在工业智能制造中的多重应用

现代工业智能制造领域中&#xff0c;三维轮廓测量仪是一项重要的测量技术。三维轮廓测量仪利用光学、激光或光电等技术手段&#xff0c;通过测量物体表面轮廓的三维坐标信息&#xff0c;能实现对物体形状、尺寸和表面特征的准确测量。它可以广泛应用于工业自动化、制造工艺控制…

CF1909_C. Heavy Intervals题解

CF1909_C. Heavy Intervals题解 题目传送门&#xff08;Problem - C - CodeforcesCodeforces. Programming competitions and contests, programming communityhttps://codeforces.com/contest/1909/problem/C&#xff09;。 题目翻译如下&#xff1a;&#xff08;图片来源&a…

不带控制器打包exe,转pdf文件时失败的原因

加了注释的两条代码后&#xff0c;控制器会显示一个docx转pdf的进度条。这个进度条需要控制器的实现&#xff0c;如果转exe不带控制器的话&#xff0c;当点击转换为pdf的按钮就会导致程序出错和闪退。 __init__.py文件的入口

前端学习笔记 3:Vue 工程

前端学习笔记 3&#xff1a;Vue 工程 上一篇文章介绍了如何在单一 Html 页面中使用 Vue&#xff0c;本文介绍如何从头开始用 Vue 构建一个前端工程项目。 1.环境准备 Vue 框架代码的创建依赖于 Node.js&#xff0c;因此需要先安装 Node.js。 2.创建和启动 2.1.创建 通过以…

【Docker】可以将TA用于什么,简单了解下

欢迎来到《小5讲堂》&#xff0c;大家好&#xff0c;我是全栈小5。 这是是《Docker容器》序列文章&#xff0c;每篇文章将以博主理解的角度展开讲解&#xff0c; 特别是针对知识点的概念进行叙说&#xff0c;大部分文章将会对这些概念进行实际例子验证&#xff0c;以此达到加深…

阿里云2024年优惠券活动大全

阿里云作为中国领先的云计算服务提供商&#xff0c;一直致力于为用户提供优质、高效、安全、可靠的云计算服务。为了更好地回馈用户&#xff0c;阿里云会不定期地推出各种优惠券活动&#xff0c;让用户在享受云计算服务的同时&#xff0c;也能享受到更多的实惠。 1、阿里云云小…

流量超了不容小觑,做到这些完全不用担心

流量告急的小伙伴们总是会有这种烦恼&#xff0c;一不注意就用超了&#xff0c;话费蹭蹭的没了&#xff0c;尤其是到月底的时候&#xff0c;一不留神&#xff0c;套餐说超就超。今天小编就给大家总结几个办法&#xff0c;很有效的让小伙伴们再也不用被“流量突然用完”的恐慌支…

大甩卖——代码全家桶!!!

Python-凯斯西储大学&#xff08;CWRU&#xff09;轴承数据解读与分类处理 Python轴承故障诊断 (一)短时傅里叶变换STFT Python轴承故障诊断 (二)连续小波变换CWT_pyts 小波变换 故障-CSDN博客 Python轴承故障诊断 (三)经验模态分解EMD_轴承诊断 pytorch-CSDN博客 Pytorch-…

Linux文件系统与日志分析

目录 一、Linux文件系统 1、inode与block 2、查看inode号码的命令 3、inode包含文件的元信息 4、Linux系统文件的三个主要时间属性 5、用户通过文件名打开文件时系统内部过程 6、inode的大小 7、inode的特点 二、日志 1、日志的功能 2、日志文件的分类 3、系统日志…

JavaScript基础(24)_dom查询练习(一)

<!DOCTYPE html> <html lang"zh"> <head><meta charset"UTF-8"><link rel"stylesheet" href"../browser_default_style/reset.css"><title>dom查询练习一</title><style>.text {widt…

c语言:求1-100的奇数和|练习题

一、题目 求1-100以内的奇数和 二、代码截图【带注释】 三、源代码【带注释】 #include <stdio.h> //思路分析 //1、一个除以2&#xff0c;除不尽的&#xff0c;便是奇数 //设计常量N为100&#xff0c;常量随时可以变动 #define N 100 int main() { int sum0;//设…

【Python】不一样的Ansible(一)

不一样的Ansible——进阶学习 前言正文概念Ansible CorePlugins和Modules 插件插件类型编写自定义插件基本要求插件选项文档标准编写插件 添加一个本地插件注册为内置插件指定插件目录 其他一些技巧更改Strategy 结语 前言 Ansible 是一个极其简单的 IT 自动化引擎&#xff0c…

MISRA C 解读

说明&#xff1a;本文由vector官方视频整理而来&#xff0c;原视频链接解读MISRA C_哔哩哔哩_bilibili 1、MISRA 简介 1.1 发起 MISRA (The Motor Industry Software Reliability Association ) 汽车工业软件可靠性联会&#xff0c;起先作为研究车载嵌入式软件制备准则的开发…

FFmpeg读取Assets资源文件

在Android开发中我们经常把原生资源文件放在assets目录下以供需要时读取&#xff0c;通过API提供的resources.assets.open(filename)/openFd(filenam)方法可以非常方便获得InputStream或FileDescriptor&#xff08;文件标识符&#xff09;&#xff0c;但是在使用FFmpeg读取Asse…

CTF-PWN-沙箱逃脱-【seccomp和prtcl-1】

文章目录 啥是seccomp#ifndef #define #endif使用使用格式 seccomp无参数条件禁用系统调用有参数条件禁用系统调用 prctl实例 seccomp_export_bpf 啥是seccomp 就是可以禁用掉某些系统调用&#xff0c;然后只能允许某些系统调用 #ifndef #define #endif使用 #ifndef #defin…

Neo4j恢复

主要记录从备份文件中恢复Neo4j 误删数据 为了模拟误删除场景&#xff0c;我们查询Person&#xff0c;并模拟误操作将其进行删除&#xff1b; match(p:Person) return p Step1&#xff1a; 关闭服务 Step2&#xff1a; 恢复数据 找到Neo4j的数据文件夹&#xff0c;我的安…

Linux第18步_安装“Ubuntu系统下的C语言编GCC译器”

Ubuntu系统没有提供C/C的编译环境&#xff0c;因此还需要手动安装build-essential软件包&#xff0c;它包含了 GNU 编辑器&#xff0c;GNU 调试器&#xff0c;和其他编译软件所必需的开发库和工具。本节用于重点介绍安装“Ubuntu系统下的C语言编译器GCC”和使用。 1、在安装前…

矢量,矢量化的梯度下降以及多元线性回归

一、矢量 定义&#xff1a;按照特定顺序排列的元素集合。可以被视为一维数组。 在机器学习中的作用&#xff1a; 特征表示&#xff1a;在机器学习任务中&#xff0c;输入数据通常以矢量的形式表示。例如&#xff0c;图像可以表示为像素值的矢量&#xff0c;文本可以表示为词…

CodeGPT,你的智能编码助手—CSDN出品

CodeGPT是由CSDN打造的一款生成式AI产品&#xff0c;专为开发者量身定制。 无论是在学习新技术还是在实际工作中遇到的各类计算机和开发难题&#xff0c;CodeGPT都能提供强大的支持。其涵盖的功能包括代码优化、续写、解释、提问等&#xff0c;还能生成精准的注释和创作相关内…