无人机遥感 · 松材线虫病 · AI自动识别

松材线虫病防控最怕两个字:发现晚。无人机影像加 AI 的价值,不是替代实验室检测,而是先把疑似异常松木快速标出来,给出坐标、截图和置信度,让外业人员带着任务去核查。

无人机影像病死松识别目标检测外业核查林业防控

一、先把问题说准:AI 识别的不是线虫本体

无人机影像看不到松材线虫本身。它看到的是树冠颜色、纹理、形态和空间位置的异常,例如针叶褪绿、树冠黄化、红褐化、枯死树冠,以及与周围健康松树不一致的冠层纹理。

更专业的表达应该是:基于无人机遥感影像的疑似松材线虫病感病松、病死松或变色立木自动识别。AI 输出的是疑似目标,最终确认仍要依靠外业核查或专业检测。

  • 传统巡查痛点:山地范围大、路线复杂、遮挡多,护林员需要大范围盲巡,发现一棵早期变色松并不容易。
  • 无人机的价值:快速获取高分辨率影像,覆盖人工难到达区域,结合坐标输出疑似点位。
  • AI 的价值:批量筛查影像,把人从海量图片里解放出来,只把疑似目标交给人工复核。
  • 系统的价值:把识别结果变成地图点位、核查任务、处置台账和样本回流,而不是停在模型演示。

二、一套系统应该怎么跑起来

图 1:松材线虫病无人机影像 AI 识别闭环

很多项目的问题是只做了“影像进模型,模型出框”。这不够。林业防控需要的是闭环:模型输出能不能落到地图上,外业人员能不能按坐标找到树,核查结论能不能回到系统,处置结果能不能追踪。

RGB 可见光 成本低、部署快,适合明显变色、枯死松识别,是工程落地的第一步。
多光谱 能计算植被指数,增强健康植被和异常植被差异,适合重点区域精准复查。
高光谱 信息量更丰富,适合科研和示范项目,但设备成本、数据量和处理复杂度更高。

三、模型不是越复杂越好,业务闭环更关键

图 2:系统能力地图

如果目标只是“找出疑似病死松的位置”,目标检测模型就够用;如果要统计病害区域面积、冠层范围或斑块变化,语义分割更合适。工程里可以先用目标检测打通闭环,再逐步增加多光谱和分割能力。

防控场景里,漏报往往比误报更危险。但误报太多也会增加外业负担。所以系统应该支持不同策略:重点疫区提高召回率,普通巡查区平衡误报和漏报,处置复查区重点看定位精度和状态变化。

四、核心代码:影像识别结果如何进入系统

下面这段不是完整工程代码,而是核心逻辑示意:模型读取影像切片,输出疑似病死松目标,再把像素框转换为空间坐标,保存为待核查任务。

from ultralytics import YOLO
from osgeo import gdal
from shapely.geometry import box

model = YOLO("pine_dead_tree.pt")

def pixel_to_geo(dataset, x, y):
    gt = dataset.GetGeoTransform()
    lon = gt[0] + x * gt[1] + y * gt[2]
    lat = gt[3] + x * gt[4] + y * gt[5]
    return lon, lat

def detect_tile(image_path, task_id, model_version):
    dataset = gdal.Open(image_path)
    results = model.predict(image_path, conf=0.35, imgsz=1280)

    records = []
    for r in results:
        for b in r.boxes:
            x1, y1, x2, y2 = [float(v) for v in b.xyxy[0]]
            cx, cy = (x1 + x2) / 2, (y1 + y2) / 2
            lon, lat = pixel_to_geo(dataset, cx, cy)

            records.append({
                "taskId": task_id,
                "modelVersion": model_version,
                "className": "疑似病死松",
                "confidence": float(b.conf[0]),
                "longitude": lon,
                "latitude": lat,
                "pixelBox": [x1, y1, x2, y2],
                "status": "待外业核查"
            })
    return records

AI 输出必须包含任务 ID、模型版本、类别、置信度、坐标、原始框和状态。否则后面无法复核、无法追踪、也无法回流训练。

五、数据库设计:AI 结果和外业结论必须分开

图 3:数据对象分层

model FlightTask {
  id          String   @id @default(cuid())
  name        String
  areaName    String
  flightDate  DateTime
  sensorType  String   // RGB / Multispectral / Hyperspectral
  status      String
  images      ImageTile[]
  results     DetectionResult[]
}

model DetectionResult {
  id           String   @id @default(cuid())
  taskId       String
  imageId      String?
  modelName    String
  modelVersion String
  className    String   // 疑似变色松 / 疑似病死松 / 枯死松
  confidence   Float
  longitude    Float?
  latitude     Float?
  pixelBox     Json?
  status       String   // 待核查 / 已确认 / 误报 / 已处置

  task         FlightTask @relation(fields: [taskId], references: [id])
}

model FieldCheckTask {
  id          String   @id @default(cuid())
  resultId    String
  assignee    String?
  status      String   // 待核查 / 已核查 / 需复查
  checkDate   DateTime?
  conclusion  String?  // 确认病死松 / 非病死松 / 无法判断
  photoUrls   Json?
  remark      String?
}

这个设计有一个底线:AI 识别结果是“疑似”,外业核查结果才是“确认”。两个对象必须分开存,不能把模型置信度、人工结论、处置状态混成一个字段。

六、页面应该长什么样

航飞任务 查看航飞批次、区域、时间、传感器、影像数量和处理状态。
影像地图 展示正射影像底图、AI 识别框、置信度、坐标和前后期对比。
疑似病死松列表 按区域、置信度、核查状态、处置状态筛选,支持批量派发核查任务。
外业核查 现场人员查看点位、上传照片、填写结论,误报样本进入回流池。
处置台账 记录清理、砍伐、除害处理、复查、归档,形成防控闭环。

地图页是核心页面。用户不应该只看到一堆模型输出框,而应该能直接看到每个疑似点位在哪里、属于哪个林班小班、谁负责核查、核查结论是什么、有没有完成处置。

七、落地难点和优化方向

  • 早期症状不明显:轻微变色和健康树差异小,单靠 RGB 图像难度较高。
  • 季节光照影响大:坡向、阴影、季节变化会改变树冠颜色,模型跨区域泛化要重点验证。
  • 误报干扰多:红屋顶、裸土、枯草、道路边缘、其他树种变色都可能干扰识别。
  • 标注成本高:高质量样本需要林业人员参与,普通标注员容易把类别标错。

真正可持续的做法,是先选一个重点区域,把航飞、识别、定位、核查、处置、回流链路跑通。第一版模型不追求完美,但必须让核查数据回得来。只要数据闭环建立起来,模型才有持续优化的基础。

无人机解决覆盖和定位,AI 解决批量筛查,地图和任务系统解决核查处置,样本回流解决持续变准。把这几件事连起来,松材线虫病无人机影像识别才不是演示,而是真正能服务防控的一套系统。

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