
简介第二代地球同步轨道海洋水色成像仪GOCI2说明手册集中整理其波段信息与关键性能指标面向海洋遥感数据处理、水色研究及传感器定标领域的科研人员和工程师有助于快速弄清GOCI至GOCI2的升级差异与观测能力。资源包内含1个PDF文件压缩后约2.93MB目前已有1155人学习浏览。内容以参数表格展示GOCI与GOCI2对比涵盖可见光至近红外多个特征波段的中心波长、带宽、名义辐射亮度、最大海洋辐射亮度、阈值辐射亮度以及信噪比等指标并介绍快门罩、指向镜、滤波轮、焦平面组件等设备结构组成同时收录GOCI2月球校准计划提出利用月球反射光开展绝对辐射定标以提高遥感数据一致性与精度。读者可据此获得较完整的传感器技术资料支撑海洋环境监测、数据产品处理或定标方案设计等工作。1. GOCI2 波段信息拿到数据先看光谱再看算法做海洋水色遥感的人第一次打开 GOCI2 的 L1B 文件时大概率会被 13 个波段吓到——上一代 GOCI 只有 8 个波段这一代直接加了 5 个。但波段多不等于效果好关键在于每个波段放在什么位置、带宽多宽、响应函数长什么样、在反演链条里扮演什么角色。GOCI2 是静止轨道海洋水色成像仪的二代载荷一天能对东亚近海拍摄十几次这意味着一个赤潮爆发的完整过程可以被连续追踪而不是像极轨卫星那样一天只有一两次过境。这篇内容围绕 GOCI2 说明手册里的波段表展开适合三类人一是刚拿到 GOCI2 数据、想知道怎么把波段和反演算法对应的新手二是做叶绿素、悬浮物、透明度反演需要确定波段组合和参数的老手三是想评估“静止轨道高频观测 荧光基线波段”这套设计对自己研究到底有没有用的人。先把波段表吃透后面设参数、跑大气校正、做时间序列才不会翻车。2. GOCI2 的 13 个波段怎么看中心波长、带宽与设计意图2.1 一张表理清 GOCI2 全波段结构GOCI2 的波段设计比第一代复杂得多。它从可见光一路铺到热红外既有继承自 GOCI 的经典水色波段也有专门为太阳诱导叶绿素荧光SIF增加的窄波段。整理波段信息时不要只盯着中心波长带宽和波段用途同样关键。这里给出一个可直接对照的波段总览表波段编号中心波长 (nm)类型主要用途B1380近紫外气溶胶校正、浑浊水体辅助B2412蓝光黄色物质CDOM吸收、清洁水体B3443蓝光叶绿素 a 吸收峰经典水色波段B4490蓝绿中等叶绿素浓度、透明度B5510绿光浑浊水体、悬浮物、浅水底质B6555绿光悬浮物、总悬浮颗粒物TSMB7620黄光红潮藻种辅助识别、高浊度水B8660红光叶绿素荧光基线低端、悬浮物B9680红光叶绿素荧光峰值区SIF 核心B10709近红外荧光基线高端、极端浑浊水体B11745近红外荧光基线辅助、大气校正B12865近红外大气校正、气溶胶光学厚度B1312000热红外云检测、海面温度辅助、水汽校正这张表是后续所有处理的基础。我一般会把这张表存成一份 JSON 或 CSV放在算法工程目录下而不是每次翻手册。原因很简单不同来源的处理脚本里波段编号有的是“1~13”有的是“0~12”还有人直接用中心波长做变量名没有统一配置表代码跑起来就是一场灾难。2.2 新增的 5 个波段到底补了什么能力对比第一代 GOCIGOCI2 的核心变化集中在 380nm、510nm、620nm、660nm、680nm、709nm、745nm 这 7 个位置上其中 510nm、620nm、680nm、709nm、745nm 是对旧设计的重要补充。510nm 和 620nm 的加入解决了一个实际问题传统 443nm 和 490nm 波段在浑浊水体里很快就饱和了吸收系数高、反射率低反演结果噪声极大。510nm 和 620nm 对高浓度悬浮物更敏感用来做近岸水体分类比单靠 490nm 稳定得多。680nm、709nm、745nm 这一组是 SIF 算法的地基叶绿素荧光峰值在 680~685nm 附近要计算荧光信号必须在峰两侧各取一个基线波段做线性插值。GOCI2 用 660nm 和 745nm 做基线两端680nm 做信号峰709nm 做辅助验证这个组合比老一代只用 680nm 单点要可靠得多。还有一个细节值得注意12000nm 热红外波段在大多数海洋水色分析里不会直接参与反演但它在云检测里价值极高。可见光波段区分薄云和海表高反射率区域经常误判热红外波段对云顶亮温敏感把 B13 加进云掩膜逻辑后白天的云边界识别精度能提升不少。很多人拿到数据后第一件事就是把热红外波段丢掉等到做大气校正时才发现云掩膜质量差又回来补这一块。2.3 波段响应函数比中心波长更重要手册里给出的中心波长只是标称值真正做定量反演时必须使用各波段的光谱响应函数SRF做加权计算。GOCI2 的每个波段不是理想的矩形响应而是类似高斯分布的曲线相邻波段的响应函数还有重叠。若直接拿中心波长代替整个波段做辐射传输模拟误差在近岸高浑浊水体里会被放大因为水体反射率在蓝绿波段斜率很陡。处理这类问题时常见做法是将 GOCI2 的 SRF 保存成查找表LUT在反演算法里做如下处理把光谱模拟值按 SRF 权重积分而不是取单波长点值。我一般会在初始化配置里加这样一段逻辑import numpy as np # 假设波段 B3 (443nm) 的 SRF 已从说明手册附带的响应函数文件中读出 srf_wavelength np.array([430, 435, 440, 443, 448, 452]) srf_response np.array([0.05, 0.42, 0.87, 1.00, 0.76, 0.12]) def weighted_band_reflectance(spectral_wl, spectral_reflectance, srf_wl, srf_resp): # 将光谱模拟值插值到 SRF 的波长网格上 interp np.interp(srf_wl, spectral_wl, spectral_reflectance) # 按响应函数加权平均 return np.sum(interp * srf_resp) / np.sum(srf_resp)这段代码的逻辑不复杂先把高光谱模拟数据插值到 SRF 网格再做加权平均得到的就是卫星传感器真正“看到”的波段反射率。参数上要注意两点第一srf_response 必须归一化否则加权结果会偏移第二插值时使用线性插值即可没有必要用高阶插值因为 SRF 本身是平滑曲线高阶插值不会带来显著改善反而可能在响应函数变化剧烈的边缘产生振荡。这个习惯养成后无论是做大气校正还是和现场实测光谱对比都会少很多“玄学误差”。3. 用 Python 从 L1B 里把波段信息真正读出来3.1 最小可用的 NetCDF 读取脚本GOCI2 的 L1B 数据以 NetCDF4 格式分发每个波段是一组二维数组存放辐射率或反射率数据。读取时最忌讳的事情是闷头用netCDF4.Dataset裸读变量名、缩放因子、填充值全靠猜。正确做法是先列出文件全部变量和全局属性确认波段名规则后再批量提取。下面是一段我常用在项目初始阶段的脚本目标只有一个把 13 个波段的辐射率全部读进一个字典import netCDF4 as nc import numpy as np def load_goci2_bands(filepath): ds nc.Dataset(filepath, r) band_dict {} scale getattr(ds, scale_factor, 1.0) offset getattr(ds, add_offset, 0.0) # GOCI2 的 L1B 文件中波段变量常以 B1..B13 命名 for i in range(1, 14): var_name fB{i} if var_name in ds.variables: data ds.variables[var_name][:] fill_value ds.variables[var_name]._FillValue valid_min ds.variables[var_name].valid_min valid_max ds.variables[var_name].valid_max # 应用缩放和偏移 data data * scale offset # 将填充值和超出有效范围的像元统一设为 NaN data np.where((data fill_value) | (data valid_min) | (data valid_max), np.nan, data) band_dict[fB{i}] data ds.close() return band_dict这段脚本的关键点有三个。第一scale_factor和add_offset不一定每个版本的文件都放在变量属性里有些版本放在全局属性里稳妥的做法是先从变量属性取取不到再从全局属性取。第二valid_min和valid_max一定要用否则你会看到大量异常负值混在数据里后面做比值指数时这些负值会直接污染结果。第三变量名规则需要先确认一次不同处理批次命名可能与B1有出入有的版本用band_1或wavelength_412这类命名写脚本前先print(ds.variables.keys())扫一眼比看手册更快。3.2 波段坐标与时间维度的处理GOCI2 是静止轨道成像仪它的数据网格不像极轨卫星那样按扫描条带组织而是固定在一个标称网格上。每帧数据的行、列坐标对应固定经纬度读取时通常不需要做重投影。但有一个容易踩坑的地方L1B 文件的经度、纬度变量可能是二维数组也可能只有四个角点的坐标信息取决于数据分发版本。如果拿到的是经纬度场建议直接和波段数组配合使用如果只有角点坐标则需要用pyproj生成网格。下面给一个将经纬度网格和波段数组对齐的做法from pyproj import Proj # 假设文件给出了标称投影参数 proj_str projgeos lon_0128.2 h35785863 x_00 y_00 ellpsGRS80 p Proj(proj_str) # 载荷全圆盘的行列号 cols, rows np.meshgrid(np.arange(width), np.arange(height)) # 将行列号转成经纬度具体偏移量按文件属性填写 lon, lat p(cols * pixel_size origin_x, rows * pixel_size origin_y, inverseTrue)这步做完后经纬度数组的 shape 与波段数组完全一致可以直接做逐像元分析。参数上需要特别注意geos投影里的h是卫星离地心距离GOCI2 静止轨道位置约在东经 128.2 度h 的标称值可以从事先保存的配置表里读取不要从文件里猜。3.3 把波段信息保存成工程配置文件读懂了 L1B 结构之后把这些信息固化下来是值得做的事。我每次接触一种新数据源习惯先写一份波段配置文件后续所有算法脚本都从这份配置读取波段参数而不是散落在代码各处。这样做的好处是换数据批次、换传感器、做交叉验证时改配置就能切换不用动算法逻辑。# goci2_bands.json { sensor: GOCI2, bands: { B1: {center_wl: 380, type: uv, role: aerosol_correction}, B2: {center_wl: 412, type: blue, role: cdom}, B3: {center_wl: 443, type: blue, role: chl_a_absorption}, B4: {center_wl: 490, type: bluegreen, role: transparency}, B5: {center_wl: 510, type: green, role: turbid_water}, B6: {center_wl: 555, type: green, role: tsm}, B7: {center_wl: 620, type: yellow, role: red_tide_discrimination}, B8: {center_wl: 660, type: red, role: fluorescence_baseline_low}, B9: {center_wl: 680, type: red, role: sif_peak}, B10: {center_wl: 709, type: nir, role: fluorescence_baseline_high}, B11: {center_wl: 745, type: nir, role: fluorescence_baseline_support}, B12: {center_wl: 865, type: nir, role: atmospheric_correction}, B13: {center_wl: 12000, type: tir, role: cloud_detection} } }这份 JSON 的价值会在后续写反演算法时充分体现——比如算 SIF 时脚本只从配置里读fluorescence_baseline_low和fluorescence_baseline_high对应波段而不是写死B8和B11。波段编号一旦发生调整配置文件改一行就能解决。另外建议把这份配置纳入版本管理数据分发方如果更新了波段表你能清楚地看到差异在哪里而不是某天突然发现结果曲线断了一截才去排查。4. 波段组合实战SIF 基线计算与赤潮日内追踪4.1 660/680/745 三波段配出荧光信号GOCI2 波段设计的最大亮点就是 SIF 相关波段。叶绿素分子吸收光能后一部分以荧光形式在 680~685nm 附近重新发射这个信号强度跟浮游植物光合作用效率相关。问题是荧光信号在辐射亮度里占比很小要把这个微弱信号从大气散射和水体反射的背景里提取出来必须借助基线法。SIF 基线法的思路很简单荧光峰位于 680nm在 660nm 和 745nm 处基本没有荧光贡献用这两个波段的辐射率做线性插值就能得到“没有荧光”时 680nm 应有的大小。实际值与基线值之差就是荧光信号。import numpy as np # 假设已经提取了三个波段的遥感反射率Rrs rrs_660 band_data[B8] rrs_680 band_data[B9] rrs_745 band_data[B11] # 三波段基线法660nm 和 745nm 线性插值到 680nm baseline_680 rrs_660 (rrs_745 - rrs_660) * (680 - 660) / (745 - 660) # 荧光信号 sif_680 rrs_680 - baseline_680 # 异常值处理基线值大于峰值时SIF 为负属于无效值 sif_680[(baseline_680 rrs_680)] np.nan这段计算看着简单实际用起来有几个容易出现偏差的细节。第一波段间的辐射度要严格对齐如果 660nm 和 745nm 波段数据里有残留云污染或太阳耀光插值出的基线会偏高SIF 直接被低估。第二线性插值的两个端点要根据实际环境微调。在离岸清洁水体745nm 的瑞利散射路径辐射较小但在近岸高浑浊水体745nm 信号里包含大量悬浮物散射此时把 709nm 加入做交叉验证更稳妥。第三SIF 有明显日变化正午前后光强最大时荧光也最强做时间序列对比时必须固定每日过境时段否则会把日变化当成空间变化。4.2 用 13 个波段做近岸赤潮的日内过程追踪赤潮暴发时海表浮游植物浓度在几小时内就可能出现明显变化。极轨卫星一天只能给一两次有效观测很难捕捉这种短时间尺度的动态。GOCI2 的静止轨道特性让它能实现白天至少 8~10 次连续观测这对研究赤潮的“起爆—扩散—消亡”过程提供了关键数据支持。我在处理这类过程数据时一般不会一步到位地反演叶绿素浓度而是先做波段指数分析锁定可疑区域再深入。一个实用路径是先用 555nm 和 865nm 比值剔除高悬浮物水体再计算 B8/B5 比值识别浮游植物富集区最后用 SIF 信号确认生理活性。import numpy as np rrs_555 band_data[B6] rrs_865 band_data[B12] rrs_510 band_data[B5] rrs_660 band_data[B8] # 悬浮指数555nm 反射率远高于 865nm 说明水体浑浊 turbidity_index (rrs_555 - rrs_865) / (rrs_555 rrs_865) # 浮游植物指数660nm 与 510nm 的差异反映色素吸收 veg_index (rrs_660 - rrs_510) / (rrs_660 rrs_510) # 综合判定高浑浊水体排除浮游植物信号强则标记 potential_bloom (turbidity_index 0.1) (veg_index 0.02)这套指数组合的优势在于利用了 GOCI2 特有的 510nm 和 620nm 波段。传统 NDVI 在近岸高浑浊水体里经常失效因为悬浮物的散射会掩盖叶绿素吸收信号。加上 510nm 后叶绿素吸收与悬浮物散射可以在不同光谱区间被区分开误判率明显降低。参数阈值不是固定的不同季节、不同海域、不同大气条件下要重新标定。我一般会取研究区域内无明显赤潮的历史 L1B 数据作为背景场计算turbidity_index和veg_index的均值和标准差把阈值设在均值加两倍标准差的位置而不是拍脑袋定一个常数。4.3 多时次影像的波段对齐与合成GOCI2 的高频观测虽然好但把多帧数据用起来必须处理两个实际问题帧间几何配准和太阳高度角变化。前者通常通过影像配准算法解决后者则需要把数据归一化到相同观测几何条件下否则时间序列上会出现虚假波动。import xarray as xr import numpy as np # 将同一区域的多帧 L1B 数据读取后按时间堆叠 time_slices [] for t, filepath in enumerate(filelist): ds xr.open_dataset(filepath) band ds[B9].squeeze() # 680nm 波段 # 假设卫星天顶角 sza 已经读取做余弦归一化 sza ds[SolarZenithAngle].squeeze() band_norm band / np.cos(np.deg2rad(sza)) time_slices.append(band_norm) ds.close() # 按时间维堆叠 stacked xr.concat(time_slices, dimtime)这里要注意squeeze()的使用时机。GOCI2 的 L1B 常有单维长度为 1 的帧维不压缩掉后面做数组运算很容易出现维度不匹配。余弦归一化的前提是辐射亮度与太阳入射角的余弦成正比这只在朗伯体假设下成立实际海表的二向反射特性会让这个归一化在高太阳天顶角时如早晨和傍晚产生偏差。所以这些时次的 SIF 反演结果要谨慎使用最稳定的观测窗口是当地时间 10:00 到 14:00。波段选择、基线计算、归一化方式都确认后拿来进行赤潮日内变化分析就能看到比较干净的过程曲线。极轨卫星完全看不到的“上午发展、下午消退”这类现象静止轨道数据可以完整呈现。5. GOCI2 波段数据处理的五个常见坑与排查思路5.1 中心波长版本差异导致反演结果漂移现象同一区域、同一天的两景数据用同一套算法反演得到的叶绿素浓度差了一倍。排查到最后发现算法里写死了中心波长而数据分发方更新过快某些波段的中心波长了调整。原因GOCI2 在轨测试期间部分波段的中心波长和带宽做过调整。如果你使用早期版本的手册数据写死了波段参数后面拿到校正后的数据偏差会直接体现在定量结果里。解决不要硬编码中心波长从 L1B 文件的波段属性里读取实际值。打开 NetCDF 文件后先检查band_wavelength或central_wavelength属性再写进配置。这个习惯能帮你避免掉一个很大的坑尤其是做长时序研究时数据跨度大、版本混杂有中心波长动态读取机制比任何事后校正都靠谱。5.2 填充值没清干净时间序列全是异常的负值现象处理某天的数据时SIF 结果大面积出现负值而且负值大致呈条带状分布统计数据几乎不可用。原因L1B 中未扫描区域和云遮挡区域的填充值没有被识别参与进了插值和比值计算。数组里的填充值多为一个极大负数如 -9999线性插值遇到它会把整条基线拉歪。解决在读取阶段就把填充值替换为 NaN例如data np.where(data fill_value, np.nan, data)然后在所有波段计算前先检查 NaN 比例如果某帧数据 NaN 超过 40%这帧基本可以直接舍弃。这步要在预处理管线里做不要在出结果后才检查。时间复杂度不高但对结果的稳定性帮助极其明显。5.3 热红外波段与可见光波段分辨率不匹配现象把 B13 的云检测结果直接作为掩膜应用到 250m 分辨率的可见光波段上云边界处出现了大量像元错判。原因B13 的空间分辨率通常比可见光波段低很多直接做逐像元布尔运算会导致云边界处产生锯齿状伪影。把低频掩膜叠加到高频数据上物理解释本身就是错的。解决先将热红外波段重采样到可见光波段的分辨率再参与云检测。重采样方法不要用双线性插值而用最近邻插值因为云掩膜是类别数据双线性插值会产生介于“有云”和“无云”之间的中间值反而需要额外设定阈值。最近邻插值虽然粗糙但保持了类别语义from scipy.ndimage import zoom cloud_mask_lowres ds[cloud_mask][:] zoom_factor visible_res / tir_res cloud_mask_highres zoom(cloud_mask_lowres, zoom_factor, order0)5.4 太阳耀光污染在高频观测中被线性插值放大现象做 680nm SIF 基线计算时部分像元出现荧光信号极高的情况这些像元往往位于海面太阳耀光区跟赤潮无关。原因太阳耀光在近红外波段的影响大于红光波段660nm 和 745nm 两个基线波段受耀光污染程度不同线性插值后基线值严重偏离实际。解决先用菲涅尔反射模型计算每个像元的耀光风险指数把高风险像元直接屏蔽掉。GOCI2 静止轨道上太阳-卫星几何相对固定每天同一时刻的耀光分布接近可以提前算好一个掩膜不必每帧重复计算。做高频时间序列时优先采用耀光影响最小的几个时次参与反演。5.5 波段编号从 0 开始还是从 1 开始现象从不同渠道下载的 GOCI2 数据有的文件里波段变量叫B1~B13有的叫band0~band12脚本里固定的索引把两个文件的数据互相覆盖了。原因原始处理系统和后来的再处理产品采用了不同的波段编号约定没有统一标准。解决任何读取脚本的第一步都是打印变量列表确认波段索引规则再动态生成映射。我在前面给出的load_goci2_bands函数里就用了一个循环来匹配这个设计就是为了防止这类问题。不要在脚本里写死ds.variables[B5]而要先用字符串匹配去找到包含 510 或 5 的关键字再做解析。6. 用波段配置表驱动一个通用的 GOCI2 分析框架处理 GOCI2 数据的流程已经很清晰读波段配置、提取数据、做大气校正、算指数、输出时间序列。把这套流程沉淀成一个可复用的小框架能显著提升效率。我的做法是把前面写的 JSON 波段配置作为唯一的数据源每个功能模块都从配置里读取所需波段不直接在功能代码里写波段号。比如做一个通用的 SIF 反演函数它的输入只需要研究区域、时间范围和一个模式参数函数内部通过配置查到 660nm、680nm、745nm 对应的波段编号再执行基线计算。这样哪怕数据分发方重新编号了波段也只需要更新 JSON整个框架不需要改。更进一步可以把每天的 L1B 处理结果按波段存档成 DataArray配合 xarray 的groupby(time.hour)直接看日内变化曲线# 按小时分组统计 SIF 均值和标准差观察荧光日内变化 hourly_sif sif_dataset.groupby(time.hour).mean(dimtime) hourly_std sif_dataset.groupby(time.hour).std(dimtime)这段分析能直接揭示数据质量随太阳高度角的变化。如果某个小时窗口的 SIF 标准差异常大大概率是观测几何或耀光影响后续处理应避开这个时段。这比肉眼翻影像快得多也能给大气校正参数调整提供量化依据。我对波段信息的理解是它不只是说明书里的一张参数表而是整套反演算法的“坐标系”。坐标系建对了后面的配准、归一化、指数计算都有意义坐标系错了所有结果都是空中楼阁。我自己刚接触 GOCI2 时就是因为觉得波段表没什么好研究的直接跳进算法开发后面花了大量时间排查波段版本问题这段血泪经验后来沉淀成了这份做法先把波段配置固化成工程文件再把处理流程模块化最后才谈反演算法调优。希望这份梳理能帮你少走一点弯路。本文还有配套的精品资源点击获取