CGAL 从DSM到DTM-建筑物区域提取
CGAL 从DSM到DTM-建筑物区域提取
生成的DSM被用作DTM计算的基础,即地面表示为过滤掉非地面点后的另一个TIN。主要是去除一些建筑物和植被非地形点。
建筑物立面及连通区域提取
建筑物立面的特征是三角形面片的高度变化剧烈。
通过遍历每一个三角面片,计算顶点之间最大的高差face_height
,与事先设置的阈值spacing
比较,大于阈值或包含无限远点infinite_vertex
标记为建筑物立面。
除去建筑物立面,对剩下的三角面片使用洪水算法
确定连通区域,并标记对应的区域id
,取值范围:[0,component_size.size()]
。
代码
#include<iostream>#include<CGAL/Surface_mesh.h>
#include<CGAL/Surface_mesh/IO/PLY.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/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_3 = Kernel::Point_3;
using Mesh = CGAL::Surface_mesh<Point_3>;using Concurrency_tag = CGAL::Sequential_tag;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 初始化三角面附件信息(int类型)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;Mesh tin_colored_mesh;//Mesh::Property_map<Mesh::Face_index, CGAL::IO::Color>color_map = tin_colored_mesh.add_property_map<Mesh::Face_index, CGAL::IO::Color>("f:color").first;CGAL::copy_face_graph (tin_with_info, tin_colored_mesh,CGAL::parameters::face_to_face_output_iterator(boost::make_function_output_iterator([&](const std::pair<TIN_with_info::Face_handle, Mesh::Face_index>& ff){// 灰色标记建筑物立面及待处理的其他非地面点if (ff.first->info() < 0){color_map[ff.second] = CGAL::IO::Color(128, 128, 128);// put(color_map, ff.second, CGAL::IO::Color(128, 128, 128));}else{// 其他标记随机颜色CGAL::Random r (ff.first->info());color_map[ff.second] = CGAL::IO::Color (r.get_int(64, 192),r.get_int(64, 192),r.get_int(64, 192));/*put(color_map, ff.second, CGAL::IO::Color(r.get_int(64, 192),r.get_int(64, 192),r.get_int(64, 192)));*/}})));std::ofstream tin_colored_ofile ("colored_tin.ply", std::ios_base::binary);CGAL::IO::set_binary_mode (tin_colored_ofile);CGAL::IO::write_PLY (tin_colored_ofile, tin_colored_mesh);tin_colored_ofile.close();return 0;
}
如下图所示,灰色标记为建筑物立面,其他联通区域标记随机颜色:
构建编译运行
cmake -B build -S . -DCMAKE_TOOLCHAIN_FILE=D:\vcpkg\scripts\buildsystems\vcpkg.cmake
cmake --build build --config Debug
.\build\Debug\coloredTIN.exe
参考
- https://doc.cgal.org/latest/Manual/tuto_gis.html
相关文章:

CGAL 从DSM到DTM-建筑物区域提取
CGAL 从DSM到DTM-建筑物区域提取 生成的DSM被用作DTM计算的基础,即地面表示为过滤掉非地面点后的另一个TIN。主要是去除一些建筑物和植被非地形点。 建筑物立面及连通区域提取 建筑物立面的特征是三角形面片的高度变化剧烈。 通过遍历每一个三角面片,…...

Python--编码解码报错
报错问题 错误信息 UnicodeDecodeError: gbk codec cant decode byte 0xac in position 2: illegal multibyte sequence 通常出现在尝试使用 GBK 编码解码某些二进制数据时,但数据中包含了无法被 GBK 解码的字符。具体错误提示是解码器在处理某个字节时发现该字节无…...

大屏可视化常用图标效果表达
1-echarts-雷达图 2-echarts-仪表盘 3-echarts-水球图(利用插件,echarts-liquidfill) 4-element UI tree 添加连接线,修改样式或使用插件(element-tree-line) 5-echarts-漏斗图 6-echarts-饼状图嵌套 optio…...

高通Liunx 系统镜像编译
本文将会介绍如何在编译高通Liunx代码, 具体可以在高通 Linux | 高通下查看相关信息。 编译服务器配置 首先,准备一台Ubuntu 22.04版本主机或者服务器 1,编译Yocto 系统,需要如下一些配置 sudo apt update sudo apt install repo gawk wg…...

