02-Sentinel-2 L1C级数据bat和Python脚本批量大气校正


(原创文章,转载请注明来源,谢谢!)

前言

本文为《SNAP与snappy》专栏第2篇博文。尽管2018年后期后开始,欧空局提供了全球范围的Sentinel-2 L2A级产品,但是在此之前Sentinel-2 L2A的数据只有欧洲范围区域才有L2A级产品。此外,博主发现欧空局似乎不会将云量比较大(Sentinel-2 成像自带检测云量的算法)的L1C处理成L2A级产品,尽管多数情况下,我们的确不需要云量过量的产品。另外,之前,看到中科院遥感卫星地面站陈甫同志的一篇文章,提到欧空局发布的Sentinlel-2 L2A级产品可能存在一些问题,至于是不是这样,很难判断。不管怎样,使用Sentinel-2数据还是有必要知道一下L2A产品的生成方法。

Sentinel-2 L1C数据大气校正方法

Sentinel- 2L1C级数据是欧空局直接提供给我们可以下载的数据。其大气校正用的大多数是欧空局自身提供的开源大气校正插件Sen2Cor,它是Sentinel-2 L2A产品生成和格式化处理器。

Sen2cor对Sentinel-2 L1C级大气输入数据进行大气、地形和卷云校正。Sen2Cor创建底部大气,可选地形和卷云校正反射图像;此外,还会创建气溶胶光学厚度,水汽,场景分类地图和带有质量指标性质的云和雪概率掩膜图像。其输出的产品格式和L1C级用户产品格式相同:JPEG 2000格式图像,三种不同的分辨率,60、20和10 m。

在大气校正前,希望你一些能对Sentinel-2 L1C数据有些基本认识:
Sentinel-2 L1C级产品标准产品覆盖范围为100平方公里,为经过UTM/WGS84投影正射影像组成。L1C级产品影像在正射校正时使用数字高程模型(DEM)投影至制图坐标下。其为大气层顶部( Top of Atmosphere , TOA)的反射率影像,不过也记录了处理为L1C产品每个像素的辐射测量的相关信息。L1C级产品根据不同光谱波段的分辨率,以10、20和60 m的固定地面采样距离( Ground Sampling Distance ,GSD)重新采样。在Level-1C产品中,像素原点是指影像的左上角。L1C级产品还将包括陆地/水、云掩膜数据和ECMWF数据(臭氧总量、水蒸气总量和平均海平面压力)

关于Sentinel-2数据各个波段的介绍在网上已有较多的资料,不再过多赘述了,这里粘贴一个:https://blog.csdn.net/qq_41718357/article/details/83536322

下面进入正题。

单个Sentinel-2 L1C数据大气校正

关于Sentinel-2单个数据集的Sen2Cor(目前的版本为V2.8)安装及大气校正教程,网上已有众多教程资料。

L1C数据经过Sen2cor校正后的是L2A产品, L2A级产品提供了来自相关L1C级产品的大气底部(Bottom Of Atmosphere , BOA)反射率图像。因此,每个L2A级产品也由100平方公里的地图几何瓦片(UTM/WGS84投影)影像组成。

以Win10系统为例,其它系统操作是类似的。

扫描二维码关注公众号,回复: 9213356 查看本文章

命令行方式调用Sen2Cor校正

Windows下的命令行方法,比较详细的及校正方法可以参考以下文章:
松果儿 知乎专栏《Sentinel影像》----Sen2Cor (V2.8)——哨兵二号的预处理
Melody sugar知乎专栏《环境遥感学习之路》----【Sentinel-2】(2):哨兵2号数据预处理
还有上面的csdn博客。

SNAP中利用Sen2Cor插件校正

如果你不喜欢命令行方式校正的,可以添加Sen2Cor,在图形用户界面(GUI)进行校正。利用GUI界面进行校正可以精确地设置各种参数,但其本质还是通过调用Sen2Cor的命令行脚本L2A_Process.bat来做处理的。

Sen2cor插件安装:

