多波段影像数据区域统计(Python代码)

Tips :本代码实现ArcGIS中的区域统计功能(Zonal),有两点特色:
1)能够将统计得到的属性值直接赋予矢量文件中;
2)可实现多波段影像区域统计(方法比较笨,先拆分波段,然后进行统计)。

区域统计的类型参考ArcGIS:
MEAN— Calculates the average of all cells in the value raster that belong to the same zone as the output cell.
MAJORITY — Determines the value that occurs most often of all cells in the value raster that belong to the same zone as the output cell.
MAX — Determines the largest value of all cells in the value raster that belong to the same zone as the output cell.
MEDIAN — Determines the median value of all cells in the value raster that belong to the same zone as the output cell.
MIN — Determines the smallest value of all cells in the value raster that belong to the same zone as the output cell.
MINORITY — Determines the value that occurs least often of all cells in the value raster that belong to the same zone as the output cell.
RANGE — Calculates the difference between the largest and smallest value of all cells in the value raster that belong to the same zone as the output cell.
STD — Calculates the standard deviation of all cells in the value raster that belong to the same zone as the output cell.
SUM — Calculates the total value of all cells in the value raster that belong to the same zone as the output cell.
VARIETY — Calculates the number of unique values for all cells in the value raster that belong to the same zone as the output cell. (unique)

# -*- coding: utf-8 -*-
"""
Created on Thu Dec 17 11:39:53 2020

@author: xiao_gf

"""
import ogr
from osgeo import gdal
import numpy as np
from rasterstats import zonal_stats


def readTif(fileName):
    dataset = gdal.Open(fileName)
    if dataset == None:
        print(fileName+"文件无法打开")
    return dataset

# 保存tif文件
def writeTiff(im_data, im_geotrans, im_proj, path):
    if 'int8' in im_data.dtype.name:
        datatype = gdal.GDT_Byte
    elif 'int16' in im_data.dtype.name:
        datatype = gdal.GDT_UInt16
    else:
        datatype = gdal.GDT_Float32
    if len(im_data.shape) == 3:
        im_bands, im_height, im_width = im_data.shape
    elif len(im_data.shape) == 2:
        im_data = np.array([im_data])
        im_bands, im_height, im_width = im_data.shape
    #创建文件
    driver = gdal.GetDriverByName("GTiff")
    dataset = driver.Create(path, int(im_width), int(im_height), int(im_bands), datatype)
    if(dataset!= None):
        dataset.SetGeoTransform(im_geotrans) #写入仿射变换参数
        dataset.SetProjection(im_proj) #写入投影
    for i in range(im_bands):
        dataset.GetRasterBand(i+1).WriteArray(im_data[i])
    del dataset
   
def zonal(input_vector,in_raster,Stats_type,path):    
    in_ds =readTif(in_raster)
    im_width = in_ds.RasterXSize  # 栅格矩阵的列数
    im_height = in_ds.RasterYSize  # 栅格矩阵的行数
    im_bands = in_ds.RasterCount
    im_data = in_ds.ReadAsArray(0, 0, im_width, im_height)
    im_geotrans = in_ds.GetGeoTransform()
    im_proj = in_ds.GetProjection()
    
    for band in range(0,im_bands):
        data = im_data[band]
        rasters = path+'\B{}'.format(band+1)+'.tif'  #输出单波段名称为B1、B2、...,可根据自己需求修改设定
        writeTiff(data, im_geotrans, im_proj, rasters)
        
        shp = ogr.Open(input_vector,1)
        lyr = shp.GetLayer()   
        # 添加字段
        zonal_Field = ogr.FieldDefn("B{}".format(band+1), ogr.OFTReal) 
        #添加的字段名称和单波段文件名称一致,为B1、B2、...,可根据自己需求修改设定
        zonal_Field.SetPrecision(9)
        lyr.CreateField(zonal_Field)
            
        zonal_method = zonal_stats(input_vector, rasters, stats=[Stats_type])
        FID = 0
        for feat in lyr:
            Index = zonal_method[FID][Stats_type]
           # print(Index)
            feat.SetField("B{}".format(band+1), Index)
            feat.SetFID(FID)
            lyr.SetFeature(feat)
            FID +=1
        
if __name__ =="__main__":
    
    input_shp = r"D:\DATA\test.shp"  #输入统计的矢量文件
    input_raster = r"D:\DATA\test_r.tif"  #需要统计的栅格数据(遥感影像)
    path = r"D:\DATA\band" #获取的单波段数据存储地址
    Stats_type = 'mean' #区域统计的类型
    # Stats_type表示统计的类型,包括:'min', 'max', 'mean', 'count', 'sum', 'std', 'median', 'majority', 'minority', 'unique', 'range
    zonal(input_shp, input_raster, Stats_type, path)
  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

小松鼠想吃大闸蟹

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

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

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

打赏作者

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

抵扣说明:

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

余额充值