fix(sr2rgb): 添加转换前后对NoData值的处理.

This commit is contained in:
谢泓 2026-01-07 11:51:31 +08:00
parent eeed789d5b
commit a4c81d0813

View File

@ -24,7 +24,10 @@ gdal.UseExceptions()
def normalize_band(
band: np.ndarray, method: str = "minmax", percentile: float = 2.0
band: np.ndarray,
method: str = "minmax",
percentile: float = 2.0,
nodata: Optional[float] = None,
) -> np.ndarray:
"""
将波段数据归一化到 0-255 uint8
@ -37,16 +40,22 @@ def normalize_band(
归一化方法 ('minmax', 'percentile', 'clip'), by default "minmax"
percentile: float, optional
百分比截断参数 (仅用于 'percentile' 方法), by default 2.0
nodata: float, optional
NoData , 如果不为 None, 则将该值替换为 NaN, by default None
"""
band = np.asarray(band, dtype=np.float32)
# 处理 NoData 值
if nodata is not None:
band[np.isclose(band, nodata)] = np.nan
if method == "clip":
# 对应原 render8bit 逻辑: 直接截断并转换
# 直接截断并转换
band[~np.isfinite(band)] = 0.0
return np.clip(band, 0.0, 255.0).astype(np.uint8)
if method == "percentile":
# 对应原 linear_stretch 逻辑
# 百分比截断并线性拉伸
lower = np.nanpercentile(band, percentile)
upper = np.nanpercentile(band, 100 - percentile)
else: # minmax
@ -59,6 +68,8 @@ def normalize_band(
return np.zeros_like(band, dtype=np.uint8)
stretched = (band - lower) / (upper - lower) * 255.0
# 处理拉伸后的 NaN 值 (原始数据中的 NaN 会传播)
stretched[~np.isfinite(stretched)] = 0.0
return np.clip(stretched, 0, 255).astype(np.uint8)
@ -107,9 +118,12 @@ def render_image_rgb(
chans = []
for b in bands:
band = ds.GetRasterBand(int(b))
nodata = band.GetNoDataValue()
arr = band.ReadAsArray(0, 0, xsize, ysize)
chans.append(
normalize_band(arr, method=normalization_method, percentile=percentile)
normalize_band(
arr, method=normalization_method, percentile=percentile, nodata=nodata
)
)
rgb = np.dstack(chans)
@ -134,6 +148,7 @@ def render_image_rgb(
ds = None
Image.fromarray(rgb, mode="RGB").save(png_path, format="PNG")
print(f"已完成RGB图像转换, 保存至: {png_path}")
return png_path
@ -216,7 +231,7 @@ if __name__ == "__main__":
# combine_bands_to_rgb(red_path, green_path, blue_path, output_path)
imgs_dir = Path(r"D:\CVEOProjects\prjaef\aef-backend-demo\media\imgs")
region_name = "Target3"
region_name = "Target4"
year = 2025
img_name = f"S1_S2_{region_name}_{year}.tif"
img_tif_path = imgs_dir / region_name / img_name