打开SNAP后,点击Tools---->Plugins可以查看相关插件信息。
在这里插入图片描述
选中Available Plugins,可以看到SNAP提供的Sen2Cor插件 V2.8.0和V2.5.5。勾选前面的勾。
在这里插入图片描述
点击install即可非常方便。安装后可以在Optial---->Thematic Land Processing---->Sen2Cor Processor找到Sen2Cor V2.8.0和V2.5.5。需要用哪个就选哪个。
在这里插入图片描述你可能好奇,下载的插件放在哪里了。可以再以下路径找到它们(路径中的红色部分为你的电脑用户名):在这里插入图片描述
知道这个默认安装路径比较重要,后面需要用到这个路径。

以Sen2Cor V2.8.0为例,对一副Sentinel-2 L1C级数据影像进行大气校正:
点击I/O Parameters选择源数据:
在这里插入图片描述点击Processing Parameters可以看到众多参数:
在这里插入图片描述如果你了解6S大气校正方法的的话,应该能认出一些参数,这里不会介绍具体的算法原理,也不讲具体的参数设置,因为博主这方面也是比较弱,如果你想看这些参数的意义请看帮助(Help),或者查看Sen2Cor的用户手册
对于我们来说,一般只需要设置分辨率这个选项就足够了。分辨率有四种选择,分辨率分别是10m, 20m, 60m,All。如果你选择60m,那么大气校正时会将所有波段(包括高于60m的10m和20m的波段)重采样(降采样)为60m的结果;如果你选择的是20m,那么大气校正时会将10m和20m的波段重采样(降采样)为20m,60m的分辨率保持不变;如果你选择的是10m分辨率,原有的10m波段仍是10m波段,此外,20m和60m的波段仍然是20m和60m(如果你想看看是否这样,建议你三个分辨率都试试看);选All的话,那个会保持原来的L1C数据分辨率(实际效果和选择分辨率为10m的结果差不多)。【一个规律就是原来高分辨率的影像会降采样为低分辨数据】。
在这里插入图片描述
这里的分辨率选择的是All,保持原有的L1C分辨率,同时勾选左上角的Display Execution output选项,下方会出现一个黑框(实际上是命令行窗口),以显示校正过程及结果。如下图:
在这里插入图片描述
点击右下角的run,就开始大气校正了。运行过程图:
在这里插入图片描述
大气校正耗费的时间与你的电脑配置过程有关,大概处理一个数据需要15-30分钟。
处理完成后的示意图:
在这里插入图片描述

Sentinel-2 L1C数据集批量大气校正

好了,终于进入主题了,尽管网上也有少量的Sentinel-2
L1C级数据Sen2cor大气校正批处理的教程,然而大多数教程,都是“浅尝辄止”的程度,“知其然而不知其然也”!

命令行bat脚本批处理

首先,你需要知道Sen2Cor这个插件其实主要是用Python代码(核心运算应该是C语言)写。我们先找到L2A_Process.bat的脚本的位置(如果你是用SNAP以插件的方式安装Sen2Cor,那么会出现在下图所示的路径中,红色部分为你的用户名),然后可以用记事本打开L2A_Process.bat的脚本查看它的命令。
在这里插入图片描述选中L2A_Process.bat,点击鼠标右键,选择编辑。

在这里插入图片描述可以看到bat脚本的命令(如果你不懂bat命令的话,请不要改动任何代码,以免bat脚本出错),我不会解释这里bat命令的具体意思,但是我标记了这个bat核心代码(蓝色背景文本),希望引起你的注意:
在这里插入图片描述
实际上,调用的L2A_Process.py文件(Python源代码,不要改动其中的代码)。这个代码位于Sen2Cor文件夹Lib\site-packages\sen2cor文件夹:
在这里插入图片描述这个L2A_Process.py代码也是比较复杂(反复调用了多个python程序),博主也没有完全弄明白,如果你弄明白的话,Please dai dai me!

低配版命令行bat脚本批处理

