使用deepwatermap生成的水体二值掩码中有部分区域由于被云挡住无法识别,造成水体不连续是使用jrc离线数据进行修正,jrc数据下载连接如下:https://global-surface-water.appspot.com/download
选择指定区域的数据集合下载如图:
使用开源项目deepwatermap生成tiff格式的水体二值掩码图(需要把原本的png水体图进行转成tiff格式使用gdal把原始的坐标迁移过去)弄好之后开始对水体中非连续的水体使用jrc文件补全。
修正的代码如下:
import numpy as np
import rioxarray as rxr
from rasterio.enums import Resampling
def update_water_classification(target_path, output_path, water_threshold=2.5,
jrc_path='occurrence_90E_30Nv1_4_2021.tif'):
# 加载目标影像(含水体掩膜)
ZB_target = rxr.open_rasterio(target_path, masked=True).squeeze()
# 加载JRC水体发生频率数据作为ZB
ZB = rxr.open_rasterio(jrc_path, masked=True).squeeze()
# 将ZB重新投影到目标影像的CRS,并重采样以匹配空间分辨率
ZB_resampled = ZB.rio.reproject_match(ZB_target, resampling=Resampling.bilinear)
#生成临时文件 仅用来测试jrc是否依据水体掩码进行重采样到相同大小
# ZB_resampled = genTempTiffFile(ZB_resampled)
# 创建一个新的掩码用于保存更新后的数据
updated_mask = ZB_target.copy() # 复制原始掩码作为基础
# 找出需要更新的非水体像素位置(即值为0的位置)
non_water_pixels = ZB_target.values == 0
# 更新非水体区域:如果对应的ZB_resampled值大于等于water_threshold,则设为1(水体)
# 使用布尔索引避免在同一数组上读写
updated_mask.values[non_water_pixels] = np.where(
ZB_resampled.values[non_water_pixels] >= water_threshold,
1,
0
)
# 保存最终结果
updated_mask.rio.to_raster(output_path)
print("Process completed.")
def genTempTiffFile(ZB_resampled):
# 保存重采样后的JRC数据到临时文件
# 设置一个新的数据类型和默认的nodata值
new_dtype = 'float32' # 或者其他适当的数据类型
if np.issubdtype(new_dtype, np.floating):
default_nodata = -9999.0 # 浮点类型的默认nodata值
else:
default_nodata = np.iinfo(new_dtype).min # 整数类型的默认nodata值
# 确保nodata值在新的数据类型范围内
if 'nodata' in ZB_resampled.attrs:
original_nodata = ZB_resampled.attrs['nodata']
if not np.issubdtype(type(original_nodata), np.number) or not (
np.iinfo(new_dtype).min <= original_nodata <= np.iinfo(new_dtype).max):
print(
f"Warning: nodata value {original_nodata} out of range for dtype {new_dtype}. Adjusting nodata value.")
original_nodata = default_nodata
else:
original_nodata = default_nodata
print("No nodata value found. Using default nodata value.")
# 设置新的nodata值并转换数据类型
ZB_resampled = ZB_resampled.rio.write_nodata(original_nodata)
ZB_resampled = ZB_resampled.astype(new_dtype)
ZB_resampled.rio.to_raster("resampled_jrc.tiff", dtype=new_dtype, nodata=original_nodata)
print(f"Resampled JRC data saved to resampled_jrc")
return ZB_resampled
# if __name__ == '__main__':
# jrc_file = "occurrence_90E_30Nv1_4_2021.tif"
# target_tiff = "D:/s2/L2A_T46RFS_A026142_20220309T042244_merged_cropped_binary_watermask.tiff"
# output_tiff = target_tiff.replace('_merged_cropped_binary_watermask.tiff',
# '_merged_cropped_binary_watermask_jrc.tiff')
# update_water_classification(target_tiff, output_tiff)
# print("影像处理完成并已保存")
在此记录一下!希望可以帮到需要的朋友!