当前位置: 首页 > article >正文

别再手动改MTL了!一个Python脚本搞定ENVI打开Landsat8 Collection2 Level2数据

别再手动改MTL了一个Python脚本搞定ENVI打开Landsat8 Collection2 Level2数据遥感数据处理中最令人头疼的莫过于遇到格式兼容性问题。最近在USGS下载的Landsat8 Collection2 Level2数据就给我带来了这样的困扰——ENVI竟然无法直接读取其MTL元数据文件。作为一名长期从事遥感研究的工程师我深知手动修改MTL文件不仅耗时耗力还容易出错特别是在处理大批量数据时。经过反复尝试和优化我开发了一个Python脚本可以自动完成MTL文件的格式转换让ENVI顺利读取这些数据。本文将详细介绍这个解决方案从原理到实现再到批量处理的应用技巧。1. 为什么ENVI无法直接读取Landsat8 C2 L2的MTL文件USGS在Landsat数据Collection2版本中对数据结构进行了重大调整特别是Level2产品的MTL文件格式与ENVI的预期格式存在差异。具体来说主要问题集中在以下几个方面元数据分组标识不匹配ENVI期望MTL文件以GROUP L1_METADATA_FILE开头而Collection2 Level2数据使用的是GROUP LANDSAT_METADATA_FILE包含不兼容的节点文件中存在GROUP LEVEL1***这样的节点会导致ENVI解析失败经典版ENVI的特殊要求即使在新版ENVI中能通过简单修改解决问题经典版ENVI仍需要更全面的格式调整手动修改虽然可行但面临三个主要问题容易遗漏需要修改的部分批量处理时效率极低不同数据产品可能需要不同的修改策略# 原始MTL文件示例片段 GROUP LANDSAT_METADATA_FILE GROUP LEVEL1_PROCESSING_RECORD DATA_TYPE L2SP ... END_GROUP LEVEL1_PROCESSING_RECORD END_GROUP LANDSAT_METADATA_FILE2. Python自动化解决方案核心原理基于上述问题分析我们的Python脚本需要完成两个核心任务修改文件头将GROUP LANDSAT_METADATA_FILE替换为GROUP L1_METADATA_FILE删除不兼容节点移除所有GROUP LEVEL1***及其对应的END_GROUP部分脚本的工作原理可以概括为以下步骤读取原始MTL文件内容定位所有需要删除的LEVEL1相关节点修改文件头并保留有效内容写入新的MTL文件注意脚本会直接修改原始文件建议先备份重要数据3. 完整脚本代码解析与使用指南下面是我开发的完整Python脚本已在实际项目中验证过其可靠性import os def fix_landsat_mtl(mtl_path): 修复Landsat8 Collection2 Level2 MTL文件使其兼容ENVI :param mtl_path: MTL文件完整路径 # 读取原始文件内容 with open(mtl_path, r) as file: lines file.readlines() # 查找所有LEVEL1节点的起始和结束行 level1_indices [i for i, line in enumerate(lines) if GROUP LEVEL1 in line] end_indices [] for start_idx in level1_indices: # 找到对应的END_GROUP行 stack 1 current_idx start_idx 1 while stack 0 and current_idx len(lines): if GROUP in lines[current_idx]: stack 1 elif END_GROUP in lines[current_idx]: stack - 1 current_idx 1 end_indices.append(current_idx - 1) # 构建新内容修改第一行跳过LEVEL1相关部分 new_lines [] new_lines.append(GROUP L1_METADATA_FILE\n) # 修改文件头 i 1 # 从第二行开始处理 while i len(lines): if i in level1_indices: # 跳过整个LEVEL1节点 i end_indices[level1_indices.index(i)] 1 else: new_lines.append(lines[i]) i 1 # 写回文件 with open(mtl_path, w) as file: file.writelines(new_lines) if __name__ __main__: # 示例用法 mtl_file rE:\data\LC08_L2SP_123032_20220101_20220109_02_T1_MTL.txt fix_landsat_mtl(mtl_file)3.1 脚本使用说明要使用这个脚本你需要安装Python 3.x环境将上述代码保存为fix_landsat_mtl.py修改脚本底部的mtl_file路径为你实际的MTL文件路径运行脚本对于批量处理可以结合os.listdir()或glob模块遍历目录import glob # 批量处理一个目录下的所有MTL文件 for mtl_file in glob.glob(rE:\landsat_data\*\*_MTL.txt): fix_landsat_mtl(mtl_file)4. 进阶应用集成到ENVI/ArcGIS工作流为了使这个解决方案更加实用我们可以将其集成到常用的遥感处理平台中。4.1 创建ENVI扩展工具ENVI支持通过IDL或Python创建自定义工具。以下是将我们的脚本封装为ENVI扩展的步骤创建一个新的ENVI扩展项目添加菜单项或按钮将Python脚本与界面元素关联打包分发扩展# ENVI扩展示例代码框架 import os from envi import ENVI, Task class FixLandsatMTLTask(Task): def __init__(self): super(FixLandsatMTLTask, self).__init__() self.name Fix Landsat MTL self.description Fix Landsat8 Collection2 Level2 MTL for ENVI def execute(self): # 获取用户选择的文件 mtl_file self.get_parameter(mtl_file).value fix_landsat_mtl(mtl_file) ENVI.message(MTL file fixed successfully!) # 注册任务 ENVI.task_registry.register(FixLandsatMTLTask)4.2 ArcGIS Python工具箱集成对于ArcGIS用户可以创建一个Python工具箱新建一个Python工具箱(.pyt)定义工具参数(输入MTL文件路径)在execute方法中调用我们的修复函数import arcpy class Toolbox(object): def __init__(self): self.label Landsat Tools self.alias landsat self.tools [FixLandsatMTL] class FixLandsatMTL(object): def __init__(self): self.label Fix Landsat MTL self.description Fix Landsat8 Collection2 Level2 MTL files def getParameterInfo(self): params [] params.append(arcpy.Parameter( namemtl_file, displayNameMTL File, datatypeDEFile, parameterTypeRequired, directionInput)) return params def execute(self, parameters, messages): mtl_file parameters[0].valueAsText fix_landsat_mtl(mtl_file) arcpy.AddMessage(MTL file fixed successfully!)5. 处理不同场景的实用技巧在实际应用中可能会遇到各种特殊情况。以下是几个实用技巧5.1 处理多个数据产品不同Landsat产品(如L2SP与L2SR)可能有细微差异脚本可能需要调整L2SP(Surface Reflectance and Surface Temperature): 通常包含更多波段L2SR(Surface Reflectance Only): 只包含反射率波段可以通过检查DATA_TYPE字段来自适应处理# 在fix_landsat_mtl函数中添加 if any(DATA_TYPE L2SR in line for line in lines): # L2SR特定处理 pass elif any(DATA_TYPE L2SP in line for line in lines): # L2SP特定处理 pass5.2 错误处理与日志记录为增强脚本的健壮性建议添加错误处理和日志import logging from datetime import datetime logging.basicConfig(filenamefix_mtl.log, levellogging.INFO) def fix_landsat_mtl(mtl_path): try: start_time datetime.now() # ...原有代码... logging.info(fSuccessfully processed {mtl_path} in {datetime.now()-start_time}) except Exception as e: logging.error(fFailed to process {mtl_path}: {str(e)}) raise5.3 性能优化建议当处理大量数据时可以考虑以下优化多线程处理使用Python的concurrent.futures模块并行处理多个文件内存映射对于超大MTL文件使用mmap模块提高IO效率批量提交将多个文件操作合并为一个批处理任务from concurrent.futures import ThreadPoolExecutor import glob def batch_process_mtl(directory, max_workers4): mtl_files glob.glob(os.path.join(directory, **, *_MTL.txt), recursiveTrue) with ThreadPoolExecutor(max_workersmax_workers) as executor: executor.map(fix_landsat_mtl, mtl_files)6. 与其他工具链的集成这个解决方案可以轻松集成到更大的处理流程中。以下是几个典型场景6.1 与QGIS处理链结合在QGIS中可以通过以下步骤创建自动化工作流使用QGIS的Processing Framework创建一个新的Python脚本将我们的MTL修复脚本作为第一步后续接ENVI或QGIS自身的处理步骤6.2 构建完整数据处理管道一个完整的数据处理管道可能包括从USGS自动下载数据修复MTL文件在ENVI中进行辐射校正/大气校正执行分类或其他分析导出结果可以使用luigi或airflow等工具编排这个流程import luigi class DownloadLandsatData(luigi.Task): date luigi.Parameter() pathrow luigi.Parameter() def run(self): # 下载逻辑 pass def output(self): return luigi.LocalTarget(flandsat_{self.date}_{self.pathrow}.tar.gz) class FixMTLFiles(luigi.Task): date luigi.Parameter() pathrow luigi.Parameter() def requires(self): return DownloadLandsatData(self.date, self.pathrow) def run(self): # 调用我们的修复脚本 pass # 可以继续添加更多处理步骤...