希望前面操作能让你有一些感性认识。好了,进入正题。仍然以Sen2Cor V2.8.0为例,其相关命令为:
在这里插入图片描述
尽管有很多参数命令,但是执行是需要的命令极少。
一般是:L2A_Process.bat <数据集必须是.SAFE为后缀的格式,不能是.zip>
当然在后面还可以添加额外的参数。

整个程序的逻辑非常简单,就是找到输入数据集中的.SAFE(L1C级数据集)然后调用L2A_Process.bat 处理该数据集。

先给出弱化版Sen2Cor_weak.bat的代码:

@echo off
rem 设置脚本标题名为: Sentinel-2A L1C批量大气校正处理bat脚本
title Sentinel-2A L1C批量大气校正处理bat脚本

rem 设置Sen2cor所在目录变量
set "Sen2cor_bin=C:\Users\XXXXXX\.snap\auxdata\Sen2Cor-02.08.00-win64"

rem 设置数据所在目录文件
set "input_dir=G:\test"

rem 设置输出文件夹
set "output_dir=G:\test"

for /d  %%i in  (%input_dir%\S2*.SAFE ) do ( 
	rem 调用Sen2cor 文件对其做大气处理
	%Sen2cor_bin%\L2A_Process.bat %%i --output_dir=%output_dir% 
	echo "-------------------------------分割线---------------------------------"
)
echo "恭喜!所有相关文件处理完成!"

我简单解释一下这个代码:

  • rem命令表示该行是注释行;
  • echo命令相当于print,显示输出语句;
  • set命令用于设置变量;
  • for /d %%i in (%input_dir%\S2*.SAFE)表示的是找到以S2开头,以.SAFE后缀结尾的文件夹(/d)。
  • %Sen2cor_bin%\L2A_Process.bat %%i --output_dir=%output_dir% 是核心的处理代码,调用L2A_Process.bat脚本处理数据集%%i,%output%表示的是输出文件夹,这里没有设置分辨率参数(–resolution),你可以在这行命令加上。

要是使用上述bat脚本需要作几个调整:

  • “Sen2cor_bin=C:\Users\XXXXXX.snap\auxdata\Sen2Cor-02.08.00-win64”(加引号的目的是为了防止路径有空格,命令行不能识别) 需要将等号后面的路径(注意最后面处没有斜杆“\”)修改为你自己Sen2Cor安装的路径
  • “input_dir=G:\test” 需要将等号后面的路径(注意最后面处没有斜杆“\”)修改为你的数据集所在路径(注意数据集必须为.SAFE格式)
  • “output_dir=G:\test” 如果需要,可以将等号后面的路径(注意最后面处没有斜杆“\”)修改为你要保存校正后的数据集所在目录路径

新建一个.txt文件,然后复制上述代码命令,修改相应三个的路径,确认无误后,给它一个合适的名字,然后把后缀.txt改为.bat(例如博主的Sen2Cor_weak.bat)。
再强调一次,数据集目录下需要是.SAFE格式的文件(如果不是.SAFE文件需要自己解压出来),否则,可能会报错,提示找不到文件
在这里插入图片描述修改后bat脚本命令后,可以启动Windows PowerShell执行Sen2Cor_weak.bat脚本或者使用命令行(cmd)执行bat脚本。
在输入数据目录打开Windows PowerShell:
在这里插入图片描述
注意,在Windows PowerShell运行bat脚本等程序需要在前面添加“.\”。成功运行的效果图:
在这里插入图片描述
大概处理一个数据集需要15-30分钟。

如果你想学习更多的bat脚本知识,在网上有众多的教程资料,这里粘贴一个(提前说一下,广告比较多,但是bat的基础内容是比较全的):
https://www.jb51.net/article/151923.htm

高配版命令行bat脚本批处理

高配版bat代码,处理的数据集是:下载下来默认格式为的.zip格式的Sentinel-2 L1C数据集。但是需要好压这个压缩软件的支持,可以是别的解压软件。注意,这个程序代码只适用于安装有好压这个软件的windows系统电脑

