Python 解析风云四A卫星L1级别数据以及绘制卫星云图

绘制出来的卫星云图

全圆盘真彩图:
在这里插入图片描述

全圆盘单通道红外图:

在这里插入图片描述

数据准备

数据格式说明:http://fy4.nsmc.org.cn/data/cn/data/realtime.html
数据下载地址:http://satellite.nsmc.org.cn/portalsite/Data/DataView.aspx?SatelliteType=1&SatelliteCode=FY4A#

本人使用的是4000M的全圆盘数据,下载数据需要申请账号
在这里插入图片描述

解析HDF数据

from netCDF4 import Dataset
import h5py

# 两种解析方式 netCDF4 和 h5py   直接用conda安装

hdf_data_path = "/Users/Downloads/FY4A-_AGRI--_N_DISK_1047E_L1-_FDI-_MULT_NOM_20200805080000_20200805081459_4000M_V0001.HDF"

# h5py 解析
hdf_obj = h5py.File(hdf_data_path, "r")
#打印文件里所有属性  属性含义自行查看数据说明格式
print(hdf_obj.keys())
# 通道1数据  
print(hdf_obj['NOMChannel01'][:])

# netCDF4 解析
nc_obj = Dataset(hdf_data_path)
#打印文件里所有属性
print(nc_obj.variables.keys())
# 通道1数据  
print(nc_obj.variables['NOMChannel01'][:])




绘制单通道云图

from netCDF4 import Dataset
import matplotlib.pyplot as plt

hdf_data_path = "/Users/Downloads/FY4A-_AGRI--_N_DISK_1047E_L1-_FDI-_MULT_NOM_20200805080000_20200805081459_4000M_V0001.HDF"

nc_obj = Dataset(hdf_data_path)
type = nc_obj.variables.keys()
print(type)

keyword = "NOMChannel"

for k in type:
    if str(k).find(keyword) == 0:
        data = nc_obj.variables[k][:]
        plt.imshow(data, cmap='gray')
        plt.title(k)
        plt.axis('off')
        plt.show()
        print("通道" + k + "绘制完成")


运行绘制出14个通道图:
在这里插入图片描述

绘制真彩云图

官方卫星真彩云图:http://fy4.nsmc.org.cn/portal/cn/theme/FY4A.html
在这里插入图片描述
上面是官方绘制出来的,绘制这样一张云图需要多通道数据融合,搜索到一篇论文,里面详细介绍了云图的合成!

FY-4A多通道扫描辐射成像仪评价与图像合成
论文地址:http://www.doc88.com/p-8866426031707.html

python数字图像处理:图像数据类型及颜色空间转换:
https://www.cnblogs.com/denny402/p/5122328.html

绘制真彩图流程:

在这里插入图片描述在这里插入图片描述

from netCDF4 import Dataset
import matplotlib.pyplot as plt
from skimage import io, data, img_as_float, img_as_ubyte, img_as_uint, img_as_int
import cv2

hdf_data_path = "/Users/Downloads/FY4A-_AGRI--_N_DISK_1047E_L1-_FDI-_MULT_NOM_20200805080000_20200805081459_4000M_V0001.HDF"

nc_obj = Dataset(hdf_data_path)
type = nc_obj.variables.keys()
print(type)

B = nc_obj.variables['NOMChannel01'][:]
G = nc_obj.variables['NOMChannel02'][:]
R = nc_obj.variables['NOMChannel03'][:]


# 将数据类型转成int16
B = img_as_int(B)
G = img_as_int(G)
R = img_as_int(R)

# opencv 将rgb三个通道融合
img3 = cv2.merge([R, G, B])

img3 = exposure.adjust_log(img3, inv=True)#调整对比度
img3 = exposure.adjust_gamma(img3, 1.2)  # 图像调暗
T = 2
for i in range(len(img3)):
    for j in range(len(img3[0])):
         r = img3[i][j][0]
         g = img3[i][j][1]
         b = img3[i][j][2]
         img3[i][j] = (r * 0.6, g, b)
         if r / g > T:
              img3[i][j] = (g, r * 0.7, b)

plt.imshow(img3, )
plt.axis('off')
plt.show()


# 

我这里只绘制出来的效果还是差点,最近比较忙有时间再解决吧!
上述问题,如果有解决了的同学,麻烦通知我一声

绘制中国地区的卫星云图




from netCDF4 import Dataset
import matplotlib.pyplot as plt
import math
from numpy import deg2rad, rad2deg, arctan, arcsin, tan, sqrt, cos, sin
import numpy as np
from mpl_toolkits.basemap import Basemap

