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

Folium地图栅格颜色暗淡问题技术求助

问题解决:Folium中4波段影像展示颜色暗淡、透明度异常的优化方案

问题概述

我有一份4波段影像(R、G、B、NIR),在Folium地图中展示时,呈现效果与QGIS差异显著:影像透明度异常且颜色十分暗淡。尝试通过拉伸处理改善效果,现有代码如下:

原始代码

import numpy as np
import folium
import rasterio as rio  # 修正导入别名匹配代码使用

with rio.open(raster) as src:
    img = src.read()
    meta = src.meta
    meta['nodata'] = np.nan
    min_lon, min_lat, max_lon, max_lat = src.bounds

meta

{'driver': 'GTiff',
 'dtype': 'float64',
 'nodata': nan,
 'width': 52,
 'height': 28,
 'count': 4,
 'crs': CRS.from_epsg(4326),
 'transform': Affine(0.00011284198076925242, 0.0, 12.026403058,
        0.0, -0.0001128420000000574, 44.289920142)}
    
bounds_orig = [[min_lat, min_lon], [max_lat, max_lon]]
centerx,centery = (np.average((min_lon,max_lon)),np.average((min_lat,max_lat)))

m = folium.Map(location = [centery,centerx], tiles='OpenStreetMap', zoom_start = 17)

vmin, vmax = np.nanpercentile(img.transpose(1, 2, 0), (10,90))

m.add_child( folium.raster_layers.ImageOverlay(img.transpose(1, 2, 0),name = 'raster',
                                              bounds = bounds_orig,opacity=1,
                                               colormap=[vmin,vmax]))

效果对比

  • Folium展示效果:
    Folium展示结果
  • QGIS展示结果:
    QGIS展示结果

问题原因

  1. 数据未归一化:Folium的ImageOverlay要求输入像素值范围为0-1(浮点)或0-255(整数),原始浮点影像未做拉伸归一化,导致颜色显示暗淡。
  2. colormap参数误用:colormap需传入颜色映射函数,而非直接传入数值范围[vmin,vmax],原代码参数设置无效。
  3. 波段选择错误:直接传入4波段数据(含NIR),但Folium仅支持RGB三通道或单通道显示,多余波段导致显示异常。

修正后的代码

import numpy as np
import folium
import rasterio as rio

def stretch_image(arr, pmin=10, pmax=90):
    """对影像做百分位拉伸,将值缩放到0-1范围"""
    # 计算百分位阈值
    pmin_val = np.nanpercentile(arr, pmin)
    pmax_val = np.nanpercentile(arr, pmax)
    # 截断超出阈值的像素值
    arr_stretched = np.clip(arr, pmin_val, pmax_val)
    # 归一化到0-1区间
    arr_stretched = (arr_stretched - pmin_val) / (pmax_val - pmin_val)
    # 将nodata值设为0(对应透明)
    arr_stretched[np.isnan(arr_stretched)] = 0
    return arr_stretched

with rio.open(raster) as src:
    # 仅读取R、G、B三个波段
    img = src.read([1,2,3])
    min_lon, min_lat, max_lon, max_lat = src.bounds

# 转置为(height, width, channels)格式
img_rgb = img.transpose(1, 2, 0)

# 对每个RGB波段分别做拉伸处理
img_stretched = np.dstack([stretch_image(img_rgb[..., i]) for i in range(3)])

bounds_orig = [[min_lat, min_lon], [max_lat, max_lon]]
centerx, centery = (np.average([min_lon, max_lon]), np.average([min_lat, max_lat]))

m = folium.Map(location=[centery, centerx], tiles='OpenStreetMap', zoom_start=17)

# 添加拉伸后的RGB影像
folium.raster_layers.ImageOverlay(
    image=img_stretched,
    name='raster',
    bounds=bounds_orig,
    opacity=1
).add_to(m)

# 添加图层控制
folium.LayerControl().add_to(m)

# 保存地图到本地
m.save('optimized_map.html')

关键优化点

  • 波段筛选:剔除NIR波段,仅保留R、G、B三通道用于可视化。
  • 百分位拉伸:通过自定义函数将像素值截断到10%-90%区间并归一化,匹配Folium的显示要求。
  • 参数修复:移除错误的colormap参数,RGB影像无需额外颜色映射。
  • Nodata处理:将无效值设为0,保证透明效果正常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 23:25:19