整个程序的逻辑也是很好懂的,就是找到.zip数据集下的某个.zip文件,然后调用好压提供的命令行工具(HaoZipC.exe)解压生成.SAFE格式的数据,然后调用L2A_Process.bat对其做大气校正。

@echo off
rem 设置脚本标题名为Sentinel-2A L1C批量大气校正处理bat脚本
title Sentinel-2A L1C批量大气校正处理bat脚本

rem 设置好压命令行工具所在目录变量
set "Haozip_bin=E:\Program Files\2345Soft\HaoZip"

rem 设置Sen2cor所在目录变量
set "Sen2cor_bin=C:\Users\lidahui\.snap\auxdata\Sen2Cor-02.08.00-win64"

rem 设置输入文件夹
set "input_dir=G:\test"

rem 设置输出文件夹
set "output_dir=G:\test"

for /r %input_dir% %%i in  (S2*.zip ) do (
	echo %%i
	rem 解压文件部分
	"%Haozip_bin%\HaoZipC.exe" x -bd -o%output_dir%  %%i
	rem 换行并打印一条分割线,分隔解压和大气校正信息
	echo.
	echo "---------------------------------分割线------------------------------------"
	
	rem 把文件名后缀.zip换为.SAFE(因为Sen2cor只能识别.SAFE格式的文件夹)
	echo  %%~dpni.SAFE
	rem 调用Sen2cor 文件对其做大气处理
	%Sen2cor_bin%\L2A_Process.bat %%~dpni.SAFE --output_dir=%output_dir%
	rem 换行并打印一条分割线,分隔解压和大气校正信息
	echo.
	echo "---------------------------------分割线------------------------------------"
)
echo "恭喜!所有相关文件处理完成!"

如果你装有好压这个软件,可以试下上面的bat脚本。
要是使用上述bat脚本需要作几个调整:

  • “Haozip_bin=E:\Program Files\2345Soft\HaoZip”(加引号的目的是为了防止路径有空格,命令行不能识别)需要将该路径(注意最后面处没有斜杆“\”)修改为你安装的好压命令行HaoZipC.exe所在的路径。
  • “Sen2cor_bin=C:\Users\XXXXXX.snap\auxdata\Sen2Cor-02.08.00-win64” 需要将等号后面的路径(注意最后面处没有斜杆“\”)修改为你自己的Sen2Cor安装路径
  • “input_dir=G:\test” 需要将等号后面的路径(注意最后面处没有斜杆“\”)修改为你的数据集所在路径(注意这次的数据集为.zip格式)
  • “output_dir=G:\test” 如果需要,可以将等号后面的路径(注意最后面处没有斜杆“\”)修改为你要保存校正后的数据集所在目录路径。

博主的好压(Haozip)软件命令行工具(HaoZipC.exe)位于:
在这里插入图片描述
新建一个.txt文件,然后复制上述代码命令,修改相应四个的路径,确认无误后,给它一个合适的名字,然后把后缀.txt改为.bat(例如博主的Sen2Cor_strong.bat)。
如果你想看HaoZipC.exe的命令,可以在Windows PowerShell下执行“.\HaoZipC.exe -h”。
在这里插入图片描述
博主不会介绍HaoZipC.exe的相关命令,如果你还需要帮助,可以看好压网站的命令行命令介绍:http://haozip.2345.cc/help/help11-1.htm

确保输入数据集含有.zip格式的Sentinel-2 L1C数据集文件,如图:
在这里插入图片描述
修改后bat脚本命令后,可以在当前数据集路径下启动Windows PowerShell执行Sen2Cor_strong.bat脚本或者使用命令行(cmd)执行bat脚本,执行效果图:
在这里插入图片描述
处理后,解压生成的L1C级数据也会存在,大概处理一个数据集需要15-30分钟。

Python脚本批处理

终于到了Python版了,如果不喜欢在命令行下敲命令,又不愿意使用好压(HaoZip)。那个可以考虑一下Python,Python也可以调用命令行工具做处理,并且自动打开,自动关闭。

这个Python脚本程序处理的数据集仍然是:下载下来默认格式为的.zip格式的Sentinel-2 L1C数据集。不需要好压软件的支持,直接用Python的标准库zipfile来解压。

