真彩色云图需要根据通道Channel01,通道Channel02,通道Channel03进行通道融合处理,大致思路:三个通道对于RGB三个颜色管道,然后合并成一个三通道图像,其余云图在历史文档里有
python解析风云4B,生成红外云图、可见光云图、水汽云图
https://blog.csdn.net/qq_38197010/article/details/146549542?utm_source%20=%20uc_fansmsg
import h5py
import matplotlib.pyplot as plt
import numpy as np
import cartopy.crs as ccrs
import cartopy.feature as cfeature
import cartopy.io.shapereader as shpreader
import cv2
from skimage import exposure
import math
from numpy import deg2rad, rad2deg, arctan, arcsin, tan, sqrt, cos, sin
from mpl_toolkits.basemap import Basemap
data_file = '.\\Z_SATE_C_BAWX_20250306061714_P_FY4B-_AGRI--_N_DISK_1050E_L1-_FDI-_MULT_NOM_20250306060000_20250306061459_4000M_V0001.HDF'
china_province_shapefile = 'china.json' # 替换为实际的 Shapefile 路径
reader = shpreader.Reader(china_province_shapefile)
ea = 6378.137 # 地球的半长轴[km]
eb = 6356.7523 # 地球的短半轴[km]
h = 42164 # 地心到卫星质心的距离[km]
λD = deg2rad(104.7) # 卫星星下点所在经度
# 列偏移
COFF = {"0500M": 10991.5,
"1000M": 5495.5,
"2000M": 2747.5,
"4000M": 1373.5}
# 列比例因子
CFAC = {"0500M": 81865099,
"1000M": 40932549,
"2000M": 20466274,
"4000M": 10233137}
LOFF = COFF # 行偏移
LFAC = CFAC # 行比例因子
def latlon2linecolumn(lat, lon, resolution):
"""
经纬度转行列
(lat, lon) → (line, column)
resolution:文件名中的分辨率{'0500M', '1000M', '2000M', '4000M'}
line, column
"""
lat = deg2rad(lat)
lon = deg2rad(lon)
eb2_ea2 = eb ** 2 / ea ** 2
λe = lon
φe = arctan(eb2_ea2 * tan(lat))
cosφe = cos(φe)
re = eb / sqrt(1 - (1 - eb2_ea2) * cosφe ** 2)
λe_λD = λe - λD
r1 = h - re * cosφe * cos(λe_λD)
r2 = -re * cosφe * sin(λe_λD)
r3 = re * sin(φe)
rn = sqrt(r1 ** 2 + r2 ** 2 + r3 ** 2)
x = rad2deg(arctan(-r2 / r1))
y = rad2deg(arcsin(-r3 / rn))
column = COFF[resolution] + x * 2 ** -16 * CFAC[resolution]
line = LOFF[resolution] + y * 2 ** -16 * LFAC[resolution]
return np.rint(line).astype(np.uint16), np.rint(column).astype(np.uint16)
# 中国范围
x_min = 10
x_max = 60
y_min = 70
y_max = 140
column = math.ceil((x_max - x_min) / 0.04)
row = math.ceil((y_max - y_min) / 0.04)
print(row, column)
ynew = np.linspace(y_min, y_max, row) # 获取网格y
xnew = np.linspace(x_min, x_max, column) # 获取网格x
xnew, ynew = np.meshgrid(xnew, ynew) # 生成xy二维数组
data_grid = np.zeros((row, column)) # 声明一个二维数组
# 读取风云4B数据
keyword = "NOMChannel"
with h5py.File(data_file, 'r') as f_data:
type = f_data['Data'].keys()
nc_obj = f_data['Data'];
index = {}
r_data = {}
for k in type:
if str(k) == 'NOMChannel04':
break
if str(k).find(keyword) == 0:
value = nc_obj[k][:] # 读取波段数据
for i in range(row):
for j in range(column):
lat = xnew[i][j]
lon = ynew[i][j]
fy_line = 0
fy_column = 0
if index.get((lat, lon)) == None:
# 查找行列并记录下来下次循环使用
fy_line, fy_column = latlon2linecolumn(lat, lon, "4000M")
index[(lat, lon)] = fy_line, fy_column
else:
fy_line, fy_column = index.get((lat, lon))
data_grid[i][j] = value[fy_line, fy_column]
r_data[k] = data_grid
B = r_data['NOMChannel01'][:] # 蓝色通道数据
G = r_data['NOMChannel02'][:] # 绿色通道数据
R = r_data['NOMChannel03'][:] # 红色通道数据
calib_coef = f_data['Calibration/CALIBRATION_COEF(SCALE+OFFSET)'][:]
# 校准通道数据
slope = calib_coef[0, 0]
intercept = calib_coef[0, 1]
B = B * slope + intercept
slope = calib_coef[1, 0]
intercept = calib_coef[1, 1]
G = G * slope + intercept
slope = calib_coef[2, 0]
intercept = calib_coef[2, 1]
R = R * slope + intercept
# 数据维度
print("Data Shape (B, G, R): ", B.shape, G.shape, R.shape)
# RGB通道合并
img3 = cv2.merge([R, G, B]) # 合并成一个三通道图像
# 对比度调整:对数变换
img3 = exposure.adjust_log(img3, inv=True)
# 伽马调整:调暗图像
img3 = exposure.adjust_gamma(img3, 1.1)
# 颜色条件修复
T = 2 # 修复条件阈值
for i in range(img3.shape[0]):
for j in range(img3.shape[1]):
r, g, b = img3[i, j]
# 自定义RGB修复逻辑
img3[i, j] = (r * 0.6, g, b) # 对红色通道进行缩放
if r / g > T:
img3[i, j] = (g, r * 0.7, b) # 如果红色通道与绿色通道的比值大于阈值T,则进行特殊修复
img3 = cv2.rotate(img3, cv2.ROTATE_90_COUNTERCLOCKWISE)
# 创建地图画布
fig = plt.figure(figsize=(12, 8))
ax = fig.add_subplot(111, projection=ccrs.PlateCarree())
# 设置地图范围
ax.set_extent([y_min, y_max,x_min, x_max], crs=ccrs.PlateCarree())
# 4. 使用Cartopy内置方法添加边界
ax.add_geometries(
reader.geometries(), # 自动处理所有几何类型
crs=ccrs.PlateCarree(), # 数据坐标系(WGS84)
edgecolor='white',
facecolor='none', # 不填充颜色
linewidth=0.6
)
# 绘制融合后的真彩云图
ax.imshow(img3,
origin='upper',
extent=[y_min, y_max, x_min, x_max], # 经度范围在前
transform=ccrs.PlateCarree())
# 添加地理要素
ax.add_feature(cfeature.COASTLINE.with_scale('50m'), linestyle=':', linewidth=0.5, color='white')
ax.add_feature(cfeature.BORDERS.with_scale('50m'), linewidth=0.5, color='white')
# 保存图像
plt.savefig('./images/FY4B_China_TrueColor_CloudMap_Enhanced.png', dpi=150, bbox_inches='tight')
print("通道1-3绘制完成")
plt.close()
提示:这里可以添加总结
具体怎么融合颜色好看 根据实际去调整