经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » 编程经验 » 查看文章
无人机照片贴地实现
来源:cnblogs  作者:当时明月在曾照彩云归  时间:2024/3/27 8:39:03  对本文有异议

1. 引言

将无人机拍摄拍摄的影像作为底图可以实现快速甚至实时的更新,这对于应急指挥(如,森林防火)有着很大的意义

常规的做法是使用无人机拍摄一组照片,然后将这一组照片放入生产软件(如,ContextCapture)生产正射影像,然后地图切片发布

这里记录的是另一种做法,直接将无人机照片贴地,这种方式速度很快,几乎无需后台处理,照片细节完整保留,当然这种方式存在着误差,尤其地势起伏较大的地方可能并不适用

2. 实现过程

这里先有以下设定:

  • 无人机拍摄的影像都是竖直向下的类似正射的照片(不是类正射的照片贴地视角会很奇怪)
  • 无人机的朝向是正北方向
  • 地面是接近于平面

无人机照片的位置关系如下图所示,可以根据这些数据快速简单地算出照片的贴地范围

image-20240326185312010

笔者这里使用的无人机是大疆无人机型号H20T,参考大疆官网给出的H20T的数据:技术参数_禅思 H20 系列无人机负载_DJI大疆行业应用

这里的DFOV是82.9°(广角相机)

上图中的widthheight是图片的宽高(单位:px),用以计算与斜边的角度

上图中的relative altitude是相对高度,表示地面与无人机(相机)的距离

widthheightrelative altitude都可以直接从照片中读取

要进行计算还有一点需要做的,就是把经纬度坐标转换为投影坐标系下的坐标,计算后再将投影坐标数据转换为经纬度,这样就完成了计算

详细的代码实现如下:

  1. /**
  2. * 根据照片的数据信息,将照片粘贴到地图上(最好是正射照片,无人机指向正北方)
  3. * @param imgWidth 图片宽度(像素)
  4. * @param imgHeight 图片高度(像素)
  5. * @param distance 相机与地面的距离(米)
  6. * @param url 图片的URL
  7. * @param latitude 照片中心点的纬度
  8. * @param longitude 照片中心点的经度
  9. * @param dfov 相机的视场角(默认为82.9)
  10. */
  11. function pasteImageByHeight(imgWidth, imgHeight, distance, url, latitude, longitude, dfov = 82.9) {
  12. console.log(imgWidth, imgHeight, distance, url, latitude, longitude, dfov)
  13. const thisDistance = parseFloat(distance)
  14. if (isNaN(thisDistance) || thisDistance <= 0) {
  15. globalAlert("照片与地面的距离信息有误")
  16. return
  17. }
  18. const thisLatitude = parseFloat(latitude)
  19. const thisLongitude = parseFloat(longitude)
  20. if (isNaN(thisLatitude) || isNaN(thisLongitude)) {
  21. globalAlert("照片的经纬度信息有误")
  22. return
  23. }
  24. const hypotenuse = distance * Math.tan(dfov / 2 * Math.PI / 180)
  25. const angle = Math.atan(imgHeight / imgWidth)
  26. const halfWidth = hypotenuse * Math.sin(angle)
  27. const halfHeight = hypotenuse * Math.cos(angle)
  28. const projCrs = "+proj=utm +zone=51 +datum=WGS84 +units=m +no_defs"
  29. const projectedPos = Proj4("EPSG:4326", projCrs, [thisLongitude, thisLatitude])
  30. const [x, y] = projectedPos
  31. const leftTop = Proj4(projCrs, "EPSG:4326", [x + halfWidth, y + halfHeight])
  32. const rightBottom = Proj4(projCrs, "EPSG:4326", [x - halfWidth, y - halfHeight])
  33. console.log(leftTop, rightBottom)
  34. console.log({ xmin: rightBottom[0], xmax: leftTop[0], ymin: rightBottom[1], ymax: leftTop[1] })
  35. const imageLayer = new mars3d.layer.ImageLayer({
  36. name: "无人机航拍影像",
  37. url: url,
  38. rectangle: { xmin: rightBottom[0], xmax: leftTop[0], ymin: rightBottom[1], ymax: leftTop[1] },
  39. zIndex: 20,
  40. opacity: 0.6
  41. })
  42. map.addLayer(imageLayer)
  43. map.flyToExtent({
  44. xmin: longitude - 0.001,
  45. xmax: longitude + 0.001,
  46. ymin: latitude - 0.001,
  47. ymax: latitude + 0.001
  48. }, {
  49. duration: 1
  50. })
  51. return imageLayer.id as string
  52. }

最后实现的效果:

image-20240326200031524

下面是可以优化的一些地方:

  • 将图片保存到Rectangle Entity中,然后统一保存到一个Layer里,减少图片过多时的性能下降
  • 将图片保存到Rectangle Entity中,然后可以Rectangle Entity进行旋转,这样就无需让无人机保持正北朝向

3. 参考资料

[1] 功能示例(Vue版) | Mars3D三维可视化平台 | 火星科技

[2] 功能示例(Vue版) | Mars3D三维可视化平台 | 火星科技

原文链接:https://www.cnblogs.com/jiujiubashiyi/p/18097972

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号