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

如何用Python从Mapbox RGB地形PNG生成16位高度图(代码问题排查)

解决Mapbox RGB地形转高度图的两个问题

问题分析

  • 山顶区域本该显示白色却呈现黑色:归一化逻辑本身无错误,但需确保解码后的高度值正确映射到目标范围的最大值,同时保存时匹配对应的数据类型。
  • 改用255作为归一化范围时图像全黑:原代码统一使用np.uint16类型,0-255的数值在16位图像中仅占极小亮度区间,视觉上接近黑色,需根据目标范围选择对应的数据类型(uint8对应255,uint16对应65535)。

修正后的代码

from PIL import Image
import numpy as np
from io import BytesIO

def rgb_to_elevation(images_array_key, save_path, normalize_range=65535):
    rgb_elevation = Image.open(BytesIO(images_array_key))
    rgb_data = np.array(rgb_elevation)
    
    # 解码Mapbox RGB地形数据为高度值
    r = rgb_data[..., 0]
    g = rgb_data[..., 1]
    b = rgb_data[..., 2]
    decoded_data = -10000 + ((r * 256 * 256 + g * 256 + b) * 0.1)
    
    # 归一化处理,避免除以0的情况
    min_val = decoded_data.min()
    max_val = decoded_data.max()
    if max_val == min_val:
        normalized = np.zeros_like(decoded_data)
    else:
        normalized = ((decoded_data - min_val) / (max_val - min_val)) * normalize_range
    
    # 根据归一化范围选择对应的数据类型
    if normalize_range == 255:
        normalized = normalized.astype(np.uint8)
    elif normalize_range == 65535:
        normalized = normalized.astype(np.uint16)
    else:
        raise ValueError("仅支持255(8位)或65535(16位)的归一化范围")
    
    # 保存图像
    outimage = Image.fromarray(normalized)
    outimage.save(save_path)

# 使用示例
# rgb_to_elevation(images_array[key], "16bit_heightmap.png", normalize_range=65535)
# rgb_to_elevation(images_array[key], "8bit_heightmap.png", normalize_range=255)

关键修正点

  • 新增数据类型匹配逻辑:当目标范围为255时转换为np.uint8,让0-255的数值对应8位图像的完整亮度区间,解决全黑问题。
  • 添加除以0的异常处理:当图像所有像素高度相同时,直接生成全0图像,避免计算报错。
  • 封装为函数,方便快速切换归一化范围。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 19:27:27