当前位置: 首页 > news >正文

CGAL 从DSM到DTM filtering

CGAL 从DSM到DTM filtering

上一节通过连通区域计算并将连通信息保存到三角面片中,获取了多个连通区域,本节将设置阈值将建筑物区域移除,生成一个最初的DTM

建筑物区域去除

设置阈值为min_size,遍历三角面片,对连通区域(>= 0)且大于阈值的区域予以保留,剩下的面片予以移除。

代码

#include<iostream>
#include <queue>#include<CGAL/Surface_mesh.h>
#include<CGAL/Surface_mesh/IO/PLY.h>
#include <CGAL/draw_surface_mesh.h>#include <CGAL/Exact_predicates_inexact_constructions_kernel.h>
#include <CGAL/Projection_traits_xy_3.h>
#include <CGAL/Delaunay_triangulation_2.h>
#include <CGAL/Triangulation_vertex_base_with_info_2.h>
#include <CGAL/Triangulation_face_base_with_info_2.h>#include <CGAL/Polygon_mesh_processing/triangulate_hole.h>
#include <CGAL/Polygon_mesh_processing/border.h>
#include <CGAL/Polygon_mesh_processing/remesh.h>#include <CGAL/boost/graph/graph_traits_Delaunay_triangulation_2.h>
#include <CGAL/boost/graph/copy_face_graph.h>#include <CGAL/compute_average_spacing.h>using Kernel = CGAL::Exact_predicates_inexact_constructions_kernel;using Projection_traits = CGAL::Projection_traits_xy_3<Kernel>;using Point_2 = Kernel::Point_2;
using Point_3 = Kernel::Point_3;
using Mesh = CGAL::Surface_mesh<Point_3>;using Concurrency_tag = CGAL::Sequential_tag;using TIN = CGAL::Delaunay_triangulation_2<Projection_traits>;
using Vbi = CGAL::Triangulation_vertex_base_with_info_2 <Mesh::Vertex_index, Projection_traits>;
using Fbi = CGAL::Triangulation_face_base_with_info_2<int, Projection_traits>;
using TDS = CGAL::Triangulation_data_structure_2<Vbi, Fbi>;
using TIN_with_info = CGAL::Delaunay_triangulation_2<Projection_traits, TDS>;int main() {Mesh mesh;CGAL::IO::read_PLY("./data/dsm.ply", mesh);auto idx_to_point_with_info= [&](const Mesh::Vertex_index& idx) -> std::pair<Point_3, Mesh::Vertex_index>{return std::make_pair ( mesh.point(idx), idx);};TIN_with_info tin_with_info(boost::make_transform_iterator (mesh.vertices().begin(), idx_to_point_with_info),boost::make_transform_iterator (mesh.vertices().end(), idx_to_point_with_info));double spacing = CGAL::compute_average_spacing<Concurrency_tag>(mesh.points(), 6);spacing *= 2;auto face_height= [&](const TIN_with_info::Face_handle fh) -> double{double out = 0.;for (int i = 0; i < 3; ++ i)out = (std::max) (out, CGAL::abs(fh->vertex(i)->point().z() - fh->vertex((i+1)%3)->point().z()));return out;};// Initialize faces info for (TIN_with_info::Face_handle fh : tin_with_info.all_face_handles())if (tin_with_info.is_infinite(fh) || face_height(fh) > spacing) // Filtered faces are given info() = -2fh->info() = -2;else // Pending faces are given info() = -1;fh->info() = -1;// Flooding algorithmstd::vector<int> component_size;for (TIN_with_info::Face_handle fh : tin_with_info.finite_face_handles()){if (fh->info() != -1)continue;std::queue<TIN_with_info::Face_handle> todo;todo.push(fh);int size = 0;while (!todo.empty()){TIN_with_info::Face_handle current = todo.front();todo.pop();if (current->info() != -1)continue;current->info() = int(component_size.size());++ size;for (int i = 0; i < 3; ++ i)todo.push (current->neighbor(i));}component_size.push_back (size);}std::cerr << component_size.size() << " connected component(s) found" << std::endl;/////! [Filtering]int min_size = int(mesh.vertices().size() / 2);std::vector<TIN_with_info::Vertex_handle> to_remove;for (TIN_with_info::Vertex_handle vh : tin_with_info.finite_vertex_handles()){TIN_with_info::Face_circulator circ = tin_with_info.incident_faces (vh),start = circ;// Remove a vertex if it's only adjacent to components smaller than thresholdbool keep = false;do{if (circ->info() >= 0 && component_size[std::size_t(circ->info())] > min_size){keep = true;break;}}while (++ circ != start);if (!keep)to_remove.push_back (vh);}std::cerr << to_remove.size() << " vertices(s) will be removed after filtering" << std::endl;for (TIN_with_info::Vertex_handle vh : to_remove)tin_with_info.remove (vh);// Copy and keep track of overly large facesMesh dtm_mesh;CGAL::copy_face_graph (tin_with_info, dtm_mesh);// Save original DTMstd::ofstream dtm_ofile ("dtm_filtering.ply", std::ios_base::binary);CGAL::IO::set_binary_mode (dtm_ofile);CGAL::IO::write_PLY (dtm_ofile, dtm_mesh);dtm_ofile.close();return 0;}

如下图所示,移除建筑物的区域,并在孔洞处重新剖分为large faces大面:

132 connected component(s) found
10805 vertices(s) will be removed after filtering

filtering

构建编译运行

cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=D:\vcpkg\scripts\buildsystems\vcpkg.cmake
cmake --build build --config Debug
.\build\Debug\filtering.exe

参考

  1. https://doc.cgal.org/latest/Manual/tuto_gis.html

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 中间件之RocketMQ
  • BSN六周年:迈向下一代互联网
  • USB组合设备——鼠标+键盘(两个接口实现)
  • [全网首发]怎么让国行版iPhone使用苹果Apple Intelligence
  • JAVA语言之Solr的工作原理以及如何管理索引库
  • 设备无关色彩 vs 设备相关色彩空间
  • C# Redis 框架开发技术详解
  • 【Android Studio】API 29(即Android 10)或更高版本,在程序启动时检查相机权限,并在未获取该权限时请求它
  • 道路检测-目标检测数据集(包括VOC格式、YOLO格式)
  • Windows与Linux下 SDL2的第一个窗口程序
  • 【开发语言】写程序的两大基本原则(PO和NT原则)
  • 基于STM32设计的智能货架(华为云IOT)(225)
  • 【重学 MySQL】二十九、函数的理解
  • 神经网络通俗理解学习笔记(3)注意力神经网络
  • Html css水平居中+垂直居中+水平垂直居中的方法总结
  • 《Java8实战》-第四章读书笔记(引入流Stream)
  • CentOS学习笔记 - 12. Nginx搭建Centos7.5远程repo
  • Django 博客开发教程 16 - 统计文章阅读量
  • ERLANG 网工修炼笔记 ---- UDP
  • express + mock 让前后台并行开发
  • Git学习与使用心得(1)—— 初始化
  • JAVA多线程机制解析-volatilesynchronized
  • Linux Process Manage
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • 基于HAProxy的高性能缓存服务器nuster
  • 力扣(LeetCode)357
  • 聊聊spring cloud的LoadBalancerAutoConfiguration
  • 罗辑思维在全链路压测方面的实践和工作笔记
  • 如何设计一个比特币钱包服务
  • 它承受着该等级不该有的简单, leetcode 564 寻找最近的回文数
  • 腾讯视频格式如何转换成mp4 将下载的qlv文件转换成mp4的方法
  • 想写好前端,先练好内功
  • 优秀架构师必须掌握的架构思维
  • 关于Android全面屏虚拟导航栏的适配总结
  • ​学习笔记——动态路由——IS-IS中间系统到中间系统(报文/TLV)​
  • ###51单片机学习(1)-----单片机烧录软件的使用,以及如何建立一个工程项目
  • #Linux(Source Insight安装及工程建立)
  • #如何使用 Qt 5.6 在 Android 上启用 NFC
  • (1综述)从零开始的嵌入式图像图像处理(PI+QT+OpenCV)实战演练
  • (2024,Flag-DiT,文本引导的多模态生成,SR,统一的标记化,RoPE、RMSNorm 和流匹配)Lumina-T2X
  • (4.10~4.16)
  • (二)丶RabbitMQ的六大核心
  • (附源码)计算机毕业设计SSM教师教学质量评价系统
  • (篇九)MySQL常用内置函数
  • (四)Tiki-taka算法(TTA)求解无人机三维路径规划研究(MATLAB)
  • (转)全文检索技术学习(三)——Lucene支持中文分词
  • (转载)VS2010/MFC编程入门之三十四(菜单:VS2010菜单资源详解)
  • .net 验证控件和javaScript的冲突问题
  • .Net 转战 Android 4.4 日常笔记(4)--按钮事件和国际化
  • .NET/C# 编译期间能确定的相同字符串,在运行期间是相同的实例
  • .NET和.COM和.CN域名区别
  • .NET开源快速、强大、免费的电子表格组件
  • .NET开源项目介绍及资源推荐:数据持久层
  • .NET命名规范和开发约定
  • .NET运行机制