最新资讯

  • 基于物理模型和全局优化算法的叶面积指数反演

基于物理模型和全局优化算法的叶面积指数反演

2026-02-01 15:00:16 栏目:最新资讯 2 阅读

遥感生物物理参数反演是遥感观测中非常重要的一项问题,今天我们花点时间来实现这一目标。

1 核心目标

(1)掌握基于物理模型的遥感参数反演的流程并能够独立完成参数反演。

(2)了解使用全局优化算法进行生物物理参数反演问题求解的思路。

2 主要内容

(1)任选两个不同植被类型站点,反演与地面测量数据对应时间的站点周围小区域LAI,并与基于地面测量数据的LAI进行对比分析。

(2)反演站点对应像元任意一年的LAI,并与MODIS LAI对比分析。

3 前期准备

(1)数据准备

站点数据下载:选择两个不同的植被类型的站点。本次选择的是代表森林的比利时的Sonian forest站点,以及代表草地的位于尼日尔的WANKAMA站点作为案例来进行讲解。

图 站点信息1

图 站点信息2

网站地址:http://w3.avignon.inra.fr/valeri/fic_htm/database/main.php.

这两个站点分别提供了UTM投影WGS-84坐标系下若干点的地面测量数据,包含有效LAI值和真实LAI值。该数据可用于后续反演LAI的精度验证。

MODIS数据下载:

首次下载,利用Global Subsets Tool工具下载小区域两个站点对应日期的地表反射率数据- MOD09A1和叶面积指数数据- MOD15A2H。两个数据的空间分辨率都是500m,由8天合成,由tif格式存储。同时下载该区域的2000-2020年MODIS的叶面积指数作为先验信息。

网站地址:TESViS Subset Order History,结果发现这个网站还是有点小问题,下载出来的影像的时间和站点观测的时间不对,这可能会影响后续的反演。

辗转多次,后面前往Google Earth Engine网站下载MODIS数据。基本流程是通过GEE平台,以站点的经纬度为中心,创建5km×5km的正方形区域,调用MODIS的反射率数据和叶面积指数产品,分别完成缩放因子操作,还原数据的数值。同时,在平台上选择站点记录的日期的每年的LAI数据,每一年在 站点观测数据对应日期附近20天窗口内的所有LAI影像先做年内平均,再对2002-2025年计算多年平均值,作为LAI反演的先验信息

时间序列数据下载:使用Google Earth Engine网站提取Sonian forest站点所在像元的MOD09A1数据的七个波段的反射率数据和MOD15A2H的叶面积指数数据,并以表格的形式存储。

图 GEE下载站点所在像元一年七个波段的反射率数据

图 GEE下载站点所在像元一年的LAI数据

下载数据的代码也提供给你了,首先是下载小区域的地表反射率数据和MODIS叶面积指数产品的代码:

/*************************************************
 * ROI: 5km x 5km centered at (50.768333N, 4.411111E)
 * (1) MOD09A1 near 2004-06-21: b1-b7 scaled (0.0001), export 7 tif (one band each)
 * (2) MOD15A2H near same period: LAI scaled (0.1), export tif
 * (3) MOD15A2H prior LAI mean (2002-2025): for EACH year,
 *     mean of ALL LAI images within 6/21 ± windowDays, then multi-year mean -> export tif
 *
 * Robust strategy:
 * - Export: DO NOT use clip(); use Export.region to crop (stable)
 * - Visualization: reproject to EPSG:4326 then clip(roi) for map display
 *************************************************/

// =====================
// 0) Parameters
// =====================
var lon = 2.635278;
var lat = 13.645;

var targetDateStr = '2005-06-27'; // target date "near"
var windowDays = 20;             // "near" window in days (8-day products: 8~24)

var roiSizeKm = 5;
var halfSizeM = roiSizeKm * 1000 / 2;

var exportScale = 500;
var exportCRS = 'EPSG:4326';

// prior window mean years
var priorStartYear = 2002;
var priorEndYear   = 2025;

// =====================
// 1) ROI in EPSG:4326 rectangle (geodesic=false)
// =====================
var pt = ee.Geometry.Point([lon, lat]);

var dLat = halfSizeM / 111320;
var dLon = halfSizeM / (111320 * Math.cos(lat * Math.PI / 180));

var roi = ee.Geometry.Rectangle(
  [lon - dLon, lat - dLat, lon + dLon, lat + dLat],
  null,
  false  // geodesic=false
);

// Display ROI outline
Map.centerObject(roi, 10);
Map.addLayer(ee.Image().byte().paint(roi, 1, 2), {palette:['yellow']}, 'ROI (5km×5km)');
Map.addLayer(pt, {color:'red'}, 'Center Point');

// =====================
// 2) Helper: choose closest image within +/- windowDays
// =====================
function getClosestImage(ic, targetDate, windowDays) {
  var t = ee.Date(targetDate);
  var filtered = ic.filterDate(t.advance(-windowDays, 'day'), t.advance(windowDays, 'day'));

  var withDelta = filtered.map(function(img) {
    var delta = ee.Number(img.get('system:time_start')).subtract(t.millis()).abs();
    return img.set('delta', delta);
  });

  return ee.Image(withDelta.sort('delta').first());
}

// Helper: for map display only (reproject then clip)
function vizClip(img, region, scale) {
  return img
    .resample('bilinear')
    .reproject({crs: exportCRS, scale: scale})
    .clip(region);
}

// =====================
// 3) (1) MOD09A1 reflectance b1-b7 near target date
// =====================
var mod09BandsRaw = [
  'sur_refl_b01','sur_refl_b02','sur_refl_b03','sur_refl_b04',
  'sur_refl_b05','sur_refl_b06','sur_refl_b07'
];
var mod09BandsOut = ['b1','b2','b3','b4','b5','b6','b7'];

var mod09IC = ee.ImageCollection('MODIS/061/MOD09A1')
  .select(mod09BandsRaw, mod09BandsOut);

var mod09Raw = getClosestImage(mod09IC, targetDateStr, windowDays);
var mod09Date = ee.Date(mod09Raw.get('system:time_start'));
print('Selected MOD09A1 nearest date:', mod09Date);

// Simple valid mask (avoid fill/abnormal)
var mod09Min = mod09Raw.reduce(ee.Reducer.min());
var mod09Max = mod09Raw.reduce(ee.Reducer.max());
var mod09Valid = mod09Min.gt(-100).and(mod09Max.lt(10000));

// Scale factor 0.0001
var mod09Scaled = mod09Raw.updateMask(mod09Valid)
  .multiply(0.0001)
  .toFloat();

// Map display
var mod09Show = vizClip(mod09Scaled, roi, exportScale);
Map.addLayer(mod09Show.select(['b1','b4','b3']), {min:0, max:0.4}, 'MOD09A1 TrueColor (scaled, ROI)');
mod09BandsOut.forEach(function(b){
  Map.addLayer(mod09Show.select(b), {min:0, max:0.5}, 'MOD09A1 '+b+' (scaled, ROI)');
});

// Export: one band one tif (NO clip; crop by region)
mod09BandsOut.forEach(function(b){
  Export.image.toDrive({
    image: mod09Scaled.select(b),
    description: 'MOD09A1_near_' + targetDateStr.replace(/-/g,'') + '_ROI5km_' + b,
    fileNamePrefix: 'MOD09A1_near_' + targetDateStr.replace(/-/g,'') + '_ROI5km_' + b,
    region: roi,
    scale: exportScale,
    crs: exportCRS,
    maxPixels: 1e13
  });
});

// =====================
// 4) (2) MOD15A2H LAI near SAME PERIOD (use MOD09 selected date as target)
// =====================
var mod15IC_raw = ee.ImageCollection('MODIS/061/MOD15A2H')
  .select(['Lai_500m']);

var mod15Raw = getClosestImage(mod15IC_raw, mod09Date, windowDays);
var mod15Date = ee.Date(mod15Raw.get('system:time_start'));
print('Selected MOD15A2H nearest date:', mod15Date);

// LAI valid range raw: 0~100 (scaled 0~10)
var laiRaw = mod15Raw.select('Lai_500m');
var laiValid = laiRaw.gte(0).and(laiRaw.lte(100));

// Scale factor 0.1
var laiScaled = laiRaw.updateMask(laiValid)
  .multiply(0.1)
  .rename('LAI')
  .toFloat();

// Map display
var laiShow = vizClip(laiScaled, roi, exportScale);
Map.addLayer(laiShow, {min:0, max:6}, 'MOD15A2H LAI (scaled, ROI)');

// Export LAI tif (NO clip; crop by region)
Export.image.toDrive({
  image: laiScaled,
  description: 'MOD15A2H_LAI_near_' + targetDateStr.replace(/-/g,'') + '_ROI5km',
  fileNamePrefix: 'MOD15A2H_LAI_near_' + targetDateStr.replace(/-/g,'') + '_ROI5km',
  region: roi,
  scale: exportScale,
  crs: exportCRS,
  maxPixels: 1e13
});

// =====================
// 5) (3) Prior LAI mean (2002-2025):
//     For EACH year, mean of ALL images in 6/21 ± windowDays,
//     then multi-year mean
// =====================

// Build a scaled+masked MOD15A2H LAI collection once
var mod15ScaledIC = ee.ImageCollection('MODIS/061/MOD15A2H')
  .select(['Lai_500m'])
  .map(function(img) {
    var raw = img.select('Lai_500m');
    var valid = raw.gte(0).and(raw.lte(100));
    var lai = raw.updateMask(valid)
      .multiply(0.1)
      .rename('LAI')
      .toFloat();
    return lai.copyProperties(img, ['system:time_start']);
  });

var years = ee.List.sequence(priorStartYear, priorEndYear);

// For each year: take ALL images within window -> mean
var perYearImgs = years.map(function(y) {
  y = ee.Number(y);
  var t = ee.Date.fromYMD(y, 6, 21);

  var ic = mod15ScaledIC.filterDate(
    t.advance(-windowDays, 'day'),
    t.advance(windowDays, 'day')
  );

  var n = ic.size();

  // If no image, return fully-masked image to avoid errors
  var yearlyMean = ee.Image(ee.Algorithms.If(
    n.gt(0),
    ic.mean(),
    ee.Image.constant(0).rename('LAI').updateMask(ee.Image.constant(0))
  ));

  return yearlyMean
    .set('year', y)
    .set('n_in_window', n)
    .set('system:time_start', t.millis());
});

var perYearIC = ee.ImageCollection.fromImages(perYearImgs);

// Check counts (should typically be >0)
print('Per-year image counts around 6/21 (2002-2025):',
      perYearIC.aggregate_array('n_in_window'));

// Multi-year mean
var laiPriorMean = perYearIC.mean()
  .rename('LAI_prior_mean_2002_2025')
  .toFloat();

// Map display
var priorShow = vizClip(laiPriorMean, roi, exportScale);
Map.addLayer(priorShow, {min:0, max:6}, 'LAI Prior Mean 2002-2025 (ROI)');

// Export prior mean tif (NO clip; crop by region)
Export.image.toDrive({
  image: laiPriorMean,
  description: 'MOD15A2H_LAI_priorMean_2002_2025_near_0621_ROI5km',
  fileNamePrefix: 'MOD15A2H_LAI_priorMean_2002_2025_near_0621_ROI5km',
  region: roi,
  scale: exportScale,
  crs: exportCRS,
  maxPixels: 1e13
});

提取某个点的MODIS反射率产品的时间序列代码:

/***************************************
 * MOD09A1 (061) point extraction (2020)
 * Bands: b1-b7 (sur_refl_b01 ... b07)
 * Scale factor: 0.0001
 ***************************************/

// 1) 目标点:注意顺序是 [lon, lat]
var pt = ee.Geometry.Point([2.635278, 13.645]);

Map.centerObject(pt, 8);
Map.addLayer(pt, {color: 'red'}, 'Target Point');

// 2) 时间范围(2020年)
var start = ee.Date('2020-01-01');
var end   = ee.Date('2021-01-01'); // 右开区间,写到2021-01-01更稳妥

// 3) 选择MOD09A1数据集(Collection 6.1)
var bandNamesRaw = [
  'sur_refl_b01','sur_refl_b02','sur_refl_b03',
  'sur_refl_b04','sur_refl_b05','sur_refl_b06','sur_refl_b07'
];
var bandNamesOut = ['b1','b2','b3','b4','b5','b6','b7'];

var col = ee.ImageCollection('MODIS/061/MOD09A1')
  .filterDate(start, end)
  .select(bandNamesRaw, bandNamesOut)
  .map(function(img) {
    // ---- 可选:简单剔除明显无效值(原始整数反射率通常在 -100~10000 之间更常见)
    // 这里用所有波段的 min/max 做一个统一掩膜,避免某些波段为填充值导致输出全是异常
    var raw = img; // 仍是整型
    var minAll = raw.reduce(ee.Reducer.min());
    var maxAll = raw.reduce(ee.Reducer.max());
    var mask = minAll.gt(-100).and(maxAll.lt(10000));
    raw = raw.updateMask(mask);

    // ---- 缩放因子还原反射率
    var scaled = raw.multiply(0.0001);

    return scaled.copyProperties(img, ['system:time_start']);
  });

// 4) 将每期影像在点位处取值,组织成 FeatureCollection
var fc = ee.FeatureCollection(
  col.map(function(img) {
    var t = ee.Number(img.get('system:time_start'));
    var dateStr = ee.Date(t).format('YYYY-MM-dd');

    // point extraction:用 first() 在点上取像元值
    var vals = img.reduceRegion({
      reducer: ee.Reducer.first(),
      geometry: pt,
      scale: 500,          // MOD09A1 500m
      maxPixels: 1e13
    });

    return ee.Feature(null, vals)
      .set('time', t)        // 用于时间轴
      .set('date', dateStr); // 导出更友好
  })
)
  // 如果某些日期点位被云/掩膜导致为空,这里过滤掉
  .filter(ee.Filter.notNull(bandNamesOut))
  .sort('time');

