像元二分模型计算植被覆盖度

目录

    • 前言
    • 论文要点
    • 计算过程
    • 辅助数据介绍
    • IDL实现
    • 计算结果

前言

关于改进的像元二分模型第一次出现是在李苗苗老师的博士论文中,但她后来发表的一篇期刊文章把这一部分单独摘了出来并做了应用案例,期刊链接在下方。

密云水库上游植被覆盖度的遥感估算

论文要点

计算公式为:Fc =(NDVI -NDVIsoil) (NDVIveg -NDVIsoil)
问题的关键在于NDVIveg 与NDVIsoil如何取值。

其中 ,NDVIsoil 为完全是裸土或无植被覆盖区域的NDVI 值 , NDVIveg 则代表完全被植被所覆盖的像元的NDVI 值, 即纯植被像元的NDVI 值。NDVIveg 代表着全植被覆盖像元的最大值, 由于植被类型的影响, NDVIveg 值也会随着时间和空间而改变。 因此 , 计算植被覆盖度时, 既使同一景影像, 对于NDVIsoil 和NDVIveg 值不能取固定值。在实地应用中,植被覆盖类型随土地利用类型而变化, 对于某一土地利用类型, 由于植被类型近似, 其 NDVIveg 值也相近;而对于特定的土壤类型 ,其 NDVIsoil 值也应该是一定的 。因此, 土地利用图和土壤图应作为计算 NDVIveg 和NDVIsoil 值的基础
像元二分模型计算植被覆盖度_第1张图片

计算过程

像元二分模型计算植被覆盖度_第2张图片

辅助数据介绍

全球土壤数据
HWSD全球土壤数据下载处理
全球土地分类数据
MCD12Q1
关于MCDQ1,由官网介绍可知数据中包含5种分类方法得到的结果。
像元二分模型计算植被覆盖度_第3张图片
数据的说明手册目前网址404了。但我们可以查看数据的头文件获取分类代码信息。
这里贴出了type3的分类代码信息,比较符合我们计算植被覆盖度的目的。

Dataset #3: Land_Cover_Type_3  
  Dims: BYTE (2400 x 2400)    
Attribute 3-1: "long_name"  
  "Land_Cover_Type_3"   
Attribute 3-2: "Water Bodies"  
  0   
Attribute 3-3: "Grasslands"  
  1   
Attribute 3-4: "Shrublands"  
  2   
Attribute 3-5: "Broadleaf Croplands"  
  3   
Attribute 3-6: "Savannas"  
  4   
Attribute 3-7: "Evergreen Broadleaf Forests"  
  5   
Attribute 3-8: "Deciduous Broadleaf Forests"  
  6   
Attribute 3-9: "Evergreen Needleleaf Forests"  
  7  
Attribute 3-10: "Deciduous Needleleaf Forests"  
  8   
Attribute 3-11: "Unvegetated"  
  9   
Attribute 3-12: "Urban and Built-up Lands"  
  10   
Attribute 3-13: "Unclassified"  
  255   
Attribute 3-14: "valid_range"  
  0, 10    
Attribute 3-15: "_FillValue"  
  255  

使用MCTK对type3进行投影,重采样,至此LULC和HWSD,NDVI数据都准备好了。

IDL实现

pro vfc_cal
  compile_opt idl2
  e = envi()
  workpath = 'F:\FY3D_MERSI_data\Subset'
  cd,workpath
  ndvifile = workpath + '\NDVI'
  lulcfile = workpath + '\LULC'
  hwsdfile = workpath + '\HWSD'
  
  ndvir = e.openraster(ndvifile)
  hwsdr = e.openraster(hwsdfile)
  lulcr = e.openraster(lulcfile)
  
  spatialref = ndvir.spatialRef
  
  ndvi = ndvir.getdata(bands=0)
  hwsd = hwsdr.getdata(bands=0)
  lulc = lulcr.getdata(bands=0)
  
  ndvi[where(finite(ndvi,/nan))]  = mean(ndvi,/nan)
  lulc[where(finite(lulc,/nan))]  = 4
  
  hwsd_class = hwsd[uniq(hwsd,sort(hwsd))]
  lulc_class = lulc[uniq(lulc,sort(lulc))]
  print,hwsd_class,lulc_class
   
  lutmin = make_array(2,n_elements(hwsd_class),type=5)
  for i=0,n_elements(hwsd_class)-1 do begin 
    lutmin[0,i] = hwsd_class[i]
    ndvi_hwsd = ndvi[where(hwsd eq lutmin[0,i])] 
    ndvi_hwsd = ndvi_hwsd[sort(ndvi_hwsd)]
    ndvi_hwsd = ndvi_hwsd[where(hwsd ge -0.1)]
    number = n_elements(ndvi_hwsd)
    lutmin[1,i] =  ndvi_hwsd[round(0.05*number)]  
  endfor

  lutmax = make_array(2,n_elements(lulc_class),type=5)
  for i=0,n_elements(lulc_class)-1 do begin
    lutmax[0,i] = lulc_class[i]
    ndvi_lulc = ndvi[where(lulc eq lutmax[0,i])]
    ndvi_lulc = ndvi_lulc[sort(ndvi_lulc)]
    number = n_elements(ndvi_lulc)
    lutmax[1,i] =  ndvi_lulc[floor(0.95*number)]
  endfor
 
  dim = size(ndvi)
  n = n_elements(ndvi)
  vfc = make_array(dim[1],dim[2],type=5)
  for i=0,n-1 do begin
    for j=0,n_elements(hwsd_class)-1 do begin
      for k=0,n_elements(lulc_class)-1 do begin
        if lulc[i] eq lutmax[0,k] and hwsd[i] eq lutmin[0,j] then begin
          case 1 of 
            ndvi[i] ge lutmax[1,k] : vfc[i] = 1
            ndvi[i] le lutmin[1,j] : vfc[i] = 0
            else: vfc[i] = (ndvi[i]-lutmin[1,j]) / (lutmax[1,k]-lutmin[1,j])
          endcase
        endif
      endfor
    endfor
  endfor
  
  tempfn = e.GetTemporaryFilename()
  vfcr = e.CreateRaster(tempfn, vfc, SpatialRef = spatialref)
  vfcr.save
 
end

PS:一开始取整用的fix,结果被坑惨了。VFC结果大部分都是1,找了半天代码错误才发现取整的地方不太合适,改为了floor。最基本的常识都忘了,小数取整不要用fix!!!

计算结果

结果差别挺大的,现在网上流传的一些计算方法大多都没有引入土壤数据,而是利用每一类土地利用的NDVImin当做NDVIsoil,这种方法我还没有去计算对比,但结合土壤数据和土地分类数据的计算绝对是纯正的计算方法。

你可能感兴趣的:(遥感,IDL)