Python 标准差拉伸(更新)

Python Gdal 标准差拉伸

16bit转为8bit

2022.9.24 更新: 排除 0 值,代码如下.

# -*- coding: utf-8 -*-
from osgeo import gdal
import numpy as np
import os


def bit8(data, d_min, d_max, mean, std, Kn):
    uc_max = mean + Kn * std
    uc_min = mean - Kn * std
    k = (d_max - d_min) / (uc_max - uc_min)
    b = (uc_max * d_min - uc_min * d_max) / (uc_max - uc_min)
    if uc_min <= 0:
        uc_min = 0
    # 跳过 0 值 2022.9.24
    data = np.select(
        [data == 0, data == d_min, data <= uc_min, data >= uc_max, k * data + b < d_min, k * data + b > d_max,
         (k * data + b > d_min) & (k * data + b < d_max)],
        [0, d_min, d_min, d_max, d_min, d_max, k * data + b], data)
    return data


def convert2bit8(in_path):
    if not os.path.exists(in_path):
        print('输入路径不存在!')
        return ""
    for root, dirs, files in os.walk(in_path):
        for file in files:
            '''筛选tif文件'''
            if not file.split('.')[-1] == 'tif':
                continue
            '''输入路径的文件名'''
            file_name = os.path.join(root, file)
            '''创建输出路径文件名'''
            out_file = os.path.join(root, os.path.splitext(file)[0] + '_bit8.tif')
            '''文件存在则删除文件重新生成'''
            if os.path.exists(out_file):
                os.remove(out_file)
            in_tif = gdal.Open(file_name)
            width = in_tif.RasterXSize
            height = in_tif.RasterYSize

            '''跳过8bit'''
            if in_tif.ReadAsArray().dtype.name == 'uint8':
                continue

            geo_transform = in_tif.GetGeoTransform()
            print('左上角坐标 %f %f' % (geo_transform[0], geo_transform[3]))
            print('像素分辨率 %f %f' % (geo_transform[1], geo_transform[5]))
            '''True Color 1,2,3波段'''
            out_tif = gdal.GetDriverByName('GTiff').Create(out_file, width, height, in_tif.RasterCount, gdal.GDT_Byte)
            out_tif.SetProjection(in_tif.GetProjection())
            out_tif.SetGeoTransform(geo_transform)

            for i in range(1, int(in_tif.RasterCount) + 1):
                band = in_tif.GetRasterBand(i)
                data = band.ReadAsArray()
                # 排除 0 值 2022.9.24
                not0 = np.where(data > 0, data, np.nan)
                mean = np.nanmean(not0)
                std = np.nanstd(not0, ddof=1)
                # std = np.std(data)
                out_band = bit8(data, 0, 255, mean, std, 5)
                out_tif.GetRasterBand(i).WriteArray(out_band)

            out_tif.FlushCache()
            for i in range(1, int(in_tif.RasterCount) + 1):
                out_tif.GetRasterBand(i).ComputeStatistics(False)
            # out_tif.BuildOverviews('average', [2, 4, 8, 16, 32])
            del out_tif
    return out_file


if __name__ == '__main__':
    '''调用选择文件夹对话框获取输入路径'''
    path = r"F:\16bit\1"

    convert2bit8(path)
    print("Done!")

### 使用Python对TIF图像数据进行标准化预处理 对于TIF图像数据的标准化预处理,可以采用`rasterio`库来读取文件并利用NumPy来进行数值操作。下面展示了一个完整的流程,包括读取TIF文件、计算统计数据以及应用线性拉伸变换以实现标准化。 #### 1. 导入必要的库 为了完成这项工作,需要导入几个重要的Python包: ```python import numpy as np import rasterio from rasterio.plot import show ``` #### 2. 加载TIF图像 使用`rasterio.open()`函数打开指定路径下的TIF文件,并从中提取单波段的数据作为数组存储起来。 ```python with rasterio.open('path/to/your/terrain.tif') as src: img_array = src.read(1) # 假设只处理第一个波段 ``` #### 3. 计算统计量 接下来要做的就是基于整个影像阵列计算均值(mean)标准差(std),这两个参数将在后续用于标准化转换。 ```python mean_val = np.mean(img_array) std_dev = np.std(img_array) print(f'Mean Value: {mean_val}') print(f'Standard Deviation: {std_dev}') ``` #### 4. 应用Z-Score标准化方法 这里采用了z-score的方式来做标准化,即将每个像素减去全局平均后再除以其标准偏差,从而使得新分布具有零均值单位方差特性。 ```python normalized_img = (img_array - mean_val) / std_dev ``` #### 5. 处理异常值(可选) 有时可能会遇到极端高或低的像素值,在这种情况下可以选择设定上下限来裁剪这些离群点。 ```python clipped_image = np.clip(normalized_img, a_min=-2*std_dev, a_max=2*std_dev) ``` #### 6. 将结果保存回新的TIF文件 最后一步是把经过标准化后的图像重新写回到一个新的GeoTIFF文件中以便于进一步分析或其他用途。 ```python profile = src.profile.copy() profile.update(dtype=rasterio.float32) with rasterio.open('output_normalized_terrain.tif', 'w', **profile) as dst: dst.write(clipped_image.astype(rasterio.float32), 1) ``` 上述过程展示了如何有效地准备地理空间栅格数据集,使其更适合机器学习模型训练或是可视化呈现[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值