97 lines
3.6 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
将 COG 格式的 Red, Green, Blue 单波段地表反射率图像合成 RGB 图像
1. 对比度线性拉伸至 0-255;
2. 合并波段;
3. 保存为 uint8 格式 RGB 图像;
"""
import os
import rasterio as rio
import numpy as np
def sr2rgb(red_path, green_path, blue_path, output_path):
"""
将红、绿、蓝三个单波段地表反射率图像合成为RGB图像
参数:
red_path (str): 红色波段文件路径
green_path (str): 绿色波段文件路径
blue_path (str): 蓝色波段文件路径
output_path (str): 输出RGB图像路径
"""
# 检查文件是否存在
for path in [red_path, green_path, blue_path]:
if not os.path.exists(path):
raise FileNotFoundError(f"文件不存在: {path}")
print(f"正在处理文件:")
print(f" 红波段: {red_path}")
print(f" 绿波段: {green_path}")
print(f" 蓝波段: {blue_path}")
# 读取三个波段数据
with rio.open(red_path) as red_src:
red_band = red_src.read(1)
profile = red_src.profile
print(f"红波段形状: {red_band.shape}, 数据类型: {red_band.dtype}")
with rio.open(green_path) as green_src:
green_band = green_src.read(1)
print(f"绿波段形状: {green_band.shape}, 数据类型: {green_band.dtype}")
with rio.open(blue_path) as blue_src:
blue_band = blue_src.read(1)
print(f"蓝波段形状: {blue_band.shape}, 数据类型: {blue_band.dtype}")
# 线性拉伸到0-255范围
def stretch_band(band):
# 处理NaN值
band_no_nan = np.where(np.isnan(band), 0, band)
band_min = np.min(band_no_nan)
band_max = np.max(band_no_nan)
# 避免除零错误
if band_max == band_min:
stretched = np.zeros_like(band_no_nan, dtype=np.uint8)
else:
stretched = ((band_no_nan - band_min) / (band_max - band_min) * 255).astype(np.uint8)
return stretched
red_stretched = stretch_band(red_band)
green_stretched = stretch_band(green_band)
blue_stretched = stretch_band(blue_band)
# 合并三个波段为RGB图像
rgb_array = np.dstack((red_stretched, green_stretched, blue_stretched))
# 更新元数据
profile.update(
dtype=rio.uint8,
count=3,
photometric='RGB',
nodata=0 # 设置nodata为0因为uint8的范围是0-255
)
# 保存RGB图像
with rio.open(output_path, 'w', **profile) as dst:
for i in range(3):
dst.write(rgb_array[:, :, i], i + 1)
print(f"RGB图像已保存到: {output_path}")
if __name__ == "__main__":
# tif_dir = "D:\\NASA_EarthData_Script\\data\\HLS\\2024\\2024012"
# red_path = os.path.join(tif_dir, "HLS.S30.T49RGP.2024012T031101.v2.0.RED.subset.tif")
# green_path = os.path.join(tif_dir, "HLS.S30.T49RGP.2024012T031101.v2.0.GREEN.subset.tif")
# blue_path = os.path.join(tif_dir, "HLS.S30.T49RGP.2024012T031101.v2.0.BLUE.subset.tif")
# output_path = os.path.join(tif_dir, "HLS.S30.T49RGP.2024012T031101.v2.0.RGB.tif")
tif_dir = "D:\\NASA_EarthData_Script\\data\\HLS\\2025\\2025011"
red_path = os.path.join(tif_dir, "HLS.S30.T49RGP.2025011T031009.v2.0.RED.subset.tif")
green_path = os.path.join(tif_dir, "HLS.S30.T49RGP.2025011T031009.v2.0.GREEN.subset.tif")
blue_path = os.path.join(tif_dir, "HLS.S30.T49RGP.2025011T031009.v2.0.BLUE.subset.tif")
output_path = os.path.join(tif_dir, "HLS.S30.T49RGP.2025011T031009.v2.0.RGB.tif")
sr2rgb(red_path, green_path, blue_path, output_path)