You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Rasterio导出的GeoTIFF在QGIS中显示全黑的问题求助

问题:导出的Sabins Ratio栅格在QGIS中显示异常(黑色方块)

我使用Python的rasterio(1.3.6)和earthpy开发卫星影像处理工作流,通过栅格代数计算生成Sabins Ratio合成栅格,将每个比值作为单独波段导出为GeoTIFF。结果在Python环境中可正常可视化,但导出后在QGIS中仅显示黑色方块(仅左上角有代表兴趣区域的红点)。相关代码如下:

#file path
multi_bands = glob.glob('.././GIS/landsat_8/LC08_L2SP_090079_20230225_20230301_02_T1/LC08_L2SP_090079_20230225_20230301_02_T1_SR_*B[2:3:4:5:6:7].tif')

multi_bands.sort()

img_list = []

#reading bands
for img in multi_bands:
    with rio.open(img, 'r') as img_file:
        img_list.append(img_file.read(1))

#multiband array    
arr_st = np.stack(img_list)

# visualize all bands
ep.plot_bands(arr_st,
              cbar=False,
              cmap = 'gist_earth')
plt.show()

#avoid numpy error of zero division
np.seterr(divide='ignore', invalid='ignore')

#perform band ratios
ironOxideR = arr_st[0]/arr_st[2]
ClayHyR = arr_st[4]/arr_st[5]
ferrousR = arr_st[4]/arr_st[3]

# Create the RGB composition
sabinsRatio = np.stack((ironOxideR, ClayHyR, ferrousR))

#sabinsRatio plot
ep.plot_rgb(sabinsRatio,
            rgb=(0,1,2),
            figsize=(10, 10),
            stretch = True,
            title = 'RGB composition of Iron Oxide, Clay Hydration, and Ferrous')
plt.show()

#trying to export

#exporting sabinsRatio

# Update the metadata
out_meta = {"driver": "GTiff",
            "height": sabinsRatio.shape[1],
            "width": sabinsRatio.shape[2],
            "crs": "EPSG:32756",
            "count":3,
            "dtype":rio.float32
            }
           


# Write the mosaic raster to disk
with rio.open('./output/sabinRation2.tif', "w", **out_meta) as dest:
    dest.write(sabinsRatio, [1,2,3])

解决方案

1. 补充地理变换(GeoTransform)参数

导出的TIFF缺失地理变换信息,导致QGIS无法正确定位和渲染栅格。需要从原始影像中读取transform参数并写入输出元数据:

# 从第一个原始影像读取transform和基础元数据
with rio.open(multi_bands[0], 'r') as src:
    out_meta = src.meta.copy()
    # 更新元数据为输出需求
    out_meta.update({
        "count": 3,
        "dtype": rio.float32
    })

或者手动在原有out_meta中添加:

with rio.open(multi_bands[0], 'r') as src:
    transform = src.transform

out_meta = {
    "driver": "GTiff",
    "height": sabinsRatio.shape[1],
    "width": sabinsRatio.shape[2],
    "crs": "EPSG:32756",
    "count":3,
    "dtype": rio.float32,
    "transform": transform  # 新增地理变换参数
}

2. 处理浮点栅格的显示范围

比值计算后的浮点数据动态范围与QGIS默认显示设置不匹配,导致渲染异常。可以:

  • 在QGIS中右键栅格图层 → 属性 → 样式,选择“最小/最大拉伸”,点击“加载”获取实际像素值范围后应用;
  • 或在导出前将数据归一化到0-1范围:
def normalize(arr):
    min_val = np.nanmin(arr)
    max_val = np.nanmax(arr)
    return (arr - min_val) / (max_val - min_val)

# 对每个波段进行归一化
sabinsRatio_normalized = np.stack([normalize(band) for band in sabinsRatio])

3. 替换NaN值

比值计算中产生的NaN(除零或无效值)会被QGIS默认渲染为黑色,可将其替换为特定值:

sabinsRatio = np.nan_to_num(sabinsRatio, nan=0.0)

完整修改后的导出代码示例

# 读取原始影像元数据
with rio.open(multi_bands[0], 'r') as src:
    out_meta = src.meta.copy()
    out_meta.update({
        "count": 3,
        "dtype": rio.float32
    })

# 处理NaN值
sabinsRatio = np.nan_to_num(sabinsRatio, nan=0.0)

# 写入栅格文件
with rio.open('./output/sabinRation2.tif', "w", **out_meta) as dest:
    dest.write(sabinsRatio, [1,2,3])

内容的提问来源于stack exchange,提问作者Rodrigo Brust

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 10:53:12