hdf_data_path = "/Users/Downloads/FY4A-_AGRI--_N_DISK_1047E_L1-_FDI-_MULT_NOM_20200805080000_20200805081459_4000M_V0001.HDF"
ch_map = "/Users/map/中国地图/国界/bou1_4l"

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
    """
    # Step1.检查地理经纬度
    # Step2.将地理经纬度的角度表示转化为弧度表示
    lat = deg2rad(lat)
    lon = deg2rad(lon)
    # Step3.将地理经纬度转化成地心经纬度
    eb2_ea2 = eb ** 2 / ea ** 2
    λe = lon
    φe = arctan(eb2_ea2 * tan(lat))
    # Step4.求Re
    cosφe = cos(φe)
    re = eb / sqrt(1 - (1 - eb2_ea2) * cosφe ** 2)
    # Step5.求r1,r2,r3
    λe_λD = λe - λD
    r1 = h - re * cosφe * cos(λe_λD)
    r2 = -re * cosφe * sin(λe_λD)
    r3 = re * sin(φe)
    # Step6.求rn,x,y
    rn = sqrt(r1 ** 2 + r2 ** 2 + r3 ** 2)
    x = rad2deg(arctan(-r2 / r1))
    y = rad2deg(arcsin(-r3 / rn))
    # Step7.求c,l
    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 = 11
x_max = 54.75
y_min = 73.31
y_max = 135.91

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))  # 声明一个二维数组

keyword = "NOMChannel"

nc_obj = Dataset(hdf_data_path)
type = nc_obj.variables.keys()
print(type)
print("--------------------------------------------")

index = {}
r_data = {}
for k in type:
    if str(k).find(keyword) == 0:
        value = nc_obj.variables[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
        img = plt.figure()
        ax = img.add_subplot(111)
        m = Basemap(llcrnrlon=y_min, llcrnrlat=x_min, urcrnrlon=y_max, urcrnrlat=x_max)
        m.readshapefile(ch_map, 'states', drawbounds=True)
        p = plt.contourf(ynew, xnew, data_grid, cmap="gray", )
        plt.axis('off')
        plt.show()
        print("通道" + k + "绘制完成")

运行效果:
在这里插入图片描述ok !!! 完事这样绘制出来的图片就可以叠加到地图上了。
代码看着简单,其实源文件里没让大家看,很多坑我这就不说了,希望大家直接避过坑,折腾我两个星期,不容易啊。

绘制出来的图片与官方对比

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

  • 67
    点赞
  • 250
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 84
    评论
绘制卫星云图,需要使用Python中的一些科学计算和可视化库。下面是一些步骤和代码示例来实现这个目标: 1. 安装必要的库 你需要安装以下库: - numpy: 用于处理数组和矩阵 - matplotlib: 用于绘制图形 - basemap: 用于绘制地图和投影坐标系 - pillow: 用于处理图像 你可以使用pip install命令来安装这些库。 2. 下载数据 卫星云图通常是从气象卫星上获取的。你可以从以下网站下载一些示例数据: - https://www.ncdc.noaa.gov/satellite-data/satellite-data-access-viewer - https://www.goes.noaa.gov/f_himawari-8.html 下载数据后,你需要将它们保存在本地。 3. 加载数据 使用numpy库中的load函数来加载数据。例如,如果你的数据保存在文件名为data.npy的文件中,你可以使用以下代码来加载数据: ```python import numpy as np data = np.load('data.npy') ``` 4. 绘制图像 使用matplotlib库来绘制图像。你可以使用imshow函数来显示图像。例如,下面的代码将显示data中的图像: ```python import matplotlib.pyplot as plt plt.imshow(data) plt.show() ``` 5. 添加地图 使用basemap库来添加地图和投影坐标系。例如,下面的代码将在图像上添加地图: ```python from mpl_toolkits.basemap import Basemap m = Basemap(projection='mill', llcrnrlat=-90, urcrnrlat=90, llcrnrlon=-180, urcrnrlon=180) m.drawcoastlines() m.drawcountries() plt.imshow(data, origin='upper', extent=[-180, 180, -90, 90]) plt.show() ``` 6. 保存图像 最后,你可以使用savefig函数将图像保存到本地。例如,下面的代码将保存图像为png格式的文件: ```python plt.savefig('cloud_map.png', dpi=300, bbox_inches='tight') ``` 这是一个完整的示例代码: ```python import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.basemap import Basemap # 加载数据 data = np.load('data.npy') # 创建地图 m = Basemap(projection='mill', llcrnrlat=-90, urcrnrlat=90, llcrnrlon=-180, urcrnrlon=180) # 添加地图 m.drawcoastlines() m.drawcountries() # 绘制图像 plt.imshow(data, origin='upper', extent=[-180, 180, -90, 90]) # 保存图像 plt.savefig('cloud_map.png', dpi=300, bbox_inches='tight') ``` 运行这段代码,你将得到一个卫星云图,并将它保存到本地。
评论 84
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mr . zhang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值