相关文章:

别再手动改MTL了!一个Python脚本搞定ENVI打开Landsat8 Collection2 Level2数据

别再手动改MTL了!一个Python脚本搞定ENVI打开Landsat8 Collection2 Level2数据 遥感数据处理中,最令人头疼的莫过于遇到格式兼容性问题。最近在USGS下载的Landsat8 Collection2 Level2数据就给我带来了这样的困扰——ENVI竟然无法直接读取其MTL元数据文件…...

保姆级教程:用Python 3.11和Poetry从零部署微软GraphRAG v2.7.0(附Azure OpenAI配置)

从零部署微软GraphRAG v2.7.0:Python 3.11与Poetry实战指南 当开发者第一次接触微软开源的GraphRAG框架时,往往会被其强大的知识图谱构建能力所吸引——这个基于图结构的检索增强生成系统,能通过智能节点关联实现远超传统RAG的语义理解深度。…...

3大技术架构深度解析:VRM-Addon-for-Blender如何实现跨格式模型转换的高性能解决方案

3大技术架构深度解析:VRM-Addon-for-Blender如何实现跨格式模型转换的高性能解决方案 【免费下载链接】VRM-Addon-for-Blender VRM Importer, Exporter and Utilities for Blender 2.93 to 5.1 项目地址: https://gitcode.com/gh_mirrors/vr/VRM-Addon-for-Blende…...

