From 2f7b90725eac431bbe49d76166926e1a05df1b12 Mon Sep 17 00:00:00 2001 From: duxin Date: Wed, 9 Sep 2026 10:33:28 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E9=87=87=E6=A0=B7=E7=82=B9=E5=9C=B0?= =?UTF-8?q?=E5=9B=BE=E5=BA=95=E5=9B=BERGB=E6=94=B9=E7=94=A8GDAL=20buf?= =?UTF-8?q?=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 - _read_hyperspectral 原整幅读3波段再np.stack(34914x19177 float32 ~7.5GiB),现将预览最长边限制到2048,用 ReadAsArray(buf_xsize/buf_ysize) 抽样 - 返回'显示坐标系'(原点不变、像元尺寸×抽样比),geo_to_pixel 直接得显示像素,比例尺/指北针一致;移除下采样暂被禁用分支 --- src/postprocessing/point_map.py | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/postprocessing/point_map.py b/src/postprocessing/point_map.py index a77c6bc..2f0dcad 100644 --- a/src/postprocessing/point_map.py +++ b/src/postprocessing/point_map.py @@ -107,16 +107,20 @@ class SamplingPointMap: else: rgb_bands = [0, 0, 0] - if downsample and (width > 2000 or height > 2000): - print(f" ⚠ 下采样暂被禁用,使用原始分辨率: {width}x{height}") - sample_factor = 1 + # ★ 底图仅供预览:整幅高光谱 RGB 在 34914x19177 全分辨率下 np.stack(float32) + # 会一次分配 ~7.5GiB 导致 OOM。统一用 GDAL buf 抽样,预览最长边 ≤ MAX_DIM。 + _MAX_DIM = 2048 + if max(width, height) <= _MAX_DIM: + buf_w, buf_h = width, height else: - sample_factor = 1 + _scale = _MAX_DIM / max(width, height) + buf_w, buf_h = max(1, int(width * _scale)), max(1, int(height * _scale)) rgb_data = [] for band_idx in rgb_bands: band = dataset.GetRasterBand(band_idx + 1) - band_data = band.ReadAsArray().astype(np.float32) + # buf_xsize/buf_ysize:由 GDAL 在读取时抽样,Python 只驻留 buf 大小的数组 + band_data = band.ReadAsArray(buf_xsize=buf_w, buf_ysize=buf_h).astype(np.float32) rgb_data.append(band_data) if len(rgb_data) == 3: @@ -128,7 +132,15 @@ class SamplingPointMap: projection = dataset.GetProjection() dataset = None - return image_array, geotransform, projection, width, height, sample_factor + # 返回“显示坐标系”:原点不变,像元尺寸按抽样比例放大; + # 下游 _geo_to_pixel 据此直接得到显示像素坐标,无需再按 sample_factor 除一次。 + disp_gt = list(geotransform) + if buf_w != width: + disp_gt[1] = geotransform[1] * (width / float(buf_w)) + if buf_h != height: + disp_gt[5] = geotransform[5] * (height / float(buf_h)) + sample_factor = 1 # 缩放已并入 disp_gt + return image_array, tuple(disp_gt), projection, buf_w, buf_h, sample_factor def _read_sampling_points(self, csv_path: str) -> pd.DataFrame: """智能读取采样点,自动识别模糊列名,允许UTM坐标,自动修复颠倒坐标"""