该程序的逻辑和高配版bat脚本是相同的,就是找到.zip数据集下的某个.zip文件,然后调用好压提供的命令行工具(HaoZipC.exe)解压生成.SAFE格式的数据,然后调用L2A_Process.bat对其做大气校正。

Python代码(不知道缩复制过来进有没有问题,最好自己检查一下)如下:

# 使用Python标准库调用Sen2cor命令行命令批量对Sentinel-2 L1C数据进行大气校正
import subprocess
import zipfile
import os

#定义一个解压函数
def unzip_file(zip_file_name, mode='rb'):
    """
    Return a unzipped file name which comes from the zipped file of A Sentinel-2 L1C data
    返回Sentinel-2 L1C级.zip文件解压后的文件名
    zip_file_name   - the zipped file name of A Sentinel-2 L1C data  
    mode            - Optional parameter, the mode of the zipped file reader 
    """
    #打开.zip文件
    zip_file = open(zip_file_name, mode)
    #利用zipfile包解压文件
    zip_fn = zipfile.ZipFile(zip_file)
    #获取.zip文件的所有子目录名和文件名
    namelist = zip_fn.namelist()
    for item in namelist:
        #提取.zip文件的子目录及文件,解压在当前文件夹('.'表示当前文件夹)
        zip_fn.extract(item, '.')
    #关闭.zip文件
    zip_fn.close()
    zip_file.close()    
    #打印解压完成
    print("Unzipping finished!")
    #返回解压后的文件名(字符串,带.SAFE后缀)
    return namelist[0]
       
#Sen2cor.bat文件所在路径
sen2cor_path = r"C:\Users\XXXXXX\.snap\auxdata\Sen2Cor-02.08.00-win64\L2A_Process.bat"
#Sentinel-2 L1C原始数据(.zip格式文件,无需解压)所在目录
origin_dir = r"G:\test"
#文件模式
pattern = ".zip"
#输出目录
output_dir = r"G:\test"

for in_file in os.listdir(origin_dir):
    # 判断是否是.zip文件
    if pattern in in_file:
        #获取.zip文件的完整路径
        zip_file_path = os.path.join(origin_dir, in_file)
        #解压.zip文件,产生.safe格式文件
        safe_in_file_path = unzip_file(zip_file_path)
        #设置Sen2cor命令行参数,按照原始分辨率处理
        cmd_args = [sen2cor_path, safe_in_file_path, \
                    '--output_dir', output_dir]
        
        #打印处理开始的消息
        print("{} processing begin!".format(safe_in_file_path))
        #传入命令行参数并调用命令行(cmd)执行命令
        subprocess.call(cmd_args)
        #打印处理完成的消息
        print("{} processing finished!\n".format(safe_in_file_path))

#打印所有文件处理完成的消息
print("All zipped file finished!") 

我不会解释上面的代码,但我强调一下使用时需要修改的部分,仍然是路径。

  • sen2cor_path = r"C:\Users\XXXXXX.snap\auxdata\Sen2Cor-02.08.00-win64\L2A_Process.bat", “”引号内的路径修改为你自己的Sen2Cor安装路径(注意最后面没有斜杆“\”),前面r保留(取消转义字符下同)
  • origin_dir = r"G:\test", “”引号内的路径修改你的数据集所在路径(注意最后面没有斜杆“\”,这次的数据集仍为.zip格式),前面r保留
  • output_dir = r"G:\test"“”引号内的路径修改为你要保存校正后的数据集所在目录路径(注意最后面没有斜杆“\”),前面r保留

复制上述Python代码,修改对应的路径,命名然后执行上述Python代码,Python会打开一个命令窗口(请不要手动关闭,处理完会自动关闭)执行效果图如下:
在这里插入图片描述
处理后,解压生成的L1C级数据也会存在,大概是15-30分钟一个数据集。如果你的数据数量很大,还是要等一段时间的(可以看下电影、电视剧等消磨时间)。

校正前后对比结果