别只盯着算法!聊聊车牌识别里那些FPGA图像后处理的‘脏活累活’:定位、分割与资源博弈

别只盯着算法!聊聊车牌识别里那些FPGA图像后处理的‘脏活累活’:定位、分割与资源博弈 车牌识别技术早已渗透进日常生活,从停车场收费到交通违章抓拍,背后都离不开高效的图像处理流水线。当大多数开发者将目光聚焦在深度学习算法调…...

3步永久备份QQ空间青春记忆:GetQzonehistory数据拯救方案

3步永久备份QQ空间青春记忆:GetQzonehistory数据拯救方案 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory 在数字记忆快速迭代的时代,你是否曾担心那些承载青春印…...

GVINS数据集评测:用自录ROS Bag在室内外验证GNSS拒止下的定位恢复能力

GVINS实战评测:如何用自采集数据验证GNSS拒止环境下的定位鲁棒性 去年夏天,我们在深圳某工业园区测试无人机自主巡检系统时,遇到了一个棘手问题——当飞行器从开阔区域进入钢结构厂房时,GNSS信号突然衰减导致的定位漂移让飞行轨迹…...

告别串口模式:在Ubuntu 22.04上为FTDI芯片启用MPSSE功能(D2XX驱动保姆级教程)

解锁FTDI芯片的隐藏潜能:Ubuntu 22.04下D2XX驱动深度配置指南 当你在Linux系统中使用FT232H或FT4232H这类FTDI芯片时,是否曾好奇过它们除了串口通信之外还能做什么?实际上,这些芯片内置了强大的MPSSE引擎,能够实现SPI、…...

别再死记硬背for循环了!用C#在Razor页面里做个动态九九乘法表,实战理解更深刻

用C#和Razor Pages打造动态九九乘法表:告别枯燥的语法学习 记得刚开始学编程时,最让我头疼的就是那些看似简单却怎么也记不住的循环语法。直到有一天,导师让我用for循环做一个能在网页上展示的九九乘法表,那些抽象的表达式突然就变…...

CentOS 7下Composer报错‘missing ext-fileinfo‘?别慌,手把手教你启用PHP的fileinfo扩展

CentOS 7下PHP的fileinfo扩展缺失问题全解析与实战修复指南 当你正在CentOS 7服务器上部署一个基于ThinkPHP的项目,运行composer install时突然遭遇一系列关于ext-fileinfo扩展缺失的错误提示,这确实会让人感到措手不及。这类问题在PHP项目部署中相当常见…...

《另一个伊甸》日服角色实装全记录:从2.14到1.0,你的本命角色是哪一年登场的?

