欢迎光临
我们一直在努力

【深度学习遥感地学应用】围绕 识别—监测—评估—预警 这一整条链条展开深度学习在“溜砂坡(scree/talus slope)”相关问题里的应用(附代码)(一)

【深度学习遥感地学应用】围绕 识别—监测—评估—预警 这一整条链条展开深度学习在“溜砂坡(scree/talus slope)”相关问题里的应用(附代码)(一)

【深度学习遥感地学应用】围绕 识别—监测—评估—预警 这一整条链条展开深度学习在“溜砂坡(scree/talus slope)”相关问题里的应用(附代码)(一)


文章目录

  • 【深度学习遥感地学应用】围绕 识别—监测—评估—预警 这一整条链条展开深度学习在“溜砂坡(scree/talus slope)”相关问题里的应用(附代码)(一)
    • 一、应用 1:溜砂坡自动识别与制图(Mapping / Segmentation)
      • 1.1 典型任务
      • 1.2 可以用的模型
      • 1.3 代码示例:多通道 U-Net 做溜砂坡分割(可直接改数据)
        • (1) 计算 DEM 地形因子(坡度 + 曲率)作为额外通道
        • (2) PyTorch Dataset:读取影像 + 地形因子 + mask
        • (3) 最小 U-Net + 训练(BCEWithLogits + Dice)
    • 二、应用 2:落石/崩塌事件识别(Rockfall event detection)
      • 代码思路(常见做法)
        • 示例:差分栅格 patch 分类(简化版 CNN)

欢迎家人们点赞、关注、收藏! 祝大家逢考必过!逢投必中!上岸上岸上岸!upupup

大多数高校硕博生毕业要求需要参加学术会议,发表EI或者SCI检索的学术论文会议论文。详细信息可扫描博文下方二维码 “学术会议小灵通”或参考学术信息专栏:https://ais.cn/u/mmmiUz 详细免费的AI课程可在这里获取→www.lab4ai.cn


一、应用 1:溜砂坡自动识别与制图(Mapping / Segmentation)

1.1 典型任务

  • 输入:卫星/航片正射影像(RGB/NIR)、DEM 派生地形因子(坡度、曲率、粗糙度)、或多源融合
  • 输出:溜砂坡范围(像素级语义分割)或面状矢量
  • 意义:快速编制溜砂坡分布图,为灾害清单、道路选线、泥石流物源评估提供底图

有研究已直接做“talus mapping with deep learning + high-resolution data”。

1.2 可以用的模型

  • U-Net / DeepLabV3+ / SegFormer(2D 语义分割)
  • 输入通道可做成:[RGB, slope, curvature, roughness] 多通道

1.3 代码示例:多通道 U-Net 做溜砂坡分割(可直接改数据)

下面是最小可跑的 U-Net(你把数据换成自己的影像 patch 即可)。

(1) 计算 DEM 地形因子(坡度 + 曲率)作为额外通道

import numpy as np
import rasterio

def terrain_features_from_dem(dem_path: str):
"""
返回 slope(0~1归一化前) 与 curvature(简单二阶差分近似)
"""
with rasterio.open(dem_path) as ds:
dem = ds.read(1).astype(np.float32)
transform = ds.transform
dx = transform.a
dy = transform.e

# 一阶梯度
gy, gx = np.gradient(dem, dy, dx)
slope = np.sqrt(gx**2 + gy**2) # 近似坡度(梯度幅值)

# 二阶:曲率(非常简化,工程上可换更严谨的 profile/plan curvature)
gyy, gyx = np.gradient(gy, dy, dx)
gxy, gxx = np.gradient(gx, dy, dx)
curvature = gxx + gyy # Laplacian 近似

return slope, curvature

(2) PyTorch Dataset:读取影像 + 地形因子 + mask

