具有 SAM2 分段的 NDVI 无人机

今天,我们通过使用带有多光谱相机的无人机并使用 SAM2 模型进行场分割和健康比较,将 NDVI 感知提升到一个新的水平。

具有 SAM2 分段的 NDVI 无人机

1. 硬件

我们使用了 OAK-D-SR 的 PCBA 并更换了一个 CCM(紧凑型相机模块),因此一个传感器感知可见光波段 (380-750nm),而另一个传感器感知近红外波段 (>750nm)。

OAK-D-SR 连接到 RPi Zero 2W,RPi Zero 2W 连接到 OAK-D-SR 并每秒保存两帧。这两款设备都由移动电源供电,再加上DJI Mini 2 SE无人机(249克),所有设备的重量总共386克。

2. SAM2 分段

录制左/右帧后,使用 SAM2 Dmo 应用程序,上传彩色视频,并选择(一次仅 3 个)我们感兴趣的字段。选择字段并运行模型后,您可以在“网络”选项卡的“propagate_in_video”请求下检查分段结果。将这些结果保存在一个文件中,然后对其进行解码和可视化。

SAM2 结果是 RLE 编码的,因此需要对其进行解码才能获得掩码。您可以使用 pycocotools 来解码掩码。


 
 
  1. from pycocotools import mask as mask_utils
  2. mask = mask_utils. decode(annotation[ "segmentation"])

3. NDVI比较

在演示的底部,您可以看到字段之间的 NDVI 比较。因为 NDVI 是相对的(不是绝对的),所以我们只能用它来比较字段的健康状况。

字段 6 具有最高的 NDVI 值,这从彩色 NDVI 图像中也很明显 - 它比其他字段更绿。

4. 可视化和代码

我们使用 Rerun 进行整个可视化,使用 OpenCV 进行图像处理和轮廓计算(以获得更好的可视化效果)。

以下是演示背后的主要逻辑。完整的代码可以在这里找到完整的演示可以在这里找到(包括SAM结果和视频)。


 
 
  1. # Run & initialize ReRun viewer
  2. rr.init( 'NDVI /w SAM2', spawn = True)
  3. # Prepare rerun visualization
  4. annotationContext = [( 0, "Background", ( 0, 0, 0, 0))]
  5. for i, color in enumerate(colors):
  6. annotationContext.append((i + 1, f "Field {i + 1}", color))
  7. rr.log(f "NDVI_Average/Field{i+1}",
  8. rr.SeriesLine(color =color, name =f "Field {i+1}")
  9. )
  10. rr.log( "Color", rr.AnnotationContext(annotationContext), timeless = True)
  11. t = 0
  12. size = ( 800, 1280)
  13. for frame_idx in range(len(sam_ data[ 0])):
  14. rr. set_ time_ sequence( "step", t)
  15. t + = 1
  16. frames = get_ all_frames()
  17. ndvi = calc_ndvi(frames[ 'color'], frames[ 'ir'])
  18. segmentations = np. zeros( size)
  19. for i, data in enumerate( get_sam_ output(frame_idx)):
  20. for result in data. get( "results", []):
  21. field_num = result[ 'object_id'] +i * 3 # 3 segmentations per file
  22. # Decode the RLE mask
  23. mask = np.array(maskUtils.decode(result[ "mask"]), dtype =np.uint 8)
  24. # Set full_mask to num where mask
  25. segmentations[mask = = 1] = field_num + 1 # as 0 is Background
  26. line_strips = get_contours(mask)
  27. rr.log(
  28. f "Color/Contours{field_num + 1}",
  29. rr.LineStrips 2D( line_strips, colors =colors[field_num])
  30. )
  31. rr.log(
  32. f "NDVI/Color/Contours{field_num + 1}",
  33. rr.LineStrips 2D( line_strips, colors =colors[field_num]
  34. )
  35. mean_ndvi = np.mean(ndvi[mask = = 1])
  36. rr.log(f "NDVI_Average/Field{field_num + 1}", rr.Scalar(mean_ndvi))
  37. rr.log( "Color/Image", rr.Image(frames[ 'color'][..., ::- 1]))
  38. rr.log( "NDVI/Color", rr.Image(frames[ 'ndvi_colorized'][..., ::- 1]))
  39. rr.log( "Color/Mask", rr.SegmentationImage(segmentations))

5. 可以进行的改进

需要注意的一点是,NDVI 是按图像视图计算的,而不是全局计算的。这就是为什么该字段的中位数 NDVI 会发生变化,而不是一个常数。为了改善这一点,我们可以使用整个视频(例如进行图像拼接)并计算整个区域的NDVI。

6. 结论

我们已经展示了如何使用带有多光谱相机的无人机来捕获 NDVI 图像,并使用 SAM2 模型进行现场分割和健康状况比较。这种方法可用于各种农业任务,例如监测作物健康、检测疾病等。

如果您有任何意见或建议,欢迎在评论中告诉我!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值