《另一个伊甸》角色编年史:从2.14到1.0的时空旅人图鉴 翻开《另一个伊甸》的版本更新日志,就像展开一卷跨越五年的时空绘卷。每个数字组合背后,都藏着改变玩家队伍构成的关键角色。从2017年的1.0版本到2022年的2.14版本,这些时空旅…...

VS Code设置文件终极指南:全局vs工作区settings.json的5种打开方式

VS Code设置文件终极指南:全局vs工作区settings.json的5种打开方式 在代码编辑器的世界里,VS Code以其高度可定制性赢得了开发者的青睐。而这份灵活性的核心密码,就藏在settings.json这个配置文件中。想象一下这样的场景:当你需要…...

在Debian 11上为龙芯3A5000手动编译GCC 12.1交叉工具链:我踩过的那些坑和最终脚本

龙芯3A5000交叉工具链深度实战:从源码编译GCC 12.1的完整避坑指南 当国产CPU龙芯3A5000遇上GCC 12.1编译器,一场充满技术细节的深度定制之旅就此展开。不同于直接使用预编译二进制工具链,手动构建交叉编译环境不仅能满足特定优化需求&#xf…...

保姆级教程:用Arduino IDE 1.8.19给ESP32-CAM烧录CameraWebServer(附离线包下载)

ESP32-CAM零基础实战指南:从环境搭建到实时监控一气呵成 当拆开ESP32-CAM包装的瞬间,多数初学者会被这个火柴盒大小的智能摄像头模块震撼——它兼具Wi-Fi连接与图像处理能力,价格却不到百元。但紧接着就会陷入开发环境配置的泥潭:…...

nli-MiniLM2-L6-H768应用场景:HR简历关键词匹配与岗位适配度初筛

nli-MiniLM2-L6-H768应用场景:HR简历关键词匹配与岗位适配度初筛 1. 项目背景与价值 在人力资源招聘场景中,简历筛选是HR每天面临的高频重复性工作。传统人工筛选方式存在效率低下、主观性强、标准不统一等问题。特别是当面对大量应聘者时,…...

UCIe协议栈信号接口实战:手把手教你用FDI和RDI信号调试Chiplet互联

UCIe协议栈信号接口实战:手把手教你用FDI和RDI信号调试Chiplet互联 在当今异构集成的芯片设计浪潮中,Chiplet技术已成为突破摩尔定律瓶颈的关键路径。作为连接不同计算单元的高速通道,UCIe协议的性能直接影响着整个系统的吞吐量和延迟表现。本…...

保姆级教程:用Android Studio 2023.3 + Flutter 3.19 从零搭建开发环境到跑通第一个App

保姆级教程:用Android Studio 2023.3 Flutter 3.19 从零搭建开发环境到跑通第一个App 移动应用开发的世界正在经历一场革命,而Flutter无疑是这场革命中最耀眼的明星之一。作为Google推出的开源UI工具包,Flutter允许开发者使用单一代码库构建…...

别再只盯着参数了!手把手教你为项目选对Intel RealSense D400系列相机(D415/D435/D455对比)

别再只盯着参数了!手把手教你为项目选对Intel RealSense D400系列相机 在机器人导航、工业检测或三维重建项目中,选择一款合适的深度相机往往让人头疼。Intel RealSense D400系列凭借成熟的立体视觉技术和丰富的型号选择,成为许多开发者的首选…...

从零到可视化:用WinCC V7.5给S7-1500 PLC做个简易监控界面(附动画效果)

从零构建动态监控界面:WinCC V7.5与S7-1500 PLC实战指南 在工业自动化领域,可视化监控系统如同工程师的"眼睛",能够实时反映设备状态与工艺参数。本文将带您完成一个污水处理罐监控界面的完整开发流程,从项目创建到动画…...

RH850中断配置避坑指南:从TAUB定时器到CAN通信的实战代码解析

RH850中断配置避坑指南:从TAUB定时器到CAN通信的实战代码解析 在汽车电子和工业控制领域,RH850系列微控制器凭借其卓越的实时性能和丰富的外设资源,成为众多关键系统的首选。中断系统作为实时响应的核心机制,其配置质量直接决定了…...

Prompt Engineering实战:如何用ChatGPT API构建高效提示词模板(附LangChain代码示例)

Prompt Engineering实战:用ChatGPT API构建高效提示词模板 在AI应用开发领域,Prompt Engineering已经从简单的聊天技巧演变为一门系统的工程学科。随着大模型API的普及,如何将零散的提示词转化为可复用的工程组件,成为开发者提升效…...

