代码目的
该代码的目的是为了更准确地从ICESat-2激光雷达数据中计算出冠层高度。它通过空间分段处理、异常值过滤、稳健统计方法以及后处理优化等步骤,来提高冠层高度计算的精确度和可靠性。
使用的方法
- 空间分段处理:将数据按照固定距离分段,确保每个分段单独处理,避免远距离点之间的干扰。
- 异常值处理:使用DBSCAN聚类算法识别和过滤异常值,对地面点和冠层点分别进行过滤,以排除不符合数据特征的点。
- 稳健统计方法:使用修剪平均值(trim_mean)替代简单平均值来计算冠层和地面的高度,去除每个分段中最高和最低的一定比例的值,从而减少极端值对平均值的影响。
- 后处理优化:应用中值滤波平滑结果,减少数据中的噪声,使结果更加平滑和稳定。
----------------------------------------------------------------更--------------------------------------------------------------这个改进版本采用了以下策略:
- 空间分段处理:
- 将数据按照固定距离(默认20米)分段
- 确保每个分段单独处理,避免远距离点之间的干扰
- 异常值处理:
- 使用DBSCAN聚类识别和过滤异常值
- 对地面点和冠层点分别进行过滤
- 稳健统计方法:
- 使用修剪平均值(trim_mean)替代简单平均值
- 去除每个分段中最高和最低的10%的值
- 后处理优化:
- 应用中值滤波平滑结果
- 计算每个分段的点数统计
- 输出更多统计信息:
- 每个分段的地面点和冠层点数量
- 原始高度和平滑后的高度
- 分段的位置信息
建议你可以尝试调整以下参数来优化结果:
segment_size
:可以尝试15-30米的不同值- DBSCAN的
eps
参数:可以根据数据特征调整 - trim_mean的
proportiontocut
:可以在0.05-0.2之间调整
import pandas as pd
import numpy as np
from scipy.stats import trim_mean
from sklearn.cluster import DBSCAN
def calculate_improved_canopy_height(input_file, output_path, segment_size=20):
"""
使用空间分段和稳健统计方法计算冠层高度
参数:
input_file: 输入文件路径
output_path: 输出路径
segment_size: 分段大小(米)
"""
# 读取数据
df = pd.read_csv(input_file)
# 按照x_atc进行分段
df['segment_id'] = (df['x_atc'] // segment_size).astype(int)
results = []
# 对每个分段进行处理
for segment_id in df['segment_id'].unique():
segment_data = df[df['segment_id'] == segment_id].copy()
# 确保分段中同时存在地面点和冠层点
ground_points = segment_data[segment_data['Classification'] == 1]
canopy_points = segment_data[segment_data['Classification'] == 2]
if len(ground_points) > 0 and len(canopy_points) > 0:
# 使用DBSCAN识别和过滤异常值
def filter_outliers(points):
if len(points) < 2:
return points
clustering = DBSCAN(eps=0.5, min_samples=2).fit(points[['Height']].values)
return points[clustering.labels_ != -1]
ground_points = filter_outliers(ground_points)
canopy_points = filter_outliers(canopy_points)
# 使用修剪平均值计算高度
if len(ground_points) > 0 and len(canopy_points) > 0:
ground_height = trim_mean(ground_points['Height'], proportiontocut=0.1)
canopy_height = trim_mean(canopy_points['Height'], proportiontocut=0.1)
# 计算段中心位置
segment_center = segment_data['x_atc'].mean()
center_lat = segment_data['Latitude'].mean()
center_lon = segment_data['Longitude'].mean()
results.append({
'segment_id': segment_id,
'x_atc': segment_center,
'Latitude': center_lat,
'Longitude': center_lon,
'ground_height': ground_height,
'canopy_height': canopy_height,
'canopy_relative_height': canopy_height - ground_height,
'n_ground_points': len(ground_points),
'n_canopy_points': len(canopy_points)
})
results_df = pd.DataFrame(results)
# 应用中值滤波平滑结果
results_df['smoothed_height'] = results_df['canopy_relative_height'].rolling(
window=3, center=True, min_periods=1
).median()
# 计算统计指标
valid_heights = results_df['smoothed_height'].dropna()
stats = {
'mean_canopy_height': valid_heights.mean(),
'median_canopy_height': valid_heights.median(),
'std_canopy_height': valid_heights.std(),
'num_segments': len(valid_heights)
}
# 保存结果
results_df.to_csv(f"{output_path}/improved_canopy_heights.csv", index=False)
return results_df, stats
# 使用示例
input_file = r" -------------------------"
output_path = r"-------------------------"
# 运行改进的算法
results, stats = calculate_improved_canopy_height(input_file, output_path, segment_size=20)
# 打印统计信息
print("\n改进后的统计信息:")
for key, value in stats.items():
print(f"{key}: {value:.2f}")