遥感影像深度学习样本对制作教程2——根据云含量筛选影像块

本文结合实例详细讲解了如何使用Python制作遥感影像深度学习样本对,关注公众号GeodataAnalysis,回复20230430获取示例数据和代码,上一章和这一章的代码和数据都在一起。

在利用遥感影像训练深度学习模型时,影像中的云会对模型的训练造成影像,比如土地覆盖分类等操作在训练前肯定要进行筛选,把有云的影像块去掉,再制作标签。当然,如果是训练去云或云检测模型,那么操作正好相反,有云的影像块才是需要保留的。

上一篇文章中,我们提取了训练模型所需的各个影像块的信息,现在就以提取每个影像块的云含量为例演示一下具体可以怎么使用这些信息。

本次示例使用landsat 8的QA波段判断一个像元是否被云覆盖,如果你用的是其他数据(没有QA波段,比如哨兵),那么先用原始数据做一下云掩膜即可。

1 导入必须的几个模块

其中unpackqa是用来解析landsat 8的QA波段的。

import os
import unpackqa
import numpy as np
import pandas as pd
import rasterio as rio
from rasterio.windows import Window

2 读取影像块信息

stat_df = pd.read_csv('./patchs.csv')
stat_df.head()

3 打开影像,方便后续调用

需要注意,这里说的打开影像只是获取了这景影像的读取接口,并不是把这幅影像的数据读入内存。

id_srcs = {
    
    }
data_dir = './data'
for id in stat_df['id'].unique():
    id_path = os.path.join(data_dir, id, id+'_QA_PIXEL.TIF')
    if os.path.exists(id_path):
        id_srcs[id] = rio.open(id_path)

4 提取每个影像块的云和阴影含量

首先定义一个可以根据影像块的信息计算云和阴影含量的函数。上一篇文章用的输入数据和标签都为landsat8,实际应用中标签可能不需要计算云含量(除非是去云或云检测),这时可以在下面的函数中加一个判断,如果这个影像块是标签,直接返回0即可,如6-7行代码所示。

# 数据产品的名字,示例数据为C2 L2级别的landsat 8
L8_qa_product = 'LANDSAT_8_C2_L2_QAPixel'

# 获取每个影像块的云含量,输入为dataframe的一行
def cloud_and_shadow_cover(patch):
    if patch.type == 'label':
        return 0
	# 读取这个影像块对应的QA波段的值
    src = id_srcs[patch.id]
    win = Window.from_slices((patch.row, patch.row+patch.image_size), 
                             (patch.col, patch.col+patch.image_size))
    patch_array = src.read(1, window=win)

	# 解析QA波段,计算哪些像元为云或阴影,是的话返回True
    mask = unpackqa.unpack_to_array(patch_array, 
                                     product=L8_qa_product, 
                                     flags=['Cloud','Cloud_Shadow'])
    mask = np.any(mask, axis=-1)

	# 返回这个影像块的云和阴影所占的比例
    return np.count_nonzero(mask) / mask.size

调用这个函数,计算每个影像块的云和阴影含量。

stat_df['cs_cover'] = stat_df.apply(cloud_and_shadow_cover, axis=1)
stat_df.head()

5 筛选

以下代码用于筛选影像块,thre1thre2分别是输入和标签的云含量阈值,你可以自行设置阈值,以及云含量是要大于、小于、还是等于这个阈值。

thre1, thre2 = 0.01, 0.01
img_mask = stat_df.loc[stat_df['type']=='img', 'cs_cover']>thre1
label_mask = stat_df.loc[stat_df['type']=='label', 'cs_cover']>thre2
mask = np.all([img_mask, label_mask], axis=0)
mask = np.vstack((mask, mask)).T.flatten()

df1 = stat_df.loc[mask, :]

猜你喜欢

转载自blog.csdn.net/weixin_44785184/article/details/130452500