用Camera2 API实现一个简易抖音拍摄功能:录制、预览与视频保存

用Camera2 API打造短视频拍摄功能:从零实现抖音式交互体验 在移动互联网时代,短视频应用已经成为人们日常生活中不可或缺的娱乐方式。作为Android开发者,掌握如何构建一个高效、流畅的短视频拍摄功能至关重要。本文将带你深入探索如何利用Cam…...

别再死记硬背YOLO的9个anchors了!用Python可视化带你搞懂它在特征图上的调整过程

用Python动态可视化拆解YOLO anchors的调整逻辑 第一次看到YOLO的9个anchors参数时,我盯着那堆数字发呆了半小时——这些宽高组合到底如何影响最终检测框?为什么调整几像素就能让模型性能波动5%?直到我用Matplotlib逐帧绘制了特征图上的坐标变…...

5个专业技巧:掌握Inter字体家族打造完美数字界面体验

5个专业技巧:掌握Inter字体家族打造完美数字界面体验 【免费下载链接】inter The Inter font family 项目地址: https://gitcode.com/gh_mirrors/in/inter Inter字体家族是一款专为现代数字屏幕设计的无衬线字体系统,以其卓越的可读性、丰富的Ope…...

Ai2Psd终极指南:如何彻底解决Illustrator到Photoshop的矢量转换难题

Ai2Psd终极指南:如何彻底解决Illustrator到Photoshop的矢量转换难题 【免费下载链接】ai-to-psd A script for prepare export of vector objects from Adobe Illustrator to Photoshop 项目地址: https://gitcode.com/gh_mirrors/ai/ai-to-psd 你是否曾为Il…...

3分钟掌握ZeroOmega:跨浏览器智能代理管理的终极指南

3分钟掌握ZeroOmega:跨浏览器智能代理管理的终极指南 【免费下载链接】ZeroOmega Manage and switch between multiple proxies quickly & easily. 项目地址: https://gitcode.com/gh_mirrors/ze/ZeroOmega ZeroOmega是一款基于manifest v3标准的开源浏览…...

终极免费打字学习工具:用Qwerty Learner打造你的键盘肌肉记忆系统

终极免费打字学习工具:用Qwerty Learner打造你的键盘肌肉记忆系统 【免费下载链接】qwerty-learner 为键盘工作者设计的单词记忆与英语肌肉记忆锻炼软件 / Words learning and English muscle memory training software designed for keyboard workers 项目地址: …...

鸣潮自动化工具ok-ww:5分钟搞定每日重复任务的终极解决方案

鸣潮自动化工具ok-ww:5分钟搞定每日重复任务的终极解决方案 【免费下载链接】ok-wuthering-waves 鸣潮 后台自动战斗 自动刷声骸 一键日常 Automation for Wuthering Waves 项目地址: https://gitcode.com/GitHub_Trending/ok/ok-wuthering-waves 你是否厌倦…...

保姆级教程:手把手为嵌入式Linux移植NAU8810音频Codec驱动(基于ALSA ASoC框架)

嵌入式Linux音频驱动实战:NAU8810 Codec移植全流程解析 当一块崭新的开发板放在你面前,而客户要求在下周之前完成音频功能的集成时,那种既兴奋又紧张的感觉,相信每个嵌入式工程师都深有体会。NAU8810作为一款高性能低功耗的音频编…...

保姆级教程:在Ubuntu 18.04上为Firefly RK3399 ProC交叉编译Python 3.7.10(含zlib、numpy、pyserial)

嵌入式开发实战:为Firefly RK3399 ProC构建定制Python 3.7环境 当你在Firefly RK3399 ProC开发板上尝试运行Python科学计算脚本时,是否遇到过性能瓶颈或依赖缺失的困扰?不同于x86平台的即装即用,ARM架构的嵌入式设备往往需要从源码…...

从‘炼丹’到‘工程’:复盘InceptionV3论文中那些被验证与‘打脸’的设计(附代码对比)

从‘炼丹’到‘工程’:InceptionV3设计思想的现代验证与技术启示 当我们在2023年回望2015年问世的InceptionV3架构,会发现它像一座横跨深度学习"炼丹时代"与"工程时代"的桥梁。这篇论文最珍贵的遗产不是某个具体模块,而是…...