如何解决Earth Engine中sampleRectangle像素超出上限的报错?
解决ee.Image转Numpy数组时大区域像素超限问题
sampleRectangle函数存在默认像素数量限制(通常为100万像素),当目标区域过大、分辨率过高导致总像素超过阈值时,就会触发报错。以下是几种可行的解决方案:
方案1:分块采样拼接(推荐直接在脚本内处理)
把大区域拆成多个小矩形块,逐个采样后拼接成完整数组,避开单块像素上限:
import numpy as np import ee ee.Initialize() # 替换为你的目标区域(ee.Geometry/ee.Feature) a_file = ee.FeatureCollection("你的区域路径").first().geometry() naipCollection = ( ee.ImageCollection("USDA/NAIP/DOQQ") .filterBounds(a_file) .filterDate("2017-01-01", "2020-12-15") ) naip = naipCollection.mosaic() naipNDVI = naip.normalizedDifference(["R", "N"]).rename("NDVI") naip_b = naipNDVI.reproject("EPSG:32613") # 获取区域的投影和像素尺寸 proj = naip_b.projection() region_bounds = a_file.bounds() width = proj.nominalScale().multiply(region_bounds.width()).divide(proj.nominalScale()).round().getInfo() height = proj.nominalScale().multiply(region_bounds.height()).divide(proj.nominalScale()).round().getInfo() # 设定单块最大像素尺寸(比如1000x1000) block_size = 1000 cols = int(np.ceil(width / block_size)) rows = int(np.ceil(height / block_size)) # 初始化完整数组 full_array = np.zeros((height, width), dtype=np.float32) # 循环分块采样并拼接 for row in range(rows): for col in range(cols): x_offset = col * block_size y_offset = row * block_size block_width = min(block_size, width - x_offset) block_height = min(block_size, height - y_offset) # 创建当前块的有效区域(确保在目标范围内) block_region = ee.Geometry.Rectangle( [x_offset, y_offset, x_offset + block_width, y_offset + block_height], proj=proj ).intersection(a_file) # 采样当前块 sample = naip_b.sampleRectangle(region=block_region, defaultValue=0) block_arr = np.array(sample.get("NDVI").getInfo()) # 填入完整数组对应位置 full_array[y_offset:y_offset+block_height, x_offset:x_offset+block_width] = block_arr nonzero_or = np.count_nonzero(full_array) print(nonzero_or)
方案2:降低采样分辨率
如果不需要原始精度,可通过重投影降低分辨率,减少总像素数:
# 重投影时设置更大的分辨率(示例:原1米分辨率改为10米) naip_b_lowres = naipNDVI.reproject(crs="EPSG:32613", scale=10) array_or = naip_b_lowres.sampleRectangle(a_file, defaultValue=0) np_arr = np.array(array_or.get("NDVI").getInfo()) nonzero_or = np.count_nonzero(np_arr)
方案3:先导出再本地处理
针对超大规模区域,可先将图像导出到云存储/本地磁盘,再读取为Numpy数组:
# 导出到Google Drive(也可导出到Cloud Storage) task = ee.batch.Export.image.toDrive( image=naip_b, description='NDVI_export', region=a_file, scale=1, maxPixels=1e13, # 设置足够大的像素上限 fileFormat='GeoTIFF' ) task.start() # 任务完成后下载文件,用rasterio读取为数组 import rasterio with rasterio.open('NDVI_export.tif') as src: np_arr = src.read(1) nonzero_or = np.count_nonzero(np_arr)
内容的提问来源于stack exchange,提问作者Alonso Gonzalez
相关产品推荐
相关产品推荐

