You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用JPG掩码+无云影像实现TIFF卫星数据去云?求Python方案

卫星影像去云解决方案(基于Rasterio/skimage)

前提说明

需确保三幅影像的空间范围、分辨率、波段数完全匹配。若存在偏差,需先完成影像配准操作,否则替换后会出现错位问题。


方案一:基于Rasterio实现(推荐,支持地理元数据保留)

Rasterio专为地理栅格数据设计,能自动保留影像的坐标系统、投影等地理信息,适合专业卫星影像处理。

代码实现

import rasterio
import numpy as np

# 替换为你的文件路径
cloudy_tif = "cloudy_image.tif"
cloud_mask_jpg = "cloud_mask.jpg"
clear_tif = "clear_image.tif"
output_tif = "denoised_result.tif"

# 读取含云影像及元数据
with rasterio.open(cloudy_tif) as src_cloudy:
    cloudy_arr = src_cloudy.read()  # 数组形状:(波段数, 高度, 宽度)
    save_profile = src_cloudy.profile  # 用于保存结果的元数据模板

# 读取无云影像
with rasterio.open(clear_tif) as src_clear:
    clear_arr = src_clear.read()

# 读取云掩码(JPG灰度图取单通道)
with rasterio.open(cloud_mask_jpg) as src_mask:
    mask_arr = src_mask.read(1)
    # 生成云区布尔掩码:黑色像素(值为0)标记为True
    cloud_mask = mask_arr == 0

# 校验尺寸一致性
assert cloudy_arr.shape == clear_arr.shape, "含云与无云影像的波段数/尺寸不匹配"
assert cloud_mask.shape == cloudy_arr.shape[1:], "掩码与影像的高度/宽度不匹配"

# 替换云区像素:遍历每个波段,用无云影像覆盖云区
denoised_arr = cloudy_arr.copy()
for band_idx in range(cloudy_arr.shape[0]):
    denoised_arr[band_idx][cloud_mask] = clear_arr[band_idx][cloud_mask]

# 保存去云结果
with rasterio.open(output_tif, 'w', **save_profile) as dst:
    dst.write(denoised_arr)

注意事项

  • 若JPG掩码因压缩导致黑色像素值不是严格的0,可调整阈值为mask_arr < 10(根据实际情况微调)
  • 所有影像的投影、分辨率必须一致,否则替换后会出现空间错位

方案二:基于skimage实现(适合无地理元数据需求的场景)

skimage专注于通用图像处理,操作简洁,但无法直接处理地理元数据,适合已完成配准的影像。

代码实现

from skimage.io import imread, imsave
import numpy as np

# 替换为你的文件路径
cloudy_tif = "cloudy_image.tif"
cloud_mask_jpg = "cloud_mask.jpg"
clear_tif = "clear_image.tif"
output_tif = "denoised_result.tif"

# 读取影像:skimage读取TIFF为(高度, 宽度, 波段数)格式
cloudy_arr = imread(cloudy_tif)
clear_arr = imread(clear_tif)
# 读取掩码并转为灰度图
mask_arr = imread(cloud_mask_jpg, as_gray=True)

# 生成云区布尔掩码
cloud_mask = mask_arr == 0

# 校验尺寸一致性
assert cloudy_arr.shape == clear_arr.shape, "含云与无云影像的波段数/尺寸不匹配"
assert cloud_mask.shape == cloudy_arr.shape[:2], "掩码与影像的高度/宽度不匹配"

# 适配多波段影像:将掩码扩展为(高,宽,1)维度,与影像通道匹配
if len(cloudy_arr.shape) == 3:
    cloud_mask = np.expand_dims(cloud_mask, axis=-1)

# 替换云区:云区用无云影像填充,非云区保留原影像
denoised_arr = np.where(cloud_mask, clear_arr, cloudy_arr)

# 保存结果:需保持与原影像一致的数据类型(如uint8、uint16)
imsave(output_tif, denoised_arr.astype(cloudy_arr.dtype))

注意事项

  • skimage读取TIFF的通道顺序为(H,W,C),与Rasterio的(C,H,W)不同,需注意数组维度差异
  • 若需要保留地理元数据,建议结合Rasterio读取/保存影像,仅用skimage完成像素替换操作

内容的提问来源于stack exchange,提问作者Salvatore Danilo Palumbo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 01:05:20