假设你已经把训练数据切成 patch:

  • img/*.tif(比如 4 通道:RGBN 或 RGB)
  • dem/*.tif
  • mask/*.tif(0/1:非溜砂坡/溜砂坡)

import os, glob
import torch
from torch.utils.data import Dataset
import rasterio
import numpy as np

class TalusSegDataset(Dataset):
def __init__(self, img_dir, dem_dir, mask_dir):
self.imgs = sorted(glob.glob(os.path.join(img_dir, "*.tif")))
self.dem_dir = dem_dir
self.mask_dir = mask_dir

def __len__(self):
return len(self.imgs)

def __getitem__(self, idx):
img_path = self.imgs[idx]
name = os.path.splitext(os.path.basename(img_path))[0]
dem_path = os.path.join(self.dem_dir, f"{name}.tif")
mask_path = os.path.join(self.mask_dir, f"{name}.tif")

with rasterio.open(img_path) as ds:
img = ds.read().astype(np.float32) # (C,H,W)
slope, curv = terrain_features_from_dem(dem_path)

with rasterio.open(mask_path) as ds:
mask = ds.read(1).astype(np.float32) # (H,W)

# 归一化(示意:你可换成训练集 mean/std)
img = img / (img.max() + 1e-6)
slope = slope / (np.percentile(slope, 99) + 1e-6)
curv = curv / (np.percentile(np.abs(curv), 99) + 1e-6)

x = np.concatenate([img, slope[None, ...], curv[None, ...]], axis=0) # (C+2,H,W)

x = torch.from_numpy(x)
y = torch.from_numpy(mask[None, ...]) # (1,H,W)
return x, y

(3) 最小 U-Net + 训练(BCEWithLogits + Dice)

import torch
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import DataLoader

class ConvBlock(nn.Module):
def __init__(self, in_ch, out_ch):
super().__init__()
self.net = nn.Sequential(
nn.Conv2d(in_ch, out_ch, 3, padding=1),
nn.BatchNorm2d(out_ch),
nn.ReLU(inplace=True),
nn.Conv2d(out_ch, out_ch, 3, padding=1),
nn.BatchNorm2d(out_ch),
nn.ReLU(inplace=True),
)
def forward(self, x): return self.net(x)

class UNetSmall(nn.Module):
def __init__(self, in_ch, base=32):
super().__init__()
self.enc1 = ConvBlock(in_ch, base)
self.pool1 = nn.MaxPool2d(2)
self.enc2 = ConvBlock(base, base*2)
self.pool2 = nn.MaxPool2d(2)
self.bott = ConvBlock(base*2, base*4)
self.up2 = nn.ConvTranspose2d(base*4, base*2, 2, stride=2)
self.dec2 = ConvBlock(base*4, base*2)
self.up1 = nn.ConvTranspose2d(base*2, base, 2, stride=2)
self.dec1 = ConvBlock(base*2, base)
self.out = nn.Conv2d(base, 1, 1)

def forward(self, x):
e1 = self.enc1(x)
e2 = self.enc2(self.pool1(e1))
b = self.bott(self.pool2(e2))
d2 = self.up2(b)
d2 = self.dec2(torch.cat([d2, e2], dim=1))
d1 = self.up1(d2)
d1 = self.dec1(torch.cat([d1, e1], dim=1))
return self.out(d1) # logits

def dice_loss_with_logits(logits, targets, eps=1e-6):
probs = torch.sigmoid(logits)
num = 2 * (probs * targets).sum(dim=(2,3))
den = (probs + targets).sum(dim=(2,3)) + eps
return 1 (num / den).mean()

def train_seg():
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
ds = TalusSegDataset("img", "dem", "mask")
dl = DataLoader(ds, batch_size=4, shuffle=True, num_workers=2, pin_memory=True)

sample_x, _ = ds[0]
model = UNetSmall(in_ch=sample_x.shape[0]).to(device)

opt = torch.optim.AdamW(model.parameters(), lr=2e-4, weight_decay=1e-2)

for epoch in range(30):
model.train()
total = 0.0
for x, y in dl:
x, y = x.to(device), y.to(device)
logits = model(x)
loss = F.binary_cross_entropy_with_logits(logits, y) + 0.5 * dice_loss_with_logits(logits, y)

opt.zero_grad()
loss.backward()
torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)
opt.step()
total += loss.item()

print(f"epoch {epoch+1:02d}, loss={total/len(dl):.4f}")

# train_seg()

二、应用 2:落石/崩塌事件识别(Rockfall event detection)

溜砂坡常处于“落石补给—再分配”的动力系统里,深度学习常用于:

  • 从 LiDAR 差分/点云变化 中自动识别落石事件,减少人工判读 已有工作把深度学习用于“rockfall database population / event classification”

代码思路(常见做法)

  • 用两期点云/DEM 做 变化检测(DoD:DEM of Difference 或点云最近邻距离)
  • 把变化栅格切 patch
  • 用 CNN 分类:rockfall / noise / vegetation / other
  • 示例:差分栅格 patch 分类(简化版 CNN)

    import torch
    import torch.nn as nn
    import torch.nn.functional as F

    class PatchCNN(nn.Module):
    def __init__(self, in_ch=1, num_classes=3):
    super().__init__()
    self.net = nn.Sequential(
    nn.Conv2d(in_ch, 16, 3, padding=1), nn.ReLU(),
    nn.MaxPool2d(2),
    nn.Conv2d(16, 32, 3, padding=1), nn.ReLU(),
    nn.MaxPool2d(2),
    nn.Conv2d(32, 64, 3, padding=1), nn.ReLU(),
    nn.AdaptiveAvgPool2d(1),
    )
    self.fc = nn.Linear(64, num_classes)

    def forward(self, x):
    h = self.net(x).flatten(1)
    return self.fc(h) # logits

    # 输入 x: (B,1,H,W) 例如差分高程、或点云距离栅格

    • 你真正落地时,关键在于:训练样本怎么标注(事件 vs 噪声)。通常先用阈值 + 形态学提候选,再人工快速确认少量样本。
    赞(0)
    未经允许不得转载:171主机测评 » 【深度学习遥感地学应用】围绕 识别—监测—评估—预警 这一整条链条展开深度学习在“溜砂坡(scree/talus slope)”相关问题里的应用(附代码)(一)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址