fix: 影像预览图GDAL buf降采样防OOM

- 预览图不再整幅读入 34914x19177x3 float32(~7.5GiB),按 MAX_PREVIEW_DIM=2048 buf 降采样
- 耀斑单波段掩膜 RGB 白色由 255 改为 1.0,消除 imshow clipping 警告
This commit is contained in:
duxin
2026-09-08 17:26:18 +08:00
parent 4d49753cca
commit 81ae400294

View File

@ -580,19 +580,33 @@ class WaterQualityVisualization:
height = dataset.RasterYSize
band_count = dataset.RasterCount
# ★ 预览只用于看图:超过 _MAX_PREVIEW_DIM 的影像一律用 GDAL buf 降采样读取。
# 修复 OOM整幅 34914x19177×3 float32 ≈ 7.48 GiB 会一次性把内存打爆。
_MAX_PREVIEW_DIM = 2048
if max(width, height) <= _MAX_PREVIEW_DIM:
_buf_w, _buf_h = width, height
else:
_scale = _MAX_PREVIEW_DIM / max(width, height)
_buf_w, _buf_h = max(1, int(width * _scale)), max(1, int(height * _scale))
def _read_band_dec(band):
"""按预览 buf 尺寸降采样读取GDAL 内部抽样Python 只驻留 buf 大小数组)。"""
return band.ReadAsArray(buf_xsize=_buf_w, buf_ysize=_buf_h)
# 检测是否为单波段二值图(耀斑掩膜)
is_binary_mask = (band_count == 1) or (folder_type == 'glint')
if is_binary_mask:
# 单波段二值图的特殊处理
binary_data = dataset.GetRasterBand(1).ReadAsArray().astype(np.float32)
# 单波段二值图的特殊处理(★ buf 降采样读取)
binary_data = _read_band_dec(dataset.GetRasterBand(1)).astype(np.float32)
# 单波段二值图 → RGB耀斑文件夹固定为黑底、耀斑白其余为灰度拉伸
if folder_type == 'glint':
# 背景黑色 (0,0,0),掩膜中大于阈值的像元为耀斑 → 白色 (1,1,1)
rgb_image = np.zeros((height, width, 3), dtype=np.float32)
# 背景黑色 (0,0,0),掩膜中大于阈值的像元为耀斑 → 白色 (1.0,1.0,1.0)
# float 图值域 [0,1] 与 imshow 默认一致,避免 255 越界触发 clipping 警告
rgb_image = np.zeros((_buf_h, _buf_w, 3), dtype=np.float32)
glint_mask = binary_data > 0.5
rgb_image[glint_mask] = 255
rgb_image[glint_mask] = 1.0
title_color_info = "背景黑,白色=耀斑区域"
else:
# 其他单波段:使用灰度
@ -607,11 +621,11 @@ class WaterQualityVisualization:
else:
bands = [0, 0, 0] # 灰度显示
# 读取指定波段
r_data = dataset.GetRasterBand(bands[0] + 1).ReadAsArray().astype(np.float32)
g_data = dataset.GetRasterBand(bands[1] + 1).ReadAsArray().astype(
# 读取指定波段(★ buf 降采样:预览内存恒定 ≤2048 边长,整幅不再入内存)
r_data = _read_band_dec(dataset.GetRasterBand(bands[0] + 1)).astype(np.float32)
g_data = _read_band_dec(dataset.GetRasterBand(bands[1] + 1)).astype(
np.float32) if band_count > 1 else r_data.copy()
b_data = dataset.GetRasterBand(bands[2] + 1).ReadAsArray().astype(
b_data = _read_band_dec(dataset.GetRasterBand(bands[2] + 1)).astype(
np.float32) if band_count > 2 else r_data.copy()
# 去除无效值