以先前用SNAP中的Sen2cor插件处理好的两个影像为例,先打开Output Product真彩色影像(L2A产品)。鼠标左键单击选择Output Product,再右键单击,选择Open RGB Image Window:
在这里插入图片描述默认就是真彩色合成图,保持默认就行,如果你想看彩红外(假彩色合成图)影像可以下拉选择,False-color Infrared那个选项。点击OK就行。
在这里插入图片描述
等待片刻,即可看到真彩色图像,同理可以看到打开L1C级数据如图(注意观察红圈里的数字,这里指示的是哪个数据集):
在这里插入图片描述
可以分隔两个窗口,以同时显示两个数据集,选择Window ----> Tile Horizontally(水平分隔),注意左下角大红色圈部分选择导航示意图。勾选一下再往下大的两个红色圈(一个是逐像素关联,一个是鼠标指示器关联,即是鼠标箭头),往上一个方框里的A是缩放到全图(All)之意,P是缩放到像素(Pixel)分辨率之意。或者你点下下方的问号"?"可以看到帮助。
在这里插入图片描述
点一下红色框的A,缩放至全图:
在这里插入图片描述
初看,感觉差别不明显。实则非也!需要看单个像元的比较。下面查看波谱图来进行对比。
利用导航工具(红色圈部分)缩放到某处:

在这里插入图片描述
利用工具栏红色圈的大头针(Pin)添加标记点Pin 1(大红圈),如图:

在这里插入图片描述
我们需要将左图的大头针复制至右图,先调出大头针管理器(选择View---->Tool Windows---->Pin Manager):
在这里插入图片描述可以看到下方出现了,Pin Manage窗口,选择右下方的红色圈,将其大头针复制到右图:
在这里插入图片描述
勾选要复制的到的数据源,点击OK。
在这里插入图片描述
可以看到Pin1成功从左图复制到右图。
好的,只差最后一步了——查看波谱图。
选择Optial---->Spectrum View:

在这里插入图片描述
选择下图红色圈的标记,即可以看到左图(其图像边界有浅黄色背影)的Pin1(水体)波谱图。
在这里插入图片描述
只需将鼠标按右图点击一下,即可以看到右图(其图像边界有浅黄色背影)Pin1(水体)的波谱图:

在这里插入图片描述可以看到他们之间的数值,乃至曲线趋势都存在明显的区别。因此,无论是对Sentinel-2做任何后续分析处理工作,大气校正都是必要的。建议你再标准的水体光谱曲线对比一下,这里,肯定会有差别(受河流泥沙量、叶绿素等因素影响)。事实,Sen2Cor大气校正的处理效果是很好的。不然,欧空局不会选择它,而且它要对全球用户负责,显然,要经得起检验。

你可以看一下前面提到的知乎专栏《环境遥感学习之路》中关于植被光谱的检验:Melody sugar知乎专栏《环境遥感学习之路》----【Sentinel-2】(2):哨兵2号数据预处理

后语

可能大气校正的批处理编写的方式,不至一种,博主也只是提供了一些参考的依据。说实话,要对遥感影像做精确的大气校正难度很大,写一个大气校正底层程序更是困难,博主对自主开发底层遥感数据处理程序的人员是非常尊敬的!最后,还是提一句,如果你对SNAP或者snappy感兴趣的话可以加入博主创建的欧空局SNAP处理交流QQ群:665903216

参考文献

[1] Sentinel-2 用户手册:https://sentinel.esa.int/documents/247904/685211/Sentinel-2_User_Handbook
[2] 松果儿 知乎专栏《Sentinel影像》----Sen2Cor (V2.8)——哨兵二号的预处理
[3] Melody sugar知乎专栏《环境遥感学习之路》----【Sentinel-2】(2):哨兵2号数据预处理
[4] shub0829 CSDN博客----哨兵2号(sentinel-2)介绍、下载和预处理、批处理
[5] Sen2Cor V2.8.0的用户手册

发布了11 篇原创文章 · 获赞 51 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/lidahuilidahui/article/details/99947811