105、解析Java中1000个常用类:StringTokenizer类,你学会了吗?
在线工具站 推荐一个程序员在线工具站:程序员常用工具(http://cxytools.com),有时间戳、JSON格式化、文本对比、HASH生成、UUID生成等常用工具,效率加倍嘎嘎好用。程序员资料站 推荐一个程序员编程资料站:程序员的成长之路(http://cxyroad.com),收录了一些列的技术教程…...

虚幻引擎 | 实时语音转口型 Multilingual lipsync
实时语音转口型:EPIC的metahuman sdk,NVIDIA的audio2face,都好。本文使用metahuman sdk 需要工具:Metahuman SDK网页账号,获取两日免费tokens https://space.metahumansdk.io/#/unauthorized ———————————…...

vue国际化
前言 现在的大公司都走国际化路线,我们应用程序也不例外。今天就在 Vue3 项目中整一个比较简单的国际化 背景 之前搞国际化的时候,也搜索了很多帖子,但是没有一个可以完整的实现。今天有空搞了一版,大家有什么问题欢迎留言探讨…...

解决tiktoken库调用get_encoding时SSL超时
文章目录 解决tiktoken库调用get_encoding时SSL超时1. 获取词表文件url2. 手动下载词表文件并保存到本地3. 复制并重命名文件4. 环境变量中设置tiktoken cache5. 使用tiktoken库参考资料 解决tiktoken库调用get_encoding时SSL超时 最近在看Build a Large Language Model (From…...

C++从入门到起飞之——继承上篇 全方位剖析!
🌈个人主页:秋风起,再归来~🔥系列专栏:C从入门到起飞 🔖克心守己,律己则安 目录 1、继承的概念 2、继承定义 2.1 定义格式 2.2 继承基类成员访问⽅式的变化 3、继承类模板 4、 基…...

【文件包含】——日志文件注入
改变的确很难,但结果值得冒险 本文主要根据做题内容的总结,如有错误之处,还请各位师傅指正 一.伪协议的失效 当我们做到关于文件包含的题目时,常用思路其实就是使用伪协议(php:filter,data,inpput等等)执行…...

UE5源码Windows编译、运行
官方文档 Welcome To Unreal Engine 5 Early Access Learn what to expect from the UE5 Early Access program. 链接如下:https://docs.unrealengine.com/5.0/en-US/Welcome/#gettingue5earlyaccessfromgithub Step 0:找到UE5源码 直接先上链接 https…...

AI大模型与产品经理:替代与合作的深度剖析
在创业的征途中,产品经理常常被外界以一种半开玩笑的口吻提及:“就差一个程序员了。”这句话背后,既蕴含着对产品经理创意与策略能力的认可,也揭示了技术实现环节对于产品成功不可或缺的重要性。然而,随着AI技术的飞速…...

资本的运作方式、贷款的评估标准、杠杆率
在资本领域,涉及到多个角色和复杂的运作机制。以下是一些主要的角色及其运作方式: 主要角色 政府: 发行债券:政府通过发行国债和其他债券来筹集资金,用于公共支出和基础设施建设。货币政策:政府通过调节利…...

Python:抓取 Bilibili(B站)评论、弹幕、字幕等
个人学习需求,需要获取一些 UGC(user generated content),包括 UP 的内容、弹幕、评论等。于是从 哔哩哔哩 (゜-゜)つロ 干杯~-bilibili 抓取了一些数据,以下内容仅供学习参考。 目录 1. Python 包:bilib…...

Ubuntu系统Docker部署数据库管理工具DbGate并实现远程查询数据
文章目录 前言1. 安装Docker2. 使用Docker拉取DbGate镜像3. 创建并启动DbGate容器4. 本地连接测试5. 公网远程访问本地DbGate容器5.1 内网穿透工具安装5.2 创建远程连接公网地址5.3 使用固定公网地址远程访问 前言 本文主要介绍如何在Linux Ubuntu系统中使用Docker部署DbGate数…...

18063 圈中的游戏
### 思路 1. 创建一个循环链表表示围成一圈的 n 个人。 2. 从第一个人开始报数,每报到 3 的人退出圈子。 3. 重复上述过程,直到只剩下一个人。 4. 输出最后留下的人的编号。 ### 伪代码 1. 创建一个循环链表,节点表示每个人的编号。 2. 初始…...

【Spring Boot】SpringBoot自动装配-Import
目录 一、前言二、 定义三、使用说明3.1 创建项目3.1.1 导入依赖3.1.2 创建User类 3.2 测试导入Bean3.2.1 修改启动类 3.3 测试导入配置类3.3.1 创建UserConfig类3.3.2 修改启动类 3.4 测试导入ImportSelector3.4.1 创建UseImportSelector类3.4.2 修改启动类3.4.3 启动测试 3.5…...

C++:opencv计算轮廓周长--cv::arcLength
cv::arcLength 是 OpenCV 中用于计算轮廓的周长或曲线长度的函数。它是计算图像轮廓特征时非常有用的工具,特别是在处理形状分析、对象检测等任务时。 函数原型 double cv::arcLength(const cv::InputArray& curve, bool closed);curve: 输入的曲线或轮廓&…...

探索学习Python的最佳开发环境和编辑器
Python,作为目前最受欢迎的编程语言之一,因其简洁明了的语法和强大的功能性而备受开发者喜爱。无论是数据科学、机器学习、Web开发还是自动化脚本,Python都有着广泛的应用。选择合适的开发环境和编辑器对于提高编程效率和学习体验至关重要。 …...

【Pycharm】Pycharm创建Django提示pip版本需要升级
目录 1、现象 2、分析 3、本质 前言:经常使用pycharm创建django、flask等项目时候提示pip版本需要升级,解决方案 1、现象 使用Pycharm创建Django项目提示安装Django超时,报错建议pip升级22升级到24 2、分析 之前使用命令升级了pip到了24…...

模拟退火算法(SA算法)求解实例---旅行商问题 (TSP)
目录 一、采用SA求解 TSP二、 旅行商问题2.1 实际例子:求解 6 个城市的 TSP2.2 **求解该问题的代码**2.3 代码运行过程截屏2.4 代码运行结果截屏(后续和其他算法进行对比) 三、 如何修改代码?3.1 减少城市坐标,如下&am…...

衡石分析平台使用手册--替换衡石 metadb
替换衡石 metadb 在使用 HENGSHI SENSE 服务过程中,可以根据业务需要替换 HENGSHI 自带的 metadb。本文讲述使用云服务 PostgreSQL 替代衡石 metadb 的过程。 准备工作 在进行配置前,请在云服务 PostgreSQL 上完成如下准备工作。 [必须] 配置衡石…...

【Unity学习心得】如何制作俯视角射击游戏
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、导入素材二、制作流程 1.制作地图2.实现人物动画和移动脚本3.制作单例模式和对象池4.制作手枪pistol和子弹bullet和子弹壳bulletShell5.制作散弹枪shotgun总…...

【资料分析】常见的坑
in 比较或计数类问题 差别大的基期比较,可以直接用现期进行比较 注意单位可能不同! 注意顺序是从小到大还是从大到小 以及老问题,名字本身就叫XX增量,XX增加值,而非还要另外去算的东东 给出的图表可能是不完整的 2…...

GitLab权限及设置
之前很少关注这些,项目的权限,一般由专门的管理人员设置。 但自己创建的项目自己可以设置权限。下面是一些笔记。 GitLab中用户权限_gitlab 权限-CSDN博客 开发中遇到要将自己这块的代码上传到Git,由其他组的同事拉取后继续开发。上传代码后…...

算法练习题24——查找杨辉三角中的组合数
题目描述 杨辉三角中的每个元素是一个组合数。第 ( i ) 行的第 ( j ) 个元素表示组合数 ( C(i, j) ) ,即从 ( i ) 个元素中选 ( j ) 个元素的组合方式。已知一个正整数 ( N ),要求在杨辉三角中找到这个数,并输出它在杨辉三角中的具体位置。位…...

string类的模拟实现
实现string的模拟实现分为三个文件,分别为:string.h、sting.cpp、test.cpp string.h 其中包含一些短小常用的函数的实现,头文件,函数的声明 #include<iostream> #include<string> #include<assert.h>using n…...

如何训练机器学习力场
机器学习力场(MLFF)的训练主要依赖于通过量子力学计算生成的高质量训练数据集,并利用不同的机器学习算法来拟合分子系统中的势能面(Potential Energy Surface, PES)和原子间作用力。这种训练过程包括数据准备、特征提取…...

AI创作新手册:精通Prompt提示词的提问策略
文章目录 🍊AI创作核心:提示词 Prompt 的重要性1. 什么是提示词工程?1.1 提示词的作用原理1.2 提示词工程师的薪资与行业前景1.3 提示词工程的适用性 2. 提示词的编写技巧3. 常见的提示词框架3.1 CO-STAR 框架3.2 BORKE 框架 4. 提示词的实际…...

gingivitis
gingivitis 牙龈炎 1)这个是啥不知道 2)七叶莲片 3)甲硝唑芬布芬胶囊 4)盐酸左氧氟沙星胶囊 5)纳珍 开始学习记录医生开的药。日常备药记录一下。【不要乱吃药哈】...