print('Extracted table (first 5 rows):', fc.limit(5));

// 5) 折线图:7个波段随时间变化
var chart = ui.Chart.feature.byFeature({
    features: fc,
    xProperty: 'time',
    yProperties: bandNamesOut
  })
  .setChartType('LineChart')
  .setOptions({
    title: 'MOD09A1 (2020) Reflectance at Point (Scaled by 0.0001)',
    hAxis: {
      title: 'Date',
      format: 'YYYY-MM-dd',
      gridlines: {count: 12},
      slantedText: true,
      slantedTextAngle: 45
    },
    vAxis: {title: 'Surface Reflectance'},
    lineWidth: 2,
    pointSize: 3,
    legend: {position: 'right'}
  });

print(chart);

// 6) 导出表格到Google Drive(CSV 可直接用 Excel 打开)
Export.table.toDrive({
  collection: fc,
  description: 'MOD09A1_Point_2020_b1_b7_scaled',
  fileNamePrefix: 'MOD09A1_Point_2020_b1_b7_scaled',
  fileFormat: 'CSV'
});

(2)工具准备

Matlab:用于编写代码,执行LAI反演全过程。

ArcMap:用于反演过程中查看出来的结果,对比不同数据源的LAI值。

4 反演方法

(1)反演过程

本次实习主要采用基于PROSAIL物理模型的贝叶斯反演方法从MODIS地表反射率数据中反演叶面积指数(LAI)。

Step1从2000-2020年MOD15A2H产品中提取同区域的LAI数据,计算多年平均值作为先验信息,建立误差协方差矩阵B。

Step2构建贝叶斯代价函数:

这里我使用了Matlab编写代价函数,方便进行调用。

function cost = functn(nopt, x)
%% ========================================================================
% 贝叶斯代价函数 - 用于LAI反演
% 
% 输入:
%   nopt - 参数维度 (此处为1, 即LAI)
%   x - 当前LAI值
%
% 输出:
%   cost - 代价函数值
%
% 代价函数形式:
%   J(x) = 0.5 * (z - h(x))' * R^(-1) * (z - h(x)) + 
%          0.5 * (x - x_b)' * B^(-1) * (x - x_b)
%
% 其中:
%   z: 观测反射率
%   h(x): PROSAIL模型模拟的反射率
%   R: 观测误差协方差矩阵
%   x_b: 先验LAI均值
%   B: 背景误差协方差
% ========================================================================

global CURRENT_OBS CURRENT_PRIOR FIXED_PARAMS_GLOBAL WEIGHT_OBS WEIGHT_PRIOR

% 参数有效性检查
if x <= 0 || x > 10
    cost = 1e10;
    return;
end

try
    %% ====================================================================
    % 1. 运行PROSAIL模型
    % ====================================================================
    % 加载光谱数据
    data = dataSpec_P5B;
    
    % 土壤反射率
    Rsoil1 = data(:, 10);  % 干土壤
    Rsoil2 = data(:, 11);  % 湿土壤
    rsoil0 = FIXED_PARAMS_GLOBAL.psoil * Rsoil1 + ...
             (1 - FIXED_PARAMS_GLOBAL.psoil) * Rsoil2;
    
    % 运行PRO4SAIL模型
    [rdot, rsot, rddt, rsdt] = PRO4SAIL(...
        FIXED_PARAMS_GLOBAL.N, ...
        FIXED_PARAMS_GLOBAL.Cab, ...
        FIXED_PARAMS_GLOBAL.Car, ...
        FIXED_PARAMS_GLOBAL.Cbrown, ...
        FIXED_PARAMS_GLOBAL.Cw, ...
        FIXED_PARAMS_GLOBAL.Cm, ...
        FIXED_PARAMS_GLOBAL.LIDFa, ...
        FIXED_PARAMS_GLOBAL.LIDFb, ...
        FIXED_PARAMS_GLOBAL.TypeLidf, ...
        x, ...  % LAI
        FIXED_PARAMS_GLOBAL.hspot, ...
        FIXED_PARAMS_GLOBAL.tts, ...
        FIXED_PARAMS_GLOBAL.tto, ...
        FIXED_PARAMS_GLOBAL.psi, ...
        rsoil0);
    
    % 计算天空光比例
    rd = pi / 180;
    skyl = 0.847 - 1.61 * sin((90 - FIXED_PARAMS_GLOBAL.tts) * rd) + ...
           1.04 * sin((90 - FIXED_PARAMS_GLOBAL.tts) * rd)^2;
    
    % 直射和漫射光
    Es = data(:, 8);
    Ed = data(:, 9);
    PARdiro = (1 - skyl) * Es;
    PARdifo = skyl * Ed;
    
    % 计算方向反射率
    resv = (rdot .* PARdifo + rsot .* PARdiro) ./ (PARdiro + PARdifo);
    
    %% ====================================================================
    % 2. 提取对应MODIS波段的模拟反射率
    % ====================================================================
    % MODIS波段中心波长 (nm)
    modis_bands = [645, 858.5, 469, 555, 1240, 1640, 2130];
    wavelengths = data(:, 1);
    
    % 提取7个MODIS波段的模拟反射率
    simulated_ref = zeros(7, 1);
    for i = 1:7
        [~, idx] = min(abs(wavelengths - modis_bands(i)));
        simulated_ref(i) = resv(idx);
    end
    
    %% ====================================================================
    % 3. 计算观测项 (Observation Term)
    % ====================================================================
    % 观测误差标准差 (假设为反射率的5%)
    obs_error_std = 0.05;
    
    % 计算残差
    residual = CURRENT_OBS - simulated_ref;
    
    % 观测项代价 (假设R为对角矩阵)
    cost_obs = 0.5 * sum((residual / obs_error_std).^2);
    
    %% ====================================================================
    % 4. 计算先验项 (Prior Term)
    % ====================================================================
    % 先验误差标准差 (LAI的标准差,假设为1.0)
    prior_error_std = 1.0;
    
    % 先验项代价
    cost_prior = 0.5 * ((x - CURRENT_PRIOR) / prior_error_std)^2;
    
    %% ====================================================================
    % 5. 总代价函数
    % ====================================================================
    cost = WEIGHT_OBS * cost_obs + WEIGHT_PRIOR * cost_prior;
    
    % 检查cost是否为有限数
    if ~isfinite(cost)
        cost = 1e10;
    end
    
catch ME
    % 如果发生错误,返回一个大的代价值
    cost = 1e10;
end

end

式子中,第一项为观测项,第二项是先验项,其中Z是观测反射率,h(x)是ProSAIL模型模拟的反射率。代价函数的构建通过编写matlab函数实现。

Step3采用SCEUA(Shuffled Complex Evolution - University of Arizona)全局优化算法最小化代价函数,反演得到LAI结果。

SCE-UA算法的实现函数:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [bestx,bestf] = sceua(x0,bl,bu,maxn,kstop,pcento,peps,ngs,iseed,iniflg)

% This is the subroutine implementing the SCE algorithm, 
% written by Q.Duan, 9/2004
%
% Definition:
%  x0 = the initial parameter array at the start;
%     = the optimized parameter array at the end;
%  f0 = the objective function value corresponding to the initial parameters
%     = the objective function value corresponding to the optimized parameters
%  bl = the lower bound of the parameters
%  bu = the upper bound of the parameters
%  iseed = the random seed number (for repetetive testing purpose)
%  iniflg = flag for initial parameter array (=1, included it in initial
%           population; otherwise, not included)
%  ngs = number of complexes (sub-populations)
%  npg = number of members in a complex 
%  nps = number of members in a simplex
%  nspl = number of evolution steps for each complex before shuffling
%  mings = minimum number of complexes required during the optimization process
%  maxn = maximum number of function evaluations allowed during optimization
%  kstop = maximum number of evolution loops before convergency
%  percento = the percentage change allowed in kstop loops before convergency

% LIST OF LOCAL VARIABLES
%    x(.,.) = coordinates of points in the population
%    xf(.) = function values of x(.,.)
%    xx(.) = coordinates of a single point in x
%    cx(.,.) = coordinates of points in a complex
%    cf(.) = function values of cx(.,.)
%    s(.,.) = coordinates of points in the current simplex
%    sf(.) = function values of s(.,.)
%    bestx(.) = best point at current shuffling loop
%    bestf = function value of bestx(.)
%    worstx(.) = worst point at current shuffling loop
%    worstf = function value of worstx(.)
%    xnstd(.) = standard deviation of parameters in the population
%    gnrng = normalized geometri%mean of parameter ranges
%    lcs(.) = indices locating position of s(.,.) in x(.,.)
%    bound(.) = bound on ith variable being optimized
%    ngs1 = number of complexes in current population
%    ngs2 = number of complexes in last population
%    iseed1 = current random seed
%    criter(.) = vector containing the best criterion values of the last
%                10 shuffling loops

global BESTX BESTF ICALL PX PF

% Initialize SCE parameters:
nopt=length(x0);
npg=2*nopt+1;
nps=nopt+1;
nspl=npg;
mings=ngs;
npt=npg*ngs;

bound = bu-bl;

% Create an initial population to fill array x(npt,nopt):
rand('seed',iseed);
x=zeros(npt,nopt);
for i=1:npt;
    x(i,:)=bl+rand(1,nopt).*bound;
end;

if iniflg==1; x(1,:)=x0; end;

nloop=0;
icall=0;
for i=1:npt;
    xf(i) = functn(nopt,x(i,:));
    icall = icall + 1;
end;
f0=xf(1);

% Sort the population in order of increasing function values;
[xf,idx]=sort(xf);
x=x(idx,:);

% Record the best and worst points;
bestx=x(1,:); bestf=xf(1);
worstx=x(npt,:); worstf=xf(npt);
BESTF=bestf; BESTX=bestx;ICALL=icall;

% Compute the standard deviation for each parameter
xnstd=std(x);

% Computes the normalized geometric range of the parameters
gnrng=exp(mean(log((max(x)-min(x))./bound)));

disp('The Initial Loop: 0');
disp(['BESTF  : ' num2str(bestf)]);
disp(['BESTX  : ' num2str(bestx)]);
disp(['WORSTF : ' num2str(worstf)]);
disp(['WORSTX : ' num2str(worstx)]);
disp(' ');

% Check for convergency;
if icall >= maxn;
    disp('*** OPTIMIZATION SEARCH TERMINATED BECAUSE THE LIMIT');
    disp('ON THE MAXIMUM NUMBER OF TRIALS ');
    disp(maxn);
    disp('HAS BEEN EXCEEDED.  SEARCH WAS STOPPED AT TRIAL NUMBER:');
    disp(icall);
    disp('OF THE INITIAL LOOP!');
end;

if gnrng < peps;
    disp('THE POPULATION HAS CONVERGED TO A PRESPECIFIED SMALL PARAMETER SPACE');
end;

% Begin evolution loops:
nloop = 0;
criter=[];
criter_change=1e+5;

while icallpeps & criter_change>pcento;
    nloop=nloop+1;
    
    % Loop on complexes (sub-populations);
    for igs = 1: ngs;
    
        % Partition the population into complexes (sub-populations);
        k1=1:npg;
        k2=(k1-1)*ngs+igs;
        cx(k1,:) = x(k2,:);
        cf(k1) = xf(k2);
        
        % Evolve sub-population igs for nspl steps:
        for loop=1:nspl;
            
            % Select simplex by sampling the complex according to a linear
            % probability distribution
            lcs(1) = 1;
            for k3=2:nps;
                for iter=1:1000;
                    lpos = 1 + floor(npg+0.5-sqrt((npg+0.5)^2 - npg*(npg+1)*rand));
                    idx=find(lcs(1:k3-1)==lpos); if isempty(idx); break; end;
                end;
                lcs(k3) = lpos;
            end;
            lcs=sort(lcs);

            % Construct the simplex:
            s = zeros(nps,nopt);
            s=cx(lcs,:); sf = cf(lcs);
            
            [snew,fnew,icall]=cceua(s,sf,bl,bu,icall,maxn);

            % Replace the worst point in Simplex with the new point:
            s(nps,:) = snew; sf(nps) = fnew;
            
            % Replace the simplex into the complex;
            cx(lcs,:) = s;
            cf(lcs) = sf;
            
            % Sort the complex;
            [cf,idx] = sort(cf); cx=cx(idx,:);
            
        % End of Inner Loop for Competitive Evolution of Simplexes
        end;

        % Replace the complex back into the population;
        x(k2,:) = cx(k1,:);
        xf(k2) = cf(k1);
    
    % End of Loop on Complex Evolution;
    end;
    
    % Shuffled the complexes;
    [xf,idx] = sort(xf); x=x(idx,:);
    PX=x; PF=xf;
    
    % Record the best and worst points;
    bestx=x(1,:); bestf=xf(1);
    worstx=x(npt,:); worstf=xf(npt);
    BESTX=[BESTX;bestx]; BESTF=[BESTF;bestf];ICALL=[ICALL;icall];

    % Compute the standard deviation for each parameter
    xnstd=std(x);

    % Computes the normalized geometric range of the parameters
    gnrng=exp(mean(log((max(x)-min(x))./bound)));

    disp(['Evolution Loop: ' num2str(nloop) '  - Trial - ' num2str(icall)]);
    disp(['BESTF  : ' num2str(bestf)]);
    disp(['BESTX  : ' num2str(bestx)]);
    disp(['WORSTF : ' num2str(worstf)]);
    disp(['WORSTX : ' num2str(worstx)]);
    disp(' ');

    % Check for convergency;
    if icall >= maxn;
        disp('*** OPTIMIZATION SEARCH TERMINATED BECAUSE THE LIMIT');
        disp(['ON THE MAXIMUM NUMBER OF TRIALS ' num2str(maxn) ' HAS BEEN EXCEEDED!']);
    end;

    if gnrng < peps;
        disp('THE POPULATION HAS CONVERGED TO A PRESPECIFIED SMALL PARAMETER SPACE');
    end;

    criter=[criter;bestf];
    if (nloop >= kstop);
        criter_change=abs(criter(nloop)-criter(nloop-kstop+1))*100;
        criter_change=criter_change/mean(abs(criter(nloop-kstop+1:nloop)));
        if criter_change < pcento;
            disp(['THE BEST POINT HAS IMPROVED IN LAST ' num2str(kstop) ' LOOPS BY ', ...
                  'LESS THAN THE THRESHOLD ' num2str(pcento) '%']);
            disp('CONVERGENCY HAS ACHIEVED BASED ON OBJECTIVE FUNCTION CRITERIA!!!')
        end;
    end;
    
