From 81ae400294587ded0032992f2475952c9eb1247e Mon Sep 17 00:00:00 2001 From: duxin Date: Tue, 8 Sep 2026 17:26:18 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E5=BD=B1=E5=83=8F=E9=A2=84=E8=A7=88?= =?UTF-8?q?=E5=9B=BEGDAL=20buf=E9=99=8D=E9=87=87=E6=A0=B7=E9=98=B2OOM?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 预览图不再整幅读入 34914x19177x3 float32(~7.5GiB),按 MAX_PREVIEW_DIM=2048 buf 降采样 - 耀斑单波段掩膜 RGB 白色由 255 改为 1.0,消除 imshow clipping 警告 --- src/postprocessing/visualization_reports.py | 32 +++++++++++++++------ 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/postprocessing/visualization_reports.py b/src/postprocessing/visualization_reports.py index ee2ff91..6451b15 100644 --- a/src/postprocessing/visualization_reports.py +++ b/src/postprocessing/visualization_reports.py @@ -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() # 去除无效值