% End of the Outer Loops
end;

disp(['SEARCH WAS STOPPED AT TRIAL NUMBER: ' num2str(icall)]);
disp(['NORMALIZED GEOMETRIC RANGE = ' num2str(gnrng)]);
disp(['THE BEST POINT HAS IMPROVED IN LAST ' num2str(kstop) ' LOOPS BY ', ...
       num2str(criter_change) '%']);

% END of Subroutine sceua
return;

与之配套的还需要CCEUA函数,代码如下:

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function [snew,fnew,icall]=cceua(s,sf,bl,bu,icall,maxn)
%  This is the subroutine for generating a new point in a simplex
%
%   s(.,.) = the sorted simplex in order of increasing function values
%   s(.) = function values in increasing order
%
% LIST OF LOCAL VARIABLES
%   sb(.) = the best point of the simplex
%   sw(.) = the worst point of the simplex
%   w2(.) = the second worst point of the simplex
%   fw = function value of the worst point
%   ce(.) = the centroid of the simplex excluding wo
%   snew(.) = new point generated from the simplex
%   iviol = flag indicating if constraints are violated
%         = 1 , yes
%         = 0 , no

[nps,nopt]=size(s);
n = nps;
m = nopt;
alpha = 1.0;
beta = 0.5;

% Assign the best and worst points:
sb=s(1,:); fb=sf(1);
sw=s(n,:); fw=sf(n);

% Compute the centroid of the simplex excluding the worst point:
ce=mean(s(1:n-1,:));

% Attempt a reflection point
snew = ce + alpha*(ce-sw);

% Check if is outside the bounds:
ibound=0;
s1=snew-bl; idx=find(s1<0); if ~isempty(idx); ibound=1; end;
s1=bu-snew; idx=find(s1<0); if ~isempty(idx); ibound=2; end;

if ibound >=1; 
    snew = bl + rand(1,nopt).*(bu-bl);
end;
fnew = functn(nopt,snew);
icall = icall + 1;

% Reflection failed; now attempt a contraction point:
if fnew > fw;
    snew = sw + beta*(ce-sw);
    fnew = functn(nopt,snew);
    icall = icall + 1;

% Both reflection and contraction have failed, attempt a random point;
    if fnew > fw;
        snew = bl + rand(1,nopt).*(bu-bl);
        fnew = functn(nopt,snew);
        icall = icall + 1;
    end;
end;

% END OF CCE
return;

其中PROSAIL模型耦合了PROSPECT-5B叶片光学模型和4SAIL冠层辐射传输模型,通过迭代优化使模拟的7个MODIS波段反射率与观测值拟合,并受先验信息约束以提高反演稳定性和精度。

Step4输出的反演LAI结果,和地面站点以及同日期的MODIS的LAI数据进行对比,计算反演结果的精度,此处主要采用散点图的形式进行。

图 基于物理模型的LAI反演框架

站点所在像元一年的LAI反演的方式与上面类似,只是将空间上的逐像元反演转化为单个像元在时间序列上的反演。只需获取像元点的MODIS波段反射率数据即可。

(2)ProSAIL模型介绍

本次实习用到的模型为PROSAIL模型,综合课程讲解和文献资料,现对模型介绍如下:

随着光学遥感技术的发展,辐射传输模型致力于理解植物冠层对光的截获,并根据生物物理特征解释植被反射率。PROSAIL模型便是一种经典的辐射传输模型,由PROSPECT叶片光学特性模型和 SAILH 冠层结构模型耦合得到,目前已被广泛用于研究太阳辐射域内植物冠层的光谱和方向反射率,以及生物物理化学参数反演等研究。

图 PROSAIL模型参数示意图

ProSAIL模型模拟的过程采用ProSAI_5B包进行,需要从其他渠道获取,如您有需要,也可以私信小编进行获取。

(3)SCE-UA算法介绍

SCE-UA算法由美国亚利桑那州大学水文与水资源系的Qingyun Duan博士提出。它的基本原理是通过把参数空间里的种群分成若干个子群,每个子群内部用单纯形的操作沿着下降方向搜索,从而在局部快速逼近更优解。SCE-UA综合了确定性搜索、随机搜索和生物竞争进化等方法的优点, 引入种群概念, 复合形点在可行域内随机生成和竞争演化[2-4]。

图 SCE-UA算法流程图(宋星原等,2009)

SCE-UA算法的实现过程主要通过老师分享的代码包来实现,通过调用编写的代价函数,执行迭代过程。站点小区域的主程序如下:

%% ========================================================================
% 草地LAI反演 - 标准贝叶斯公式 + SCE-UA算法 - 完整版
% 
% 代价函数: J(x) = 1/2*(z-h(x))'*R^(-1)*(z-h(x)) + 1/2*(x-x_b)'*B^(-1)*(x-x_b)
% 优化算法: SCE-UA (Shuffled Complex Evolution)
% 站点: Wankama 2005草地
%% ========================================================================
clear; clc; close all;

fprintf('================================================================
');
fprintf('  草地LAI反演 - 标准贝叶斯公式 + SCE-UA算法
');
fprintf('================================================================
');
fprintf('站点: Wankama 2005
');
fprintf('日期: 2005-06-27
');
fprintf('================================================================
');

addpath('D:Duyan
emote_sensingLAIGrasslandGrassland_LAI_Inversion_PackageGrassland_LAI_Inversion_Package');

%% ========================================================================
% 1. 数据路径设置
%% ========================================================================
data_dir = 'D:Duyan
emote_sensingLAIGrasslandGEE_MODIS';
date_str = '20050627';

ref_files = cell(7,1);
for i = 1:7
    ref_files{i} = fullfile(data_dir, sprintf('MOD09A1_near_%s_ROI5km_b%d.tif', date_str, i));
end
modis_lai_file = fullfile(data_dir, sprintf('MOD15A2H_LAI_near_%s_ROI5km.tif', date_str));
prior_lai_file = fullfile(data_dir, 'MOD15A2H_LAI_priorMean_2002_2025_near_0627_ROI5km.tif');
ground_data_file = fullfile(data_dir, 'Wankama2005GroundData_latlon.xlsx');

output_dir = 'D:Duyan
emote_sensingLAIGrasslandGrassland_LAI_Inversion_PackageGrassland_LAI_Inversion_Packageoutputs';
if ~exist(output_dir, 'dir'), mkdir(output_dir); end

%% ========================================================================
% 2. 读取遥感数据
%% ========================================================================
fprintf('
正在读取数据...
');

[ref_b1, R] = readgeoraster(ref_files{1});
[nrows, ncols] = size(ref_b1);
fprintf('影像尺寸: %d x %d
', nrows, ncols);

reflectance = zeros(nrows, ncols, 7);
for i = 1:7
    reflectance(:,:,i) = readgeoraster(ref_files{i});
    fprintf('  波段%d读取完成
', i);
end

modis_lai = readgeoraster(modis_lai_file);
prior_lai_mean = readgeoraster(prior_lai_file);

% 处理无效值
reflectance(reflectance < 0 | reflectance > 1) = NaN;
modis_lai(modis_lai < 0 | modis_lai > 10) = NaN;
prior_lai_mean(prior_lai_mean < 0 | prior_lai_mean > 10) = NaN;

% 先验LAI统计
prior_valid = prior_lai_mean(~isnan(prior_lai_mean) & prior_lai_mean > 0);
fprintf('
先验LAI统计:
');
fprintf('  范围: [%.6f, %.6f]
', min(prior_valid), max(prior_valid));
fprintf('  均值: %.6f ± %.6f
', mean(prior_valid), std(prior_valid));

%% ========================================================================
% 3. 读取地面观测数据
%% ========================================================================
try
    ground_data = readtable(ground_data_file);
    fprintf('
地面观测样点: %d
', height(ground_data));
catch
    fprintf('
警告: 无法读取地面数据
');
    ground_data = [];
end

%% ========================================================================
% 4. 贝叶斯参数设置
%% ========================================================================
fprintf('
================================================================
');
fprintf('  贝叶斯反演参数设置
');
fprintf('================================================================
');

% PROSAIL模型参数 (草地)
fixed_params = struct();
fixed_params.N = 1.3;
fixed_params.Cab = 35;
fixed_params.Car = 9;
fixed_params.Cbrown = 0.0;
fixed_params.Cw = 0.010;
fixed_params.Cm = 0.004;
fixed_params.psoil = 0.4;
fixed_params.LIDFa = 70;
fixed_params.LIDFb = 0;
fixed_params.TypeLidf = 2;
fixed_params.hspot = 0.01;
fixed_params.tts = 30;
fixed_params.tto = 10;
fixed_params.psi = 0;

fprintf('
PROSAIL参数 (草地):
');
fprintf('  N=%.1f, Cab=%d, Cw=%.3f, LIDFa=%d°
', ...
        fixed_params.N, fixed_params.Cab, fixed_params.Cw, fixed_params.LIDFa);

% 协方差矩阵设置
obs_error_std = 0.03;
R_matrix = (obs_error_std^2) * eye(7);

prior_error_std = 0.5;
B_variance = prior_error_std^2;

fprintf('
协方差矩阵:
');
fprintf('  R: 观测误差协方差 (对角,标准差=%.3f)
', obs_error_std);
fprintf('  B: 背景误差方差 (%.4f)
', B_variance);

% LAI范围
lai_min = max(0.05, min(prior_valid) - 0.15);
lai_max = min(5.0, max(prior_valid) + 1.0);
fprintf('
LAI反演范围: [%.4f, %.4f]
', lai_min, lai_max);

% SCE-UA参数
sce_params = struct();
sce_params.maxn = 10000;
sce_params.kstop = 15;
sce_params.pcento = 0.01;
sce_params.peps = 0.001;
sce_params.ngs = 5;
sce_params.iseed = 123;
sce_params.iniflg = 1;

fprintf('
SCE-UA参数: maxn=%d, pcento=%.2f%%
', sce_params.maxn, sce_params.pcento);

%% ========================================================================
% 5. 逐像元LAI反演
%% ========================================================================
fprintf('
================================================================
');
fprintf('  开始逐像元LAI反演 (SCE-UA)
');
fprintf('================================================================
');

inverted_lai = nan(nrows, ncols);
convergence_flag = zeros(nrows, ncols);
cost_values = nan(nrows, ncols);

valid_pixels = 0;
total_pixels = nrows * ncols;

global CURRENT_OBS CURRENT_PRIOR FIXED_PARAMS_GLOBAL ...
       OBS_COV_MATRIX PRIOR_VARIANCE

FIXED_PARAMS_GLOBAL = fixed_params;
OBS_COV_MATRIX = R_matrix;
PRIOR_VARIANCE = B_variance;

tic;

for i = 1:nrows
    for j = 1:ncols
        if mod((i-1)*ncols + j, 20) == 0
            fprintf('  进度: %d/%d (%.1f%%)
', (i-1)*ncols+j, total_pixels, ...
                    ((i-1)*ncols+j)/total_pixels*100);
        end
        
        pixel_ref = squeeze(reflectance(i, j, :));
        
        if any(isnan(pixel_ref)) || all(pixel_ref == 0) || any(pixel_ref < 0.001)
            continue;
        end
        
        prior_lai_pixel = prior_lai_mean(i, j);
        if isnan(prior_lai_pixel) || prior_lai_pixel <= 0
            prior_lai_pixel = mean(prior_valid);
        end
        
        CURRENT_OBS = pixel_ref;
        CURRENT_PRIOR = prior_lai_pixel;
        lai_init = prior_lai_pixel;
        
        try
            [best_lai, best_cost, exitflag] = sceua(@functn, ...
                lai_init, lai_min, lai_max, ...
                sce_params.maxn, sce_params.kstop, ...
                sce_params.pcento, sce_params.peps, ...
                sce_params.ngs, sce_params.iseed, ...
                sce_params.iniflg);
            
            if isnan(best_lai) || isinf(best_cost) || best_cost > 1e10
                best_lai = prior_lai_pixel;
                exitflag = -1;
            end
            
            best_lai = max(lai_min, min(lai_max, best_lai));
            
            inverted_lai(i, j) = best_lai;
            cost_values(i, j) = best_cost;
            convergence_flag(i, j) = (exitflag >= 0);
            valid_pixels = valid_pixels + 1;
            
        catch
            inverted_lai(i, j) = prior_lai_pixel;
        end
    end
end

elapsed_time = toc;

fprintf('
反演完成! 用时: %.1f分钟
', elapsed_time/60);
fprintf('  有效像元: %d/%d (%.1f%%)
', valid_pixels, total_pixels, ...
        valid_pixels/total_pixels*100);

valid_lai = inverted_lai(~isnan(inverted_lai) & inverted_lai > 0);
fprintf('
反演LAI统计:
');
fprintf('  范围: [%.6f, %.6f]
', min(valid_lai), max(valid_lai));
fprintf('  均值: %.6f ± %.6f
', mean(valid_lai), std(valid_lai));

converged = sum(convergence_flag(:));
fprintf('
收敛率: %.1f%%
', converged/valid_pixels*100);

%% ========================================================================
% 6. 保存结果
%% ========================================================================
fprintf('
正在保存结果...
');

geotiffwrite(fullfile(output_dir, sprintf('Grassland_Bayesian_LAI_%s.tif', date_str)), ...
             inverted_lai, R);
geotiffwrite(fullfile(output_dir, sprintf('Grassland_Bayesian_Cost_%s.tif', date_str)), ...
             cost_values, R);
geotiffwrite(fullfile(output_dir, sprintf('Grassland_Bayesian_Convergence_%s.tif', date_str)), ...
             convergence_flag, R);

%% ========================================================================
% 7. 生成所需图表
%% ========================================================================
fprintf('
================================================================
');
fprintf('  生成可视化图表
');
fprintf('================================================================
');

% ------------------------------------------------------------------------
% 图1: 四张LAI对比图 (反演、MODIS、先验、差值)
% ------------------------------------------------------------------------
fprintf('  生成图1: LAI对比图...
');

figure('Position', [100, 100, 1800, 900]);

% 子图1: 反演LAI
subplot(2,2,1);
imagesc(inverted_lai);
h1 = colorbar;
ylabel(h1, 'LAI', 'FontSize', 10);
inv_min = min(valid_lai); inv_max = max(valid_lai);
caxis([inv_min*0.95 inv_max*1.05]);
title(sprintf('反演LAI (贝叶斯+SCE-UA)
范围: [%.4f, %.4f]', inv_min, inv_max), ...
      'FontSize', 12, 'FontWeight', 'bold');
axis image;
colormap(jet);
xlabel(sprintf('均值: %.4f, 标准差: %.4f', mean(valid_lai), std(valid_lai)), ...
       'FontSize', 10);

% 子图2: MODIS LAI
subplot(2,2,2);
imagesc(modis_lai);
h2 = colorbar;
ylabel(h2, 'LAI', 'FontSize', 10);
modis_valid = modis_lai(~isnan(modis_lai) & modis_lai > 0);
modis_min = min(modis_valid); modis_max = max(modis_valid);
caxis([modis_min*0.95 modis_max*1.05]);
title(sprintf('MODIS LAI产品
范围: [%.4f, %.4f]', modis_min, modis_max), ...
      'FontSize', 12, 'FontWeight', 'bold');
axis image;
colormap(jet);
xlabel(sprintf('均值: %.4f, 标准差: %.4f', mean(modis_valid), std(modis_valid)), ...
       'FontSize', 10);

% 子图3: 先验LAI (多年均值)
subplot(2,2,3);
imagesc(prior_lai_mean);
h3 = colorbar;
ylabel(h3, 'LAI', 'FontSize', 10);
prior_min = min(prior_valid); prior_max = max(prior_valid);
caxis([prior_min*0.95 prior_max*1.05]);
title(sprintf('先验LAI (多年均值 2002-2025)
范围: [%.6f, %.6f]', prior_min, prior_max), ...
      'FontSize', 12, 'FontWeight', 'bold');
axis image;
colormap(jet);
xlabel(sprintf('均值: %.6f, 标准差: %.6f', mean(prior_valid), std(prior_valid)), ...
       'FontSize', 10);

% 子图4: 差值图 (反演 - MODIS)
subplot(2,2,4);
diff_lai = inverted_lai - modis_lai;
imagesc(diff_lai);
h4 = colorbar;
ylabel(h4, 'LAI差值', 'FontSize', 10);
diff_valid = diff_lai(~isnan(diff_lai));
diff_abs_max = max(abs(diff_valid));
caxis([-diff_abs_max diff_abs_max]);
title(sprintf('差值图 (反演LAI - MODIS LAI)
范围: [%.4f, %.4f]', ...
      min(diff_valid), max(diff_valid)), ...
      'FontSize', 12, 'FontWeight', 'bold');
axis image;
colormap(gca, redblue);
xlabel(sprintf('均值: %.4f, 标准差: %.4f', mean(diff_valid), std(diff_valid)), ...
       'FontSize', 10);

sgtitle('草地LAI反演结果对比 (标准贝叶斯公式+SCE-UA)', ...
        'FontSize', 14, 'FontWeight', 'bold');

saveas(gcf, fullfile(output_dir, 'Grassland_Bayesian_LAI_Comparison.png'));
fprintf('    已保存: Grassland_Bayesian_LAI_Comparison.png
');

% ------------------------------------------------------------------------
% 图2: 反演LAI直方图
% ------------------------------------------------------------------------
fprintf('  生成图2: 反演LAI直方图...
');

figure('Position', [100, 100, 900, 700]);
histogram(valid_lai, 30, 'FaceColor', [0.2 0.6 0.8], 'EdgeColor', 'black');
hold on;

% 添加统计线
xline(mean(valid_lai), 'r--', 'LineWidth', 2, 'Label', sprintf('均值: %.4f', mean(valid_lai)));
xline(median(valid_lai), 'g--', 'LineWidth', 2, 'Label', sprintf('中位数: %.4f', median(valid_lai)));

xlabel('LAI', 'FontSize', 12, 'FontWeight', 'bold');
ylabel('频数', 'FontSize', 12, 'FontWeight', 'bold');
title('反演LAI分布直方图', 'FontSize', 14, 'FontWeight', 'bold');
grid on;

% 添加统计信息文本框
dim = [0.15 0.7 0.3 0.2];
str = {sprintf('样本数: %d', length(valid_lai)), ...
       sprintf('范围: [%.4f, %.4f]', min(valid_lai), max(valid_lai)), ...
       sprintf('均值: %.6f', mean(valid_lai)), ...
       sprintf('标准差: %.6f', std(valid_lai)), ...
       sprintf('中位数: %.6f', median(valid_lai)), ...
       sprintf('四分位距: %.6f', iqr(valid_lai))};
annotation('textbox', dim, 'String', str, 'FitBoxToText', 'on', ...
           'BackgroundColor', 'white', 'EdgeColor', 'black', 'FontSize', 10);

saveas(gcf, fullfile(output_dir, 'Grassland_Bayesian_LAI_Histogram.png'));
fprintf('    已保存: Grassland_Bayesian_LAI_Histogram.png
');

% ------------------------------------------------------------------------
% 图3: 散点图1 - 反演LAI vs MODIS LAI
% ------------------------------------------------------------------------
fprintf('  生成图3: 反演LAI vs MODIS LAI散点图...
');

valid_mask = ~isnan(inverted_lai) & ~isnan(modis_lai) & ...
             inverted_lai > 0 & modis_lai > 0;
inv_lai_vec = inverted_lai(valid_mask);
modis_lai_vec = modis_lai(valid_mask);

figure('Position', [100, 100, 900, 700]);
scatter(modis_lai_vec, inv_lai_vec, 35, 'filled', 'MarkerFaceAlpha', 0.6);
hold on;

% 自适应坐标轴
all_lai = [inv_lai_vec; modis_lai_vec];
axis_min = max(0, min(all_lai) * 0.90);
axis_max = max(all_lai) * 1.10;

% 1:1线
plot([axis_min axis_max], [axis_min axis_max], 'r--', 'LineWidth', 2.5);

% 线性拟合
p = polyfit(modis_lai_vec, inv_lai_vec, 1);
x_fit = linspace(axis_min, axis_max, 100);
y_fit = polyval(p, x_fit);
plot(x_fit, y_fit, 'b-', 'LineWidth', 2);

% 统计指标
rmse = sqrt(mean((inv_lai_vec - modis_lai_vec).^2));
bias = mean(inv_lai_vec - modis_lai_vec);
r = corrcoef(inv_lai_vec, modis_lai_vec);
r2 = r(1,2)^2;
mae = mean(abs(inv_lai_vec - modis_lai_vec));

xlabel('MODIS LAI', 'FontSize', 13, 'FontWeight', 'bold');
ylabel('反演LAI (贝叶斯+SCE-UA)', 'FontSize', 13, 'FontWeight', 'bold');
title('反演LAI vs MODIS LAI', 'FontSize', 14, 'FontWeight', 'bold');
grid on;
axis equal;
xlim([axis_min axis_max]);
ylim([axis_min axis_max]);

% 统计信息
text_x = axis_min + (axis_max - axis_min) * 0.05;
text_y = axis_max - (axis_max - axis_min) * 0.30;
text_str = sprintf(['R² = %.4f
' ...
                    'RMSE = %.6f
' ...
                    'MAE = %.6f
' ...
                    'Bias = %.6f
' ...
                    'y = %.3fx + %.3f
' ...
                    'N = %d'], ...
                   r2, rmse, mae, bias, p(1), p(2), length(inv_lai_vec));
text(text_x, text_y, text_str, 'FontSize', 11, ...
     'BackgroundColor', 'white', 'EdgeColor', 'black', ...
     'VerticalAlignment', 'top');

legend('数据点', '1:1线', '拟合线', 'Location', 'southeast', 'FontSize', 10);

saveas(gcf, fullfile(output_dir, 'Grassland_Bayesian_Scatter_MODIS.png'));
fprintf('    已保存: Grassland_Bayesian_Scatter_MODIS.png
');

% ------------------------------------------------------------------------
% 图4: 散点图2 - 反演LAI vs 地面观测LAI
% ------------------------------------------------------------------------
if ~isempty(ground_data)
    fprintf('  生成图4: 反演LAI vs 地面观测LAI散点图...
');
    
    % 确定LAI列
    if ismember('LAItrue', ground_data.Properties.VariableNames)
        ground_lai_col = 'LAItrue';
    else
        lai_cols = ground_data.Properties.VariableNames(...
            contains(ground_data.Properties.VariableNames, 'LAI'));
        if ~isempty(lai_cols)
            ground_lai_col = lai_cols{1};
        else
            fprintf('    警告: 未找到地面LAI列
');
            ground_lai_col = '';
        end
    end
    
    if ~isempty(ground_lai_col)
        n_samples = height(ground_data);
        ground_lai = ground_data.(ground_lai_col);
        inv_lai_at_samples = zeros(n_samples, 1);
        
        for k = 1:n_samples
            lon = ground_data.Longitude(k);
            lat = ground_data.Latitude(k);
            [row, col] = geographicToDiscrete(R, lat, lon);
            
            if row >= 1 && row <= nrows && col >= 1 && col <= ncols
                inv_lai_at_samples(k) = inverted_lai(round(row), round(col));
            else
                inv_lai_at_samples(k) = NaN;
            end
        end
        
        valid_samples = ~isnan(inv_lai_at_samples) & ~isnan(ground_lai) & ...
                        inv_lai_at_samples > 0 & ground_lai > 0;
        inv_lai_samples = inv_lai_at_samples(valid_samples);
        ground_lai_valid = ground_lai(valid_samples);
        
        if sum(valid_samples) > 3
            figure('Position', [100, 100, 900, 700]);
            scatter(ground_lai_valid, inv_lai_samples, 100, 'filled', ...
                    'MarkerFaceAlpha', 0.7, 'MarkerEdgeColor', 'black');
            hold on;
            
            % 自适应坐标轴
            all_lai_g = [inv_lai_samples; ground_lai_valid];
            g_axis_min = max(0, min(all_lai_g) * 0.85);
            g_axis_max = max(all_lai_g) * 1.15;
            
            % 1:1线
            plot([g_axis_min g_axis_max], [g_axis_min g_axis_max], ...
                 'r--', 'LineWidth', 2.5);
            
            % 线性拟合
            p_g = polyfit(ground_lai_valid, inv_lai_samples, 1);
            x_fit_g = linspace(g_axis_min, g_axis_max, 100);
            y_fit_g = polyval(p_g, x_fit_g);
            plot(x_fit_g, y_fit_g, 'b-', 'LineWidth', 2);
            
            % 统计指标
            rmse_g = sqrt(mean((inv_lai_samples - ground_lai_valid).^2));
            bias_g = mean(inv_lai_samples - ground_lai_valid);
            r_g = corrcoef(inv_lai_samples, ground_lai_valid);
            r2_g = r_g(1,2)^2;
            mae_g = mean(abs(inv_lai_samples - ground_lai_valid));
            
            xlabel('地面观测LAI', 'FontSize', 13, 'FontWeight', 'bold');
            ylabel('反演LAI (贝叶斯+SCE-UA)', 'FontSize', 13, 'FontWeight', 'bold');
            title('反演LAI vs 地面观测LAI', 'FontSize', 14, 'FontWeight', 'bold');
            grid on;
            axis equal;
            xlim([g_axis_min g_axis_max]);
            ylim([g_axis_min g_axis_max]);
            
            % 统计信息
            text_x_g = g_axis_min + (g_axis_max - g_axis_min) * 0.05;
            text_y_g = g_axis_max - (g_axis_max - g_axis_min) * 0.35;
            text_str_g = sprintf(['R² = %.4f
' ...
                                  'RMSE = %.6f
' ...
                                  'MAE = %.6f
' ...
                                  'Bias = %.6f
' ...
                                  'y = %.3fx + %.3f
' ...
                                  'N = %d'], ...
                                 r2_g, rmse_g, mae_g, bias_g, p_g(1), p_g(2), sum(valid_samples));
            text(text_x_g, text_y_g, text_str_g, 'FontSize', 11, ...
                 'BackgroundColor', 'white', 'EdgeColor', 'black', ...
                 'VerticalAlignment', 'top');
            
            legend('数据点', '1:1线', '拟合线', 'Location', 'southeast', 'FontSize', 10);
            
            saveas(gcf, fullfile(output_dir, 'Grassland_Bayesian_Scatter_Ground.png'));
            fprintf('    已保存: Grassland_Bayesian_Scatter_Ground.png
');
            
            fprintf('
与地面观测对比:
');
            fprintf('  RMSE: %.6f
', rmse_g);
            fprintf('  MAE:  %.6f
', mae_g);
            fprintf('  Bias: %.6f
', bias_g);
            fprintf('  R²:   %.6f
', r2_g);
        end
    end
else
    fprintf('  跳过图4: 无地面观测数据
');
end

%% ========================================================================
% 8. 保存统计报告
%% ========================================================================
fprintf('
保存统计报告...
');

results_table = table();
results_table.Metric = {'Obs_Error_Std'; 'Prior_Error_Std'; ...
                        'RMSE_MODIS'; 'MAE_MODIS'; 'Bias_MODIS'; 'R2_MODIS'; ...
                        'Inv_LAI_Min'; 'Inv_LAI_Max'; 'Inv_LAI_Mean'; 'Inv_LAI_Std'; ...
                        'Prior_LAI_Min'; 'Prior_LAI_Max'; 'Prior_LAI_Mean'; 'Prior_LAI_Std'; ...
                        'Valid_Pixels'; 'Convergence_Rate'; 'Elapsed_Time_Min'};
results_table.Value = [obs_error_std; prior_error_std; ...
                       rmse; mae; bias; r2; ...
                       min(valid_lai); max(valid_lai); mean(valid_lai); std(valid_lai); ...
                       min(prior_valid); max(prior_valid); mean(prior_valid); std(prior_valid); ...
                       valid_pixels; converged/valid_pixels; elapsed_time/60];

writetable(results_table, fullfile(output_dir, 'Grassland_Bayesian_Statistics.csv'));

fprintf('
================================================================
');
fprintf('  程序运行完成!
');
fprintf('================================================================
');
fprintf('算法: 标准贝叶斯公式 + SCE-UA
');
fprintf('反演LAI: [%.6f, %.6f], 均值=%.6f
', ...
        min(valid_lai), max(valid_lai), mean(valid_lai));
fprintf('与MODIS对比: RMSE=%.6f, R²=%.6f
', rmse, r2);
fprintf('收敛率: %.1f%%
', converged/valid_pixels*100);
fprintf('用时: %.1f分钟
', elapsed_time/60);
fprintf('================================================================
');
fprintf('
生成的图表:
');
fprintf('  1. Grassland_Bayesian_LAI_Comparison.png  (4图对比)
');
fprintf('  2. Grassland_Bayesian_LAI_Histogram.png   (直方图)
');
fprintf('  3. Grassland_Bayesian_Scatter_MODIS.png   (vs MODIS)
');
fprintf('  4. Grassland_Bayesian_Scatter_Ground.png  (vs 地面)
');
fprintf('================================================================
');

% 辅助函数: 红蓝色图
function map = redblue(m)
    if nargin < 1
        m = size(get(gcf,'colormap'),1);
    end
    r = (0:m-1)'/max(m-1,1);
    map = [max(0,1-2*r) ones(m,1)-2*abs(r-0.5) max(0,2*r-1)];
end

如果你需要反演某个像元一年的LAI的时间序列,可以使用如下的代码进行,二者还是比较类似的

%% ========================================================================
% LAI时间序列反演 - 单像元全年反演
%% ========================================================================
% 功能: 基于PROSAIL模型和SCE-UA优化算法反演单像元全年LAI时间序列
% 输入: MOD09A1反射率CSV + MOD15A2H LAI CSV
% 输出: 反演LAI时间序列 + 对比图表 + 精度统计
%
% 作者: Claude
% 日期: 2026-01-31
%% ========================================================================

clear; clc; close all;
fprintf('========================================
');
fprintf('LAI时间序列反演程序
');
fprintf('========================================
');

%% ========================================================================
% 1. 设置数据路径
%% ========================================================================
% 修改这里为你的数据路径
data_dir = 'D:Duyan
emote_sensingLAIForest';

% 输入文件
refl_file = fullfile(data_dir, 'MOD09A1_Point_2020_b1_b7_scaled.csv');
lai_file = fullfile(data_dir, 'MOD15A2H_LAI_Point_2020.csv');

% 输出目录
output_dir = fullfile(data_dir, 'output_timeseries');
if ~exist(output_dir, 'dir')
    mkdir(output_dir);
end

fprintf('数据目录: %s
', data_dir);
fprintf('输出目录: %s
', output_dir);

%% ========================================================================
% 2. 读取时间序列数据
%% ========================================================================
fprintf('
========================================
');
fprintf('读取时间序列数据
');
fprintf('========================================
');

% 读取反射率数据
fprintf('读取MOD09A1反射率数据...
');
refl_data = readtable(refl_file);
fprintf('  时间点数: %d
', height(refl_data));

% 读取MODIS LAI数据
fprintf('读取MOD15A2H LAI数据...
');
lai_data = readtable(lai_file);
fprintf('  时间点数: %d
', height(lai_data));

% 检查时间点数量是否一致
if height(refl_data) ~= height(lai_data)
    warning('反射率和LAI数据时间点数量不一致!');
end

% 提取时间序列
n_times = height(refl_data);
dates = refl_data.system_index;  % 时间列

% 提取7个波段反射率
b1 = refl_data.b1;
b2 = refl_data.b2;
b3 = refl_data.b3;
b4 = refl_data.b4;
b5 = refl_data.b5;
b6 = refl_data.b6;
b7 = refl_data.b7;

% 提取MODIS LAI
modis_lai = lai_data.LAI;

fprintf('数据读取完成!
');
fprintf('  时间范围: %s 至 %s
', string(dates(1)), string(dates(end)));
fprintf('  MODIS LAI范围: %.2f - %.2f
', min(modis_lai), max(modis_lai));

%% ========================================================================
% 3. 设置PROSAIL模型固定参数
%% ========================================================================
fprintf('
========================================
');
fprintf('设置PROSAIL模型参数
');
fprintf('========================================
');

% 叶片参数 (根据森林类型调整)
fixed_params.N = 1.5;           % 叶片结构参数
fixed_params.Cab = 45;          % 叶绿素含量 (μg/cm²) [30-60]
fixed_params.Car = 8;           % 类胡萝卜素含量 (μg/cm²)
fixed_params.Cw = 0.015;        % 等效水厚度 (cm) [0.01-0.03]
fixed_params.Cm = 0.005;        % 干物质含量 (g/cm²)
fixed_params.Cbrown = 0;        % 褐色素含量

% 冠层结构参数
fixed_params.LIDFa = 57;        % 平均叶倾角 (度) [40-70]
fixed_params.TypeLidf = 2;      % 叶倾角分布类型 (2=椭球分布)
fixed_params.lai = 3.0;         % LAI初值 (将被优化)

% 土壤和背景
fixed_params.psoil = 1.0;       % 土壤亮度系数

% 观测几何 (根据实际情况调整)
fixed_params.tts = 30;          % 太阳天顶角 (度)
fixed_params.tto = 10;          % 观测天顶角 (度)
fixed_params.psi = 0;           % 相对方位角 (度)

fprintf('PROSAIL参数设置完成
');
fprintf('  叶绿素: %.1f μg/cm²
', fixed_params.Cab);
fprintf('  水分: %.4f cm
', fixed_params.Cw);
fprintf('  平均叶倾角: %.1f°
', fixed_params.LIDFa);

%% ========================================================================
% 4. 设置SCE-UA优化参数
%% ========================================================================
fprintf('
========================================
');
fprintf('设置优化算法参数
');
fprintf('========================================
');

% SCE-UA参数
sce_params.maxn = 5000;         % 最大迭代次数 [3000-8000]
sce_params.kstop = 10;          % 收敛判断次数
sce_params.pcento = 0.1;        % 收敛阈值 (百分比)
sce_params.peps = 0.001;        % 参数空间收敛阈值
sce_params.ngs = 5;             % 复形数量 [3-7]
sce_params.iseed = 0;           % 随机种子
sce_params.iniflg = 1;          % 初始化标志

% LAI参数范围
lai_min = 0.1;                  % LAI最小值
lai_max = 7.0;                  % LAI最大值

fprintf('优化参数设置完成
');
fprintf('  最大迭代: %d
', sce_params.maxn);
fprintf('  LAI范围: [%.1f, %.1f]
', lai_min, lai_max);

%% ========================================================================
% 5. 定义全局变量供代价函数使用
%% ========================================================================
global obs_refl fixed_prosail_params

%% ========================================================================
% 6. 时间序列反演循环
%% ========================================================================
fprintf('
========================================
');
fprintf('开始时间序列反演
');
fprintf('========================================
');

% 初始化结果数组
inverted_lai = zeros(n_times, 1);
convergence_flag = zeros(n_times, 1);
iteration_count = zeros(n_times, 1);

% 记录开始时间
tic;

% 逐时间点反演
for t = 1:n_times
    if mod(t, 5) == 0 || t == 1
        fprintf('
处理时间点 %d/%d (%.1f%%)...
', t, n_times, 100*t/n_times);
    end
    
    % 提取当前时间点的7波段反射率
    current_refl = [b1(t); b2(t); b3(t); b4(t); b5(t); b6(t); b7(t)];
    
    % 检查数据有效性
    if any(isnan(current_refl)) || any(current_refl < 0) || any(current_refl > 1)
        fprintf('  警告: 时间点%d数据无效,跳过
', t);
        inverted_lai(t) = NaN;
        convergence_flag(t) = -1;
        continue;
    end
    
    % 设置全局变量
    obs_refl = current_refl;
    fixed_prosail_params = fixed_params;
    
    % 初始LAI值
    if t == 1
        % 第一个时间点:使用MODIS LAI作为初值
        x0 = modis_lai(t);
    else
        % 后续时间点:使用前一个反演结果作为初值
        if ~isnan(inverted_lai(t-1)) && inverted_lai(t-1) > 0
            x0 = inverted_lai(t-1);
        else
            x0 = modis_lai(t);
        end
    end
    
    % 确保初值在范围内
    x0 = max(lai_min, min(lai_max, x0));
    
    % 调用SCE-UA优化算法
    bl = lai_min;  % 下界
    bu = lai_max;  % 上界
    
    [bestx, bestf, icall, ~] = sceua(x0, bl, bu, sce_params.maxn, ...
        sce_params.kstop, sce_params.pcento, sce_params.peps, ...
        sce_params.ngs, sce_params.iseed, sce_params.iniflg);
    
    % 保存结果
    inverted_lai(t) = bestx;
    iteration_count(t) = icall;
    
    % 判断收敛
    if bestf < 0.01  % 代价函数很小,认为收敛
        convergence_flag(t) = 1;
    else
        convergence_flag(t) = 0;
        fprintf('  警告: 时间点%d未完全收敛 (代价函数=%.4f)
', t, bestf);
    end
    
    if mod(t, 5) == 0 || t == 1
        fprintf('  反演LAI: %.3f, MODIS LAI: %.3f, 迭代次数: %d
', ...
            inverted_lai(t), modis_lai(t), icall);
    end
end

% 记录结束时间
elapsed_time = toc;

fprintf('
========================================
');
fprintf('反演完成!
');
fprintf('========================================
');
fprintf('总耗时: %.1f 秒 (平均 %.2f 秒/点)
', elapsed_time, elapsed_time/n_times);
fprintf('收敛点数: %d/%d (%.1f%%)
', sum(convergence_flag==1), n_times, ...
    100*sum(convergence_flag==1)/n_times);
fprintf('平均迭代次数: %.0f
', mean(iteration_count(convergence_flag==1)));

%% ========================================================================
% 7. 保存结果到CSV
%% ========================================================================
fprintf('
========================================
');
fprintf('保存反演结果
');
fprintf('========================================
');

% 创建结果表格
results_table = table(dates, modis_lai, inverted_lai, convergence_flag, ...
    'VariableNames', {'Date', 'MODIS_LAI', 'Inverted_LAI', 'Converged'});

% 保存为CSV
output_csv = fullfile(output_dir, 'LAI_TimeSeries_Results_2020.csv');
writetable(results_table, output_csv);
fprintf('结果已保存: %s
', output_csv);

%% ========================================================================
% 8. 精度验证
%% ========================================================================
fprintf('
========================================
');
fprintf('精度验证统计
');
fprintf('========================================
');

% 仅使用收敛的点进行统计
valid_idx = (convergence_flag == 1) & ~isnan(inverted_lai) & ~isnan(modis_lai);
inv_valid = inverted_lai(valid_idx);
modis_valid = modis_lai(valid_idx);

if sum(valid_idx) < 3
    warning('有效数据点太少,无法进行统计分析!');
else
    % 计算精度指标
    rmse = sqrt(mean((inv_valid - modis_valid).^2));
    bias = mean(inv_valid - modis_valid);
    mae = mean(abs(inv_valid - modis_valid));
    
    % 计算R²
    ss_res = sum((inv_valid - modis_valid).^2);
    ss_tot = sum((modis_valid - mean(modis_valid)).^2);
    r2 = 1 - ss_res/ss_tot;
    
    % 显示统计结果
    fprintf('有效样本数: %d
', sum(valid_idx));
    fprintf('RMSE: %.4f
', rmse);
    fprintf('Bias: %.4f
', bias);
    fprintf('MAE: %.4f
', mae);
    fprintf('R²: %.4f
', r2);
    
    % 保存统计结果
    stats_table = table({'RMSE'; 'Bias'; 'MAE'; 'R²'; 'Valid_Points'}, ...
        [rmse; bias; mae; r2; sum(valid_idx)], ...
        'VariableNames', {'Metric', 'Value'});
    
    stats_csv = fullfile(output_dir, 'Validation_Statistics.csv');
    writetable(stats_table, stats_csv);
    fprintf('统计结果已保存: %s
', stats_csv);
end

%% ========================================================================
% 9. 绘制时间序列对比图
%% ========================================================================
fprintf('
========================================
');
fprintf('生成可视化图表
');
fprintf('========================================
');

% 转换日期格式(如果可能)
try
    date_nums = datenum(dates);
catch
    date_nums = 1:n_times;  % 如果日期转换失败,使用序号
end

% 图1: 时间序列对比图
figure('Position', [100, 100, 1200, 500]);
plot(date_nums, modis_lai, 'b-o', 'LineWidth', 1.5, 'MarkerSize', 6, ...
    'DisplayName', 'MODIS LAI');
hold on;
plot(date_nums, inverted_lai, 'r-s', 'LineWidth', 1.5, 'MarkerSize', 6, ...
    'DisplayName', 'Inverted LAI');

% 标记未收敛的点
unconverged_idx = (convergence_flag ~= 1);
if any(unconverged_idx)
    plot(date_nums(unconverged_idx), inverted_lai(unconverged_idx), ...
        'kx', 'MarkerSize', 10, 'LineWidth', 2, 'DisplayName', 'Not Converged');
end

hold off;
xlabel('Date', 'FontSize', 12, 'FontWeight', 'bold');
ylabel('LAI', 'FontSize', 12, 'FontWeight', 'bold');
title('LAI Time Series Comparison - 2020', 'FontSize', 14, 'FontWeight', 'bold');
legend('Location', 'best', 'FontSize', 11);
grid on;

% 设置日期刻度(如果日期转换成功)
if exist('datenum', 'builtin')
    datetick('x', 'mmm-yy', 'keepticks');
end

saveas(gcf, fullfile(output_dir, 'LAI_TimeSeries_Comparison.png'));
fprintf('  时间序列图已保存
');

%% ========================================================================
% 10. 绘制散点图
%% ========================================================================
if sum(valid_idx) >= 3
    figure('Position', [100, 100, 600, 600]);
    scatter(modis_valid, inv_valid, 80, 'b', 'filled', 'MarkerEdgeColor', 'k');
    hold on;
    
    % 1:1线
    min_val = min([modis_valid; inv_valid]);
    max_val = max([modis_valid; inv_valid]);
    plot([min_val, max_val], [min_val, max_val], 'k--', 'LineWidth', 1.5);
    
    % 线性拟合
    p = polyfit(modis_valid, inv_valid, 1);
    fit_x = linspace(min_val, max_val, 100);
    fit_y = polyval(p, fit_x);
    plot(fit_x, fit_y, 'r-', 'LineWidth', 2);
    
    hold off;
    xlabel('MODIS LAI', 'FontSize', 12, 'FontWeight', 'bold');
    ylabel('Inverted LAI', 'FontSize', 12, 'FontWeight', 'bold');
    title('LAI Validation Scatter Plot', 'FontSize', 14, 'FontWeight', 'bold');
    grid on;
    axis equal;
    xlim([min_val, max_val]);
    ylim([min_val, max_val]);
    
    % 添加统计信息
    text_str = sprintf('R² = %.4f
RMSE = %.4f
Bias = %.4f
N = %d', ...
        r2, rmse, bias, sum(valid_idx));
    text(0.05, 0.95, text_str, 'Units', 'normalized', 'FontSize', 11, ...
        'BackgroundColor', 'white', 'VerticalAlignment', 'top');
    
    saveas(gcf, fullfile(output_dir, 'LAI_Scatter_Plot.png'));
    fprintf('  散点图已保存
');
end

%% ========================================================================
% 11. 绘制残差分析图
%% ========================================================================
if sum(valid_idx) >= 3
    figure('Position', [100, 100, 1200, 400]);
    
    % 残差
    residuals = inv_valid - modis_valid;
    
    subplot(1, 2, 1);
    plot(date_nums(valid_idx), residuals, 'b-o', 'LineWidth', 1.5, 'MarkerSize', 6);
    hold on;
    yline(0, 'k--', 'LineWidth', 1.5);
    yline(mean(residuals), 'r--', 'LineWidth', 1.5, 'DisplayName', ...
        sprintf('Mean Bias = %.3f', bias));
    hold off;
    xlabel('Date', 'FontSize', 12, 'FontWeight', 'bold');
    ylabel('Residual (Inverted - MODIS)', 'FontSize', 12, 'FontWeight', 'bold');
    title('Residual Analysis', 'FontSize', 14, 'FontWeight', 'bold');
    legend('Location', 'best');
    grid on;
    if exist('datenum', 'builtin')
        datetick('x', 'mmm-yy', 'keepticks');
    end
    
    subplot(1, 2, 2);
    histogram(residuals, 15, 'FaceColor', 'b', 'EdgeColor', 'k');
    xlabel('Residual (Inverted - MODIS)', 'FontSize', 12, 'FontWeight', 'bold');
    ylabel('Frequency', 'FontSize', 12, 'FontWeight', 'bold');
    title('Residual Distribution', 'FontSize', 14, 'FontWeight', 'bold');
    grid on;
    
    saveas(gcf, fullfile(output_dir, 'LAI_Residual_Analysis.png'));
    fprintf('  残差分析图已保存
');
end

%% ========================================================================
% 完成
%% ========================================================================
fprintf('
========================================
');
fprintf('程序运行完成!
');
fprintf('========================================
');
fprintf('输出文件位于: %s
', output_dir);
fprintf('  1. LAI_TimeSeries_Results_2020.csv    - 反演结果CSV
');
fprintf('  2. Validation_Statistics.csv           - 精度统计
');
fprintf('  3. LAI_TimeSeries_Comparison.png       - 时间序列对比图
');
fprintf('  4. LAI_Scatter_Plot.png                - 散点验证图
');
fprintf('  5. LAI_Residual_Analysis.png           - 残差分析图
');
fprintf('========================================
');

上述代码的实现依赖于一些核心的代码包,可以私信小编联系。

5 反演结果

(1)站点附近小区域的LAI反演

本次选用以站点经纬度为中心点附近5km×5km的区域,通过全局优化算法展开函数求解,进行LAI反演,并将得到的结果和地面测量数据以及MODIS的反射率产品进行对比。得到的结果如下:

图 考虑先验信息下的反演结果-森林站点

图 考虑先验信息下的反演结果-草地站点

(2)站点所在像元一年的LAI值反演

反演站点所在像元一年的时间序列时,实习过程用的代价函数并没有考虑先验信息。

从趋势上看,反演的LAI时间序列在趋势上基本吻合了MODIS产品的LAI时间序列。据图,发现夏季的反演效果相对较好,两条线比较接近,反演的LAI略低于MODIS的叶面积指数。同时两数据的差值最小,尤其是在7月-9月;冬季反演的的效果比较差,反演的LAI显著高于MODIS的产品。

从指标评估来看,反演的LAI和MODIS提供的LAI拟合系数能够达到0.626,均方根误差为1.86,MAE为1.478,总体而言反演的精度相较于站点的小区域LAI精度要高。当然,如果能够纳入多年同一像元的LAI数据作为先验信息输入,或许能够进一步提供LAI模拟的精度。

6 学习总结

遥感反演是一项复杂的任务,病态反演问题告诉我们,实现完美的反演过程只是一种理想,我们工作的重心更应在于如何管理与约束算法求解过程的不确定性,尽管结果有待提高,但仍然是一次不错的尝试!

以上是本期关于遥感反演LAI指数的全部内容啦,欢迎交流!

本文地址:https://www.yitenyun.com/4630.html

搜索文章

Tags

#ios面试 #ios弱网 #断点续传 #ios开发 #objective-c #ios #ios缓存 #服务器 #python #pip #conda #远程工作 #kubernetes #笔记 #平面 #容器 #linux #学习方法 香港站群服务器 多IP服务器 香港站群 站群服务器 #Trae #IDE #AI 原生集成开发环境 #Trae AI #运维 #分阶段策略 #模型协议 #人工智能 #github #git #华为云 #部署上线 #动静分离 #Nginx #新人首发 #docker #开发语言 #云原生 #iventoy #VmWare #OpenEuler #后端 #数据库 #Conda # 私有索引 # 包管理 #科技 #深度学习 #自然语言处理 #神经网络 #kylin #内网穿透 #网络 #cpolar #开源 #进程控制 #低代码 #爬虫 #音视频 #银河麒麟高级服务器操作系统安装 #银河麒麟高级服务器V11配置 #设置基础软件仓库时出错 #银河麒高级服务器系统的实操教程 #生产级部署银河麒麟服务系统教程 #Linux系统的快速上手教程 #学习 #数信院生信服务器 #Rstudio #生信入门 #生信云服务器 #物联网 #websocket #MobaXterm #ubuntu #Dell #PowerEdge620 #内存 #硬盘 #RAID5 #缓存 #vscode #mobaxterm #计算机视觉 #node.js #FTP服务器 #harmonyos #鸿蒙PC #fastapi #html #css #hadoop #hbase #hive #zookeeper #spark #kafka #flink #算法 #大数据 #分布式 #华为 #unity #c# #游戏引擎 #flask #golang #java #redis #vllm #大模型 #Streamlit #Qwen #本地部署 #AI聊天机器人 #web安全 #安全 #uni-app #小程序 #notepad++ #nginx #tcp/ip #qt #C++ #RTP over RTSP #RTP over TCP #RTSP服务器 #RTP #TCP发送RTP #多个客户端访问 #IO多路复用 #回显服务器 #TCP相关API #Harbor #我的世界 #centos #ssh #android #腾讯云 #Ascend #MindIE #ide #ARM服务器 # GLM-4.6V # 多模态推理 #jvm #c++ #需求分析 #pytorch #sql #AIGC #langchain #agi #udp #微信 #Ubuntu服务器 #硬盘扩容 #命令行操作 #VMware #ModelEngine #儿童书籍 #儿童诗歌 #童话故事 #经典好书 #儿童文学 #好书推荐 #经典文学作品 #php #VS Code调试配置 #asp.net #elasticsearch #http #性能优化 #1024程序员节 #前端 #项目 #高并发 #架构 #Android #Bluedroid #云计算 #spring boot #经验分享 #安卓 #计算机网络 #SSH反向隧道 # Miniconda # Jupyter远程访问 #课程设计 #c语言 #stm32 #jar #prometheus #epoll #高级IO #凤希AI伴侣 #面试 #fiddler #AI #大模型学习 #gemini #gemini国内访问 #gemini api #gemini中转搭建 #Cloudflare #游戏 #MC #json #数据结构 #链表 #链表的销毁 #链表的排序 #链表倒置 #判断链表是否有环 #jenkins #电脑 #自动化 #jmeter #功能测试 #软件测试 #自动化测试 #职场和发展 #银河麒麟 #系统升级 #信创 #国产化 #vue.js #AI编程 #mvp #个人开发 #设计模式 #gpu算力 #grafana #asp.net大文件上传 #asp.net大文件上传下载 #asp.net大文件上传源码 #ASP.NET断点续传 #asp.net上传文件夹 #编辑器 #研发管理 #禅道 #禅道云端部署 #ping通服务器 #读不了内网数据库 #bug菌问答团队 #mcu #网络安全 #MCP #MCP服务器 #RAID #RAID技术 #磁盘 #存储 #windows #数据仓库 #AI论文写作工具 #学术论文创作 #论文效率提升 #MBA论文写作 #进程 #操作系统 #进程创建与终止 #shell #unity3d #服务器框架 #Fantasy #ollama #ai #llm #claude #django #机器学习 #推荐算法 #arm开发 #log #RustDesk #IndexTTS 2.0 #本地化部署 #信息可视化 #claude code #codex #code cli #ccusage #毕业设计 #车辆排放 #pycharm #Spring AI #STDIO协议 #Streamable-HTTP #McpTool注解 #服务器能力 #javascript #react.js #程序人生 #蓝桥杯 #生信 #阿里云 #远程桌面 #远程控制 #pencil #pencil.dev #设计 #智能手机 #journalctl #bash #mysql #openresty #lua #LobeChat #vLLM #GPU加速 #语音识别 #测试工具 #压力测试 #RAG #全链路优化 #实战教程 #openlayers #bmap #tile #server #vue #时序数据库 #网络协议 #版本控制 #Git入门 #开发工具 #代码托管 #制造 #个人博客 #openEuler #Hadoop #nas #n8n #信令服务器 #Janus #MediaSoup #嵌入式编译 #ccache #distcc #YOLO #建筑缺陷 #红外 #数据集 #ssl #智能路由器 #iphone #sqlserver #密码学 #oracle #SA-PEKS # 关键词猜测攻击 # 盲签名 # 限速机制 #模版 #函数 #类 #笔试 #树莓派4b安装系统 #apache #鸭科夫 #逃离鸭科夫 #鸭科夫联机 #鸭科夫异地联机 #开服 #ms-swift # 一锤定音 # 大模型微调 #deepseek #WEB #我的世界服务器搭建 #minecraft #diskinfo # TensorFlow # 磁盘健康 #流量监控 #cpp #LoRA # RTX 3090 # lora-scripts #laravel #企业开发 #ERP #项目实践 #.NET开发 #C#编程 #编程与数学 #CPU利用率 #Ansible #Playbook #AI服务器 #流媒体 #NAS #飞牛NAS #监控 #NVR #EasyNVR # 自动化部署 # VibeThinker #screen 命令 #macos #vuejs #eBPF #todesk #DisM++ # 系统维护 #ansible #金融 #mcp #金融投资Agent #Agent #京东云 #web #webdav #目标检测 #ida #中间件 #svn #microsoft #LLM #flutter #数码相机 #SSH #X11转发 #Miniconda #深度优先 #DFS #改行学it #创业创新 #程序员创富 #毕设 #STUN # TURN # NAT穿透 #debian #无人机 #Deepoc #具身模型 #开发板 #未来 #rustdesk #p2p #postgresql #连接数据库报错 #r-tree #聊天小程序 #cursor #YOLOFuse # Base64编码 # 多模态检测 #NFC #智能公交 #服务器计费 #数据挖掘 #FP-增长 #tdengine #涛思数据 #tensorflow #arm #gitlab #Proxmox VE #虚拟化 #企业微信 #SPA #单页应用 #spring #web3.py #交互 #embedding #visual studio code #GPU服务器 #8U #硬件架构 #NPU #CANN #麒麟OS #swagger #ui #cosmic #mariadb #SSH免密登录 # PyTorch # CUDA #LangGraph #CLI #Python #JavaScript #langgraph.json #集成测试 #微服务 #H5 #跨域 #发布上线后跨域报错 #请求接口跨域问题解决 #跨域请求代理配置 #request浏览器跨域 #单片机 #嵌入式硬件 #游戏机 #JumpServer #堡垒机 #银河麒麟操作系统 #openssh #华为交换机 #信创终端 #dify #java大文件上传 #java大文件秒传 #java大文件上传下载 #java文件传输解决方案 #处理器 #上下文工程 #langgraph #意图识别 #agent #微信小程序 #振镜 #振镜焊接 #teamviewer #sqlite #PyCharm # 远程调试 # YOLOFuse #jupyter #Linux #TCP #Socket网络编程 #wordpress #雨云 #Triton # Triton # 目标检测 #电气工程 #C# #PLC #翻译 #开源工具 #libosinfo #SRS #直播 #milvus #springboot #知识库 #web server #请求处理流程 #ComfyUI # 推理服务器 #Host #渗透测试 #SSRF #chrome #客户端 #嵌入式 #DIY机器人工房 #maven #SSH Agent Forwarding # 容器化 #政务 #nacos #银河麒麟aarch64 #rocketmq #单元测试 #测试用例 #selenium #windows11 #系统修复 #守护进程 #复用 #screen #.net #系统架构 #aws #性能 #优化 #DDR #RAM #分类 #powerbi #Clawdbot #个人助理 #数字员工 #es安装 #transformer #chatgpt #万悟 #联通元景 #智能体 #镜像 #umeditor粘贴word #ueditor粘贴word #ueditor复制word #ueditor上传word图片 #IPv6 #DNS #scala #webrtc #idm # REST API # GLM-4.6V-Flash-WEB #源码 #闲置物品交易系统 #健身房预约系统 #健身房管理系统 #健身管理系统 #视频去字幕 #jetty #java-ee #prompt #YOLOv8 # Docker镜像 #北京百思可瑞教育 #百思可瑞教育 #北京百思教育 #计算机 #OPCUA #mamba #esp32教程 #risc-v #adb #CMake #Make #C/C++ #UOS #海光K100 #统信 #vps #SSH公钥认证 # 安全加固 #Fun-ASR # 语音识别 # WebUI #算力一体机 #ai算力服务器 #青少年编程 #PyTorch #CUDA # 高并发部署 #部署 #语言模型 #DeepSeek #昇腾300I DUO #ddos #科研 #博士 #webpack #opencv #Qwen3-14B # 大模型部署 # 私有化AI #学术写作辅助 #论文创作效率提升 #AI写论文实测 #搜索引擎 #文心一言 #AI智能体 #tomcat #运维开发 #opc ua #opc #负载均衡 #前端框架 #reactjs #web3 #intellij-idea #东方仙盟 # GLM-TTS # 数据安全 #API限流 # 频率限制 # 令牌桶算法 #iBMC #UltraISO #黑群晖 #虚拟机 #无U盘 #纯小白 #支付 #蓝湖 #Axure原型发布 #1panel #vmware #select #llama #ceph #说话人验证 #声纹识别 #CAM++ #muduo库 #PTP_1588 #gPTP #uv #uvx #uv pip #npx #Ruff #pytest #模型上下文协议 #MultiServerMCPC #load_mcp_tools #load_mcp_prompt #哈希算法 #ci/cd #gitea #蓝耘智算 #散列表 #leetcode #910B #昇腾 #wsl #硬件工程 #Windows #MS #Materials #Anaconda配置云虚拟环境 #MQTT协议 #结构体 #网站 #截图工具 #批量处理图片 #图片格式转换 #图片裁剪 #https #SMTP # 内容安全 # Qwen3Guard #ONLYOFFICE #MCP 服务器 #Android16 #音频性能实战 #音频进阶 #集成学习 # 双因素认证 #服务器繁忙 #扩展屏应用开发 #android runtime #SSE # AI翻译机 # 实时翻译 #心理健康服务平台 #心理健康系统 #心理服务平台 #心理健康小程序 #数学建模 #2026年美赛C题代码 #2026年美赛 #插件 #开源软件 #媒体 #智能家居 #mybatis #spine #rust #论文笔记 #bootstrap #移动端h5网页 #调用浏览器摄像头并拍照 #开启摄像头权限 #拍照后查看与上传服务器端 #摄像头黑屏打不开问题 #系统安全 #kmeans #聚类 #idea #intellij idea #文件IO #输入输出流 #WinDbg #Windows调试 #内存转储分析 #信息与通信 #信号处理 #tcpdump # 大模型 # 模型训练 #浏览器自动化 #python #AI大模型 #程序员 #5G #Java #重构 #能源 #Smokeping #memcache #策略模式 #pve #大剑师 #nodejs面试题 #C2000 #TI #实时控制MCU #AI服务器电源 #Llama-Factory # 树莓派 # ARM架构 #paddleocr #企业级存储 #网络设备 #统信UOS #服务器操作系统 #win10 #qemu #大模型应用 #API调用 #PyInstaller打包运行 #服务端部署 #大语言模型 #UDP的API使用 #zotero #WebDAV #同步失败 #代理模式 #Anything-LLM #IDC服务器 #私有化部署 #工具集 #视觉检测 #visual studio #ESP32 #传感器 #MicroPython #RK3576 #瑞芯微 #硬件设计 #智能体来了 #智能体对传统行业冲击 #行业转型 #AI赋能 #欧拉 #儿童AI #图像生成 #星图GPU #elk #win11 #麒麟 #chat # IndexTTS 2.0 # 自动化运维 #VoxCPM-1.5-TTS # 云端GPU # PyCharm宕机 #SSH保活 #远程开发 #rdp #everything #海外服务器安装宝塔面板 #c #YOLO26 #muduo #TcpServer #accept #高并发服务器 #业界资讯 #n8n解惑 #勒索病毒 #勒索软件 #加密算法 #.bixi勒索病毒 #数据加密 #大模型开发 #rabbitmq #HistoryServer #Spark #YARN #jobhistory #实时音视频 #大模型部署 #mindie #大模型推理 #UDP套接字编程 #UDP协议 #网络测试 #postman #excel #copilot #数据分析 #微PE #硬盘克隆 #DiskGenius #模拟退火算法 #简单数论 #埃氏筛法 #交通物流 #手机h5网页浏览器 #安卓app #苹果ios APP #手机电脑开启摄像头并排查 #yum #uvicorn #uvloop #asgi #event #IO #hibernate #homelab #Lattepanda #Jellyfin #Plex #Emby #Kodi #yolov12 #研究生life #ArkUI #ArkTS #鸿蒙开发 #eureka #mongodb #rtsp #转发 #Nacos #TensorRT # 推理优化 #zabbix #三维 #3D #三维重建 #go #其他 #IntelliJ IDEA #Spring Boot #puppeteer #neo4j #NoSQL #SQL # 大模型推理 #KMS #slmgr #宝塔面板部署RustDesk #RustDesk远程控制手机 #手机远程控制 #Jetty # CosyVoice3 # 嵌入式服务器 #模型训练 #CVE-2025-61686 #漏洞 #路径遍历高危漏洞 #HeyGem # 服务器IP # 端口7860 #POC #问答 #交付 #xlwings #Excel # 代理转发 # 跳板机 #echarts # keep-alive #web服务器 #spring cloud #restful #ajax # 公钥认证 #Reactor #nfs #iscsi #机器人 # GPU租赁 # 自建服务器 #文件管理 #文件服务器 #遛狗 #MinIO服务器启动与配置详解 #clickhouse #代理 #DHCP #scanf #printf #getchar #putchar #cin #cout #scrapy #ai大模型 #eclipse #servlet #arm64 #serverless #nvidia #wpf #串口服务器 #Modbus #MOXA #GATT服务器 #蓝牙低功耗 #cesium #可视化 #硬件 #firefox #safari #排序算法 #jdk #排序 #memory mcp #Cursor #PowerBI #企业 #aiohttp #asyncio #异步 #软件 #本地生活 #电商系统 #商城 #.netcore #内存治理 #googlecloud # 模型微调 #vnstat #c++20 # 远程连接 #vp9 #Aluminium #Google #AutoDL #攻防演练 #Java web #红队 #AB包 #fpga开发 #LVDS #高速ADC #驱动开发 #Go并发 #高并发架构 #Goroutine #系统设计 #飞牛nas #fnos #Dify #ARM架构 #鲲鹏 #net core #kestrel #web-server #asp.net-core #AI技术 #指针 #GB28181 #SIP信令 #SpringBoot #视频监控 #WT-2026-0001 #QVD-2026-4572 #smartermail #系统管理 #服务 #Modbus-TCP #EMC存储 #存储维护 #NetApp存储 #screen命令 #C语言 #管道Pipe #system V #ai编程 #azure #ambari #SAP #ebs #metaerp #oracle ebs #智慧校园解决方案 #智慧校园一体化平台 #智慧校园选型 #智慧校园采购 #智慧校园软件 #智慧校园专项资金 #智慧校园定制开发 # 高并发 #数据恢复 #视频恢复 #视频修复 #RAID5恢复 #流媒体服务器恢复 #Termux #Samba #国产化OS #ShaderGraph #图形 #VMware Workstation16 # 批量管理 #RSO #机器人操作系统 #进程等待 #wait #waitpid #glibc #pdf #大模型教程 #vivado license #CVE-2025-68143 #CVE-2025-68144 #CVE-2025-68145 #html5 #计算几何 #斜率 #方向归一化 #叉积 #GPU ##租显卡 #markdown #建站 #fabric #可信计算技术 #winscp #openHiTLS #TLCP #DTLCP #商用密码算法 #平板 #零售 #智能硬件 #H5网页 #网页白屏 #H5页面空白 #资源加载问题 #打包部署后网页打不开 #HBuilderX #CTF #CPU #VMWare Tool #测评 #CCE #Dify-LLM #Flexus #ue5 #bond #服务器链路聚合 #网卡绑定 # 远程运维 #sentinel #程序开发 #程序设计 #计算机毕业设计 #大作业 #matlab #Docker #FHSS #网络攻击模型 #pyqt #outlook #错误代码2603 #无网络连接 #2603 #算力建设 #性能测试 #LoadRunner #r语言 #智能制造 #供应链管理 #工业工程 #库存管理 #服务器解析漏洞 #nodejs #运维工具 #ipmitool #BMC # 黑屏模式 # TTS服务器 #C #SSH密钥 #领域驱动 #练习 #基础练习 #数组 #循环 #九九乘法表 #计算机实现 #STDIO传输 #SSE传输 #WebMVC #WebFlux #dynadot #域名 #ETL管道 #向量存储 #数据预处理 #DocumentReader #esb接口 #走处理类报异常 #ffmpeg #IndexTTS2 # 阿里云安骑士 # 木马查杀 #入侵 #日志排查 #网路编程 #百万并发 #smtp #smtp服务器 #PHP #银河麒麟部署 #银河麒麟部署文档 #银河麒麟linux #银河麒麟linux部署教程 #Spring AOP #计组 #数电 #AI视频创作系统 #AI视频创作 #AI创作系统 #AI视频生成 #AI工具 #文生视频 #AI创作工具 #人大金仓 #Kingbase #Xshell #Finalshell #生物信息学 #组学 #word #AI 推理 #NV #租显卡 #训练推理 #ServBay #SFTP #多进程 #python技巧 #ranger #MySQL8.0 #raid #raid阵列 # OTA升级 # 黄山派 #ansys #ansys问题解决办法 #智能一卡通 #门禁一卡通 #梯控一卡通 #电梯一卡通 #消费一卡通 #一卡通 #考勤一卡通 # 网络延迟 #vim #gcc # Connection refused #Langchain-Chatchat # 国产化服务器 # 信创 #数据采集 #浏览器指纹 #numpy #database #pjsip #sql注入 #gRPC #注册中心 #Autodl私有云 #深度服务器配置 # 水冷服务器 # 风冷服务器 #雨云服务器 #Minecraft服务器 #教程 #MCSM面板 #iot #鸿蒙 #人脸识别sdk #视频编解码 #人脸识别 #智慧城市 # 服务器配置 # GPU #跳槽 #CA证书 #gateway #esp32 arduino #ZooKeeper #ZooKeeper面试题 #面试宝典 #深入解析 #AI-native #WinSCP 下载安装教程 #FTP工具 #服务器文件传输 # 批量部署 #CosyVoice3 # 语音合成 # 键鼠锁定 # 显卡驱动备份 #远程连接 #区块链 #生活 #工程设计 #预混 #扩散 #燃烧知识 #层流 #湍流 #广播 #组播 #并发服务器 #x86_64 #数字人系统 #语音生成 #TTS #Keycloak #Quarkus #AI编程需求分析 #大模型入门 #AI写作 #文件传输 #电脑文件传输 #电脑传输文件 #电脑怎么传输文件到另一台电脑 #电脑传输文件到另一台电脑 #服务器线程 # SSL通信 # 动态结构体 #node #参数估计 #矩估计 #概率论 #lvs #蓝牙 #LE Audio #BAP #企业存储 #RustFS #对象存储 #高可用 #gpu #nvcc #cuda #Node.js # child_process #SQL注入主机 #log4j #麦克风权限 #访问麦克风并录制音频 #麦克风录制音频后在线播放 #用户拒绝访问麦克风权限怎么办 #uniapp 安卓 苹果ios #将音频保存本地或上传服务器 #RXT4090显卡 #RTX4090 #深度学习服务器 #硬件选型 #仙盟创梦IDE #GLM-4.6V-Flash-WEB # AI视觉 # 本地部署 #动态规划 #dlms #dlms协议 #逻辑设备 #逻辑设置间权限 #scikit-learn #随机森林 #安全威胁分析 #戴尔服务器 #戴尔730 #装系统 #Minecraft #PaperMC #我的世界服务器 #junit #前端开发 #ThingsBoard MCP #LangFlow # 智能运维 # 性能瓶颈分析 #空间计算 #原型模式 #VibeVoice # 云服务器 #3d #devops # 服务器IP访问 # 端口映射 #kong #Kong Audio #Kong Audio3 #KongAudio3 #空音3 #空音 #中国民乐 #Comate #数模美赛 #ecmascript #elementui #bug #小艺 #搜索 #SSH复用 # 远程开发 #自动化运维 #数据安全 #注入漏洞 #多模态 #微调 #超参 #LLamafactory #产品经理 #就业 #ipv6 #duckdb #全能视频处理软件 #视频裁剪工具 #视频合并工具 #视频压缩工具 #视频字幕提取 #视频处理工具 #机器视觉 #6D位姿 # ControlMaster #国产操作系统 #V11 #kylinos #KMS激活 #b树 #Java程序员 #Java面试 #后端开发 #Spring源码 #Spring #CSDN #论文阅读 #软件工程 #le audio #低功耗音频 #通信 #连接 #Buck #NVIDIA #算力 #交错并联 #DGX #数字化转型 #实体经济 #商业模式 #软件开发 #数智红包 #商业变革 #创业干货 #安全架构 #blender #warp #TTS私有化 # IndexTTS # 音色克隆 #Tracker 服务器 #响应最快 #torrent 下载 #2026年 #Aria2 可用 #迅雷可用 #BT工具通用 #Zabbix #语音合成 #anaconda #虚拟环境 #FASTMCP #SSH跳板机 # Python3.11 #交换机 #三层交换机 #Gunicorn #WSGI #Flask #并发模型 #容器化 #性能调优 #高斯溅射 #视频 #产品运营 #Puppet # IndexTTS2 # TTS #ip #联机教程 #局域网联机 #局域网联机教程 #局域网游戏 #门禁 #梯控 #智能梯控 #云服务器 #个人电脑 #源代码管理 #超时设置 #客户端/服务器 #网络编程 #挖矿 #Linux病毒 #黑客技术 #网安应急响应 #MC群组服务器 # GLM # 服务连通性 #asp.net上传大文件 #VPS #搭建 #unix #编程 #c++高并发 #CS2 #debian13 #typescript #npm #框架搭建 #信创国产化 #达梦数据库 #状态模式 #dba #Tokio # ARM服务器 # 鲲鹏 #react native #uip #SSH跳转 #k8s # GPU集群 #Gateway #认证服务器集成详解 #samba #树莓派 #温湿度监控 #WhatsApp通知 #IoT #MySQL #ASR #SenseVoice #weston #x11 #x11显示服务器 #证书 #游戏美术 #技术美术 #游戏策划 #游戏程序 #用户体验 #后端框架 #文件上传漏洞 #Kylin-Server #服务器安装 # 数字人系统 # 远程部署 #vncdotool #链接VNC服务器 #如何隐藏光标 #A2A #GenAI #TLS协议 #HTTPS #漏洞修复 #运维安全 #free #vmstat #sar #CNAS #CMA #程序文件 #数据报系统 #MinIO #wireshark #网络安全大赛 #idc #Discord机器人 #云部署 #程序那些事 #实时检测 #卷积神经网络 #量子计算 #DAG #TRO #TRO侵权 #TRO和解 #云服务器选购 #Saas #线程 #具身智能 #VSCode # Qwen3Guard-Gen-8B #HarmonyOS APP #服务器IO模型 #非阻塞轮询模型 #多任务并发模型 #异步信号模型 #多路复用模型 #海外短剧 #海外短剧app开发 #海外短剧系统开发 #短剧APP #短剧APP开发 #短剧系统开发 #海外短剧项目 #AI电商客服 #webgl #spring ai #oauth2 #数据可视化 #rtmp #声源定位 #MUSIC #晶振 #工业级串口服务器 #串口转以太网 #串口设备联网通讯模块 #串口服务器选型 #华为od #华为od机试 #华为od机考 #华为od最新上机考试题库 #华为OD题库 #华为OD机试双机位C卷 #od机考题库 #ROS # 局域网访问 # 批量处理 #运维 # 高温监控 #fs7TF # 远程访问 #npu #远程软件 #bigtop #hdp #hue #kerberos #内网 #clawdbot #轻量化 #低配服务器 #分布式数据库 #集中式数据库 #业务需求 #选型误 #docker安装seata #WRF #WRFDA #HarmonyOS #代理服务器 #Matrox MIL #二次开发 #rsync # 数据同步 #设计师 #图像处理 #vertx #vert.x #vertx4 #runOnContext #多线程 #claudeCode #content7 #工作 #odoo #Syslog #系统日志 #日志分析 #日志监控 #edge #迭代器模式 #观察者模式 #生产服务器问题查询 #日志过滤 #机器人学习 #Apple AI #Apple 人工智能 #FoundationModel #Summarize #SwiftUI #AI生成 # outputs目录 # 自动化 #stl #IIS Crypto # 串口服务器 # NPort5630 #appche #视觉理解 #Moondream2 #多模态AI #编程助手 #ftp #sftp #YOLO识别 #YOLO环境搭建Windows #YOLO环境搭建Ubuntu # 轻量化镜像 # 边缘计算 #OpenHarmony #决策树 #Python办公自动化 #Python办公 #sglang #知识 #内存接口 # 澜起科技 # 服务器主板 #opc模拟服务器 #程序定制 #毕设代做 #课设 #cpu #protobuf #报表制作 #职场 #用数据讲故事 #音乐分类 #音频分析 #ViT模型 #Gradio应用 #鼠大侠网络验证系统源码 # 服务器迁移 # 回滚方案 #开关电源 #热敏电阻 #PTC热敏电阻 #AI部署 # ms-swift #PN 结 #RWK35xx #语音流 #实时传输 #超算中心 #PBS #lsf #gpt #adobe #数据迁移 #测速 #iperf #iperf3 #群晖 #音乐 #express #cherry studio #gmssh #宝塔 #漏洞挖掘 #Exchange #Coturn #TURN #小智 #系统安装 #铁路桥梁 #DIC技术 #箱梁试验 #裂纹监测 #四点弯曲 #目标跟踪 #可再生能源 #绿色算力 #风电 #ARM64 # DDColor # ComfyUI #模块 #Ubuntu #ESP32编译服务器 #Ping #DNS域名解析 #若依 #期刊 #SCI #面向对象 #基础语法 #标识符 #常量与变量 #数据类型 #运算符与表达式 #地理 #遥感 #Fluentd #Sonic #日志采集 #SMARC #ARM #taro #AI应用编程 #设备驱动 #芯片资料 #网卡 #主板 #总体设计 #电源树 #框图 #EN4FE #自由表达演说平台 #演说 #AI Agent #开发者工具 #Linly-Talker # 数字人 # 服务器稳定性 #国产开源制品管理工具 #Hadess #一文上手 #数据访问 #okhttp #范式 #计算机外设 #I/O模型 #并发 #水平触发、边缘触发 #多路复用 #Karalon #AI Test #传统行业 #流程图 #图论 #电子电气架构 #系统工程与系统架构的内涵 #自动驾驶 #汽车 #Routine #磁盘配额 #存储管理 #形考作业 #国家开放大学 #系统运维 #健康医疗 #C++ UA Server #SDK #跨平台开发 #ET模式 #非阻塞 #remote-ssh #mssql #工程实践 #lucene #AI应用 #图像识别 #高考 #Beidou #北斗 #SSR #密码 #API #wps #Linux多线程 #nmodbus4类库使用教程 #docker-compose #simulink #寄存器 #信息安全 #信息收集 #windbg分析蓝屏教程 #poll #coffeescript #SMP(软件制作平台) #EOM(企业经营模型) #应用系统 #H3C #IFix #项目申报系统 #项目申报管理 #项目申报 #企业项目申报 # 环境迁移 #matplotlib # AI部署 #材料工程 #智能电视 #VMware创建虚拟机 #远程更新 #缓存更新 #多指令适配 #物料关联计划 #挖漏洞 #攻击溯源 #gerrit #防毒面罩 #防尘面罩 #xshell #host key #tcp/ip #网络 #m3u8 #HLS #移动端H5网页 #APP安卓苹果ios #监控画面 直播视频流 #Prometheus #Shiro #反序列化漏洞 #CVE-2016-4437 #DooTask #UEFI #BIOS #Legacy BIOS #Socket #KMS 激活 #AI智能棋盘 #Rock Pi S #边缘计算 #高仿永硕E盘的个人网盘系统源码 #turn #汇编 #身体实验室 #健康认知重构 #系统思维 #微行动 #NEAT效应 #亚健康自救 #ICT人 #云开发 #xss #支持向量机 #SSH别名 #BoringSSL #云计算运维 # 权限修复 #ICE #考研 #华为机试 #http头信息 # SSH #音诺ai翻译机 #AI翻译机 # Ampere Altra Max #服务器开启 TLS v1.2 #IISCrypto 使用教程 #TLS 协议配置 #IIS 安全设置 #服务器运维工具 #uniapp #合法域名校验出错 #服务器域名配置不生效 #request域名配置 #已经配置好了但还是报错 #uniapp微信小程序 # HiChatBox # 离线AI #mtgsig #美团医药 #美团医药mtgsig #美团医药mtgsig1.2 #TCP服务器 #开发实战 #全文检索 #银河麒麟服务器系统 #套接字 #I/O多路复用 #字节序 #国产PLM #瑞华丽PLM #瑞华丽 #PLM #统信操作系统 #nosql #阻塞队列 #生产者消费者模型 #服务器崩坏原因 #xml #可撤销IBE #服务器辅助 #私钥更新 #安全性证明 #双线性Diffie-Hellman #短剧 #短剧小程序 #短剧系统 #微剧 #电梯 #电梯运力 #电梯门禁 #MCP服务器注解 #异步支持 #方法筛选 #声明式编程 #自动筛选机制 #JNI #pxe #大学生 #esp32 #mosquito # GPU服务器 # tmux #NSP #下一状态预测 #aigc #效率神器 #办公技巧 #自动化工具 #Windows技巧 #打工人必备 #vue上传解决方案 #vue断点续传 #vue分片上传下载 #vue分块上传下载 #RK3588 #RK3588J #评估板 #核心板 #嵌入式开发 #数字孪生 #三维可视化 #AI+ #coze #AI入门 #resnet50 #分类识别训练 #cascadeur #Spire.Office #隐私合规 #网络安全保险 #法律风险 #风险管理 #Python3.11 #2025年 #FRP #AI工具集成 #容器化部署 #分布式架构 #AI教程 #网络配置实战 #Web/FTP 服务访问 #计算机网络实验 #外网访问内网服务器 #Cisco 路由器配置 #静态端口映射 #网络运维 #自动化巡检 #0day漏洞 #DDoS攻击 #漏洞排查 #Rust #异步编程 #系统编程 #Pin #http服务器 # IP配置 # 0.0.0.0 #路由器 #galeweather.cn #高精度天气预报数据 #光伏功率预测 #风电功率预测 #高精度气象 #CS336 #Assignment #Experiments #TinyStories #Ablation #星际航行 #论文复现 #反向代理 #娱乐 #敏捷流程 #AE #rag #AI赋能盾构隧道巡检 #开启基建安全新篇章 #以注意力为核心 #YOLOv12 #AI隧道盾构场景 #盾构管壁缺陷病害异常检测预警 #隧道病害缺陷检测 #ossinsight #jquery #学术生涯规划 #CCF目录 #基金申请 #职称评定 #论文发表 #科研评价 #顶会顶刊 #AITechLab #cpp-python #CUDA版本 #fork函数 #进程创建 #进程终止 #分子动力学 #化工仿真 #节日 #静脉曲张 #腿部健康 #运动 #session #游戏服务器断线 #JADX-AI 插件 #Archcraft #clamav #外卖配送 #语义检索 #向量嵌入 #boltbot #命令模式 #边缘AI # Kontron # SMARC-sAMX8 #环境搭建 #starrocks #人脸活体检测 #live-pusher #动作引导 #张嘴眨眼摇头 #苹果ios安卓完美兼容 #LabVIEW知识 #LabVIEW程序 #labview #LabVIEW功能 #OSS #百度 #ueditor导入word #L6 #L10 #L9 #OpenAI #故障 # 硬件配置 #阿里云RDS #软件需求 #composer #symfony #java-zookeeper #dubbo #个性化推荐 #BERT模型 #Qwen3-VL # 服务状态监控 # 视觉语言模型 #二值化 #Canny边缘检测 #轮廓检测 #透视变换 #因果学习 #DuckDB #协议 #React安全 #漏洞分析 #Next.js #新浪微博 #传媒 #隐函数 #常微分方程 #偏微分方程 #线性微分方程 #线性方程组 #非线性方程组 #复变函数 #土地承包延包 #领码SPARK #aPaaS+iPaaS #智能审核 #档案数字化 #农产品物流管理 #物流管理系统 #农产品物流系统 #农产品物流 #Ward #思爱普 #SAP S/4HANA #ABAP #NetWeaver #WAN2.2 #日志模块 #Arduino BLDC #核辐射区域探测机器人 #DDD #tdd # 服务器IP配置