PCL 计算字符型ply文件的法向量

文章目录

  • ply格式
  • 计算法向量意义
  • 具体代码

ply格式

PLY(Polygon File Format)是一种用于存储三维模型数据的文件格式。在PLY文件中,法向量是指每个顶点或面片的法向量,用于描述表面的朝向和光照计算。

在PLY文件中,法向量的定义通常位于文件头部的元数据(header)中。具体而言,法向量可以通过以下两种方式定义:

1.顶点法向量(Vertex Normals):对于每个顶点,可以指定一个法向量来描述该顶点周围的表面朝向。通常以属性名称"nx", “ny”, "nz"表示,表示顶点法向量在x、y、z轴上的分量。

2.面片法向量(Face Normals):对于每个面片(三角形或四边形),可以指定一个法向量来描述该面片的朝向。通常以属性名称"nx", “ny”, "nz"表示,表示面片法向量在x、y、z轴上的分量。

计算法向量意义

1.表面重建和拟合通过计算点云中每个点的法向量,可以对表面进行重建和拟合操作。法向量可用于估计点云中点的法线方向,从而得到平滑的表面拟合结果,用于生成三维模型或重建真实世界物体的几何形状。
2.物体识别和分类点云法向量可以用于物体的识别和分类。通过分析点云中每个点的法向量,可以提取表面的几何特征,如曲率、角度变化等,用于区分不同物体或物体的不同部分。
3.特征提取和描述点云法向量可用于特征提取和描述。通过计算点云中每个点的法向量,可以获得点云的局部几何信息。这些法向量可以与其他特征(如表面法线直方图、曲率等)结合使用,用于点云的特征提取、配准、匹配和分类等任务。
4.表面分析和曲面平滑点云法向量可以提供有关点云表面的局部几何信息,如表面的曲率、凹凸性等。这些信息可用于表面分析、曲面平滑和去噪等操作,帮助改善点云数据的质量和几何细节。

具体代码

#include <iostream>
#include <fstream>
#include <sstream>
#include <vector>
#include <string>
#include <cmath>//定义一个名为Vec3的结构体,用于表示三维向量,并提供向量操作,向量减法、叉积和归一化
struct Vec3 {float x, y, z;Vec3(float _x, float _y, float _z) : x(_x), y(_y), z(_z) {}Vec3 operator-(const Vec3& other) const {return Vec3(x - other.x, y - other.y, z - other.z);}Vec3 cross(const Vec3& other) const {return Vec3(y * other.z - z * other.y, z * other.x - x * other.z, x * other.y - y * other.x);}void normalize() {float length = std::sqrt(x * x + y * y + z * z);x /= length;y /= length;z /= length;}
};//定义一个Face的结构体,用于表示面,其中包含了一个保存顶点索引的整数向量
struct Face {std::vector<int> vertex_indices;
};bool readPLYFile(const std::string& file_path, std::vector<Vec3>& vertices, std::vector<Face>& faces) {std::ifstream ply_file(file_path);if (!ply_file.is_open()) {std::cerr << "Error: Could not open the PLY file." << std::endl;return false;}//解析文件头:通过逐行读取文件内容,循环解析文件的头部信息。头部通常包括描述顶点数量和面数量的元数据以及其他元数据。这些信息以文本行的形式存储在文件中。std::string line;while (std::getline(ply_file, line)) {//如果在某一行中找到了包含"element vertex"的字符串,//就提取出顶点数量并分配空间给vertices向量,以便存储顶点数据。if (line.find("element vertex") != std::string::npos) {int num_vertices;std::istringstream iss(line.substr(line.find_last_of(" ") + 1));iss >> num_vertices;vertices.reserve(num_vertices);}else if (line.find("element face") != std::string::npos) {//如果在某一行中找到了包含"element face"的字符串,//就提取出面的数量并分配空间给faces向量,以便存储面的数据。int num_faces;std::istringstream iss(line.substr(line.find_last_of(" ") + 1));iss >> num_faces;faces.reserve(num_faces);}else if (line == "end_header") {//如果在某一行中找到了"end_header"字符串,表示头部信息结束,跳出循环,开始读取顶点和面数据。break; }}//读取顶点数据:使用一个循环,按照顶点的数量逐个读取文件中的顶点数据。每个顶点通常由三个浮点数(x、y、z坐标)表示,所以从文件中读取这三个浮点数,并将它们作为Vec3对象添加到vertices向量中for (int i = 0; i < vertices.capacity(); ++i) {float x, y, z;ply_file >> x >> y >> z;vertices.emplace_back(x, y, z);}//读取面数据:使用另一个循环,按照面的数量逐个读取文件中的面数据。每个面通常包括一个整数(表示该面的顶点数)和一组顶点索引。在循环内,首先读取面的顶点数,然后读取相应数量的顶点索引,并将它们作为Face对象添加到faces向量中for (int i = 0; i < faces.capacity(); ++i) {int num_vertices;ply_file >> num_vertices;Face face;for (int j = 0; j < num_vertices; ++j) {int vertex_index;ply_file >> vertex_index;face.vertex_indices.push_back(vertex_index);}faces.push_back(face);}ply_file.close();return true;
}void calculateAndPrintNormals(const std::vector<Vec3>& vertices, const std::vector<Face>& faces) {for (const Face& face : faces) {//循环遍历faces向量:通过for循环,迭代遍历存储了面数据的faces向量,其中每个元素都是一个Face结构体,表示一个面if (face.vertex_indices.size() >= 3) {//检查面的顶点数量:对于每个面,首先检查其顶点索引数量是否大于等于3。这是因为计算法向矢量通常需要至少3个顶点来定义一个平面。//从vertices向量中提取出这些顶点的坐标信息。这些坐标信息存储在Vec3结构体中。const Vec3& v1 = vertices[face.vertex_indices[0]];const Vec3& v2 = vertices[face.vertex_indices[1]];const Vec3& v3 = vertices[face.vertex_indices[2]];//计算两个边向量:使用提取的顶点信息计算两个边向量,edge1和edge2。这些边向量是面的两条边的矢量差。Vec3 edge1 = v2 - v1;Vec3 edge2 = v3 - v1;//计算法向矢量:通过对边向量使用叉积运算计算法向矢量normal。法向矢量表示了面的朝向和方向。Vec3 normal = edge1.cross(edge2);normal.normalize();//归一化法向矢量:通过调用normalize方法,将法向矢量归一化,确保其长度为1std::cout << "Face Normal: (" << normal.x << ", " << normal.y << ", " << normal.z << ")\n";}}
}int main() {std::string inputFile = "E:\\****\\coordoutput.ply";std::vector<Vec3> vertices;std::vector<Face> faces; 读取PLY文件并解析顶点和面数据readPLYFile(inputFile, vertices, faces); 计算法向并打印结果calculateAndPrintNormals(vertices, faces);return 0;
}

法向量信息展示
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/107697.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Unity之创建第一个2D游戏项目

一 Unity环境配置 1.1 Untity资源官网下载&#xff1a;https://unity.cn/releases 1.2 Unity Hub集成环境&#xff0c;包含工具和项目的管理 1.3 Unity Editor编辑器 1.4 Visual Studio 2022脚本编辑器 1.5 AndroidSKD&#xff0c;JDK&#xff0c;NDK工具&#xff0c;用于and…

Gartner 2023API管理市场指南重磅发布,得帆云iPaaS标杆入榜

中国API管理-市场指南 Market Guide for API Management, China 是由全球最具权威的IT咨询与研究机构Gartner发布、聚焦中国API管理市场领域的专业研究报告&#xff0c;通过对市场概况以及代表厂商的分析&#xff0c;为企业决策者提供重要依据与参考。 得帆云iPaaS融合集成平台…

PPT架构师架构技能图

PPT架构师架构技能图 目录概述需求&#xff1a; 设计思路实现思路分析1.软素质2.核心输出&#xff08;office输出&#xff09; 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,ma…

算法:移除数组中的val的所有元素---双指针[2]

文章来源&#xff1a; https://blog.csdn.net/weixin_45630258/article/details/132689237 欢迎各位大佬指点、三连 1、题目&#xff1a; 给你一个数组 nums和一个值 val&#xff0c;你需要原地移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用…

通过 Blob 对二进制流文件下载实现文件保存下载

原理&#xff1a;前端将二进制文件做转换实现下载: 请求后端接口->接收后端返回的二进制流(通过二进制流&#xff08;Blob&#xff09;下载,把后端返回的二进制文件放在 Blob 里面)->再通过file-saver插件保存 页面上使用&#xff1a; <span click"downloadFil…

上海亚商投顾:三大指数小幅下跌 光刻机概念股午后走强

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 三大指数昨日小幅调整&#xff0c;创业板指走势较弱。减肥药概念股继续大涨&#xff0c;常山药业2连板&#x…

MySQL日常使用记录

1.时间 1.1.时间格式化 yyyy-MM-dd HH:mm:ss格式&#xff0c;如下&#xff1a; select date_format(now(), %Y-%m-%d %H:%i:%s) from dual;date_format函数是将date类型按照指定的格式转换成varchar类型 1.2.日期加减 当前天 1 天 select date_format(now(), %Y-%m-%d), …

概念解析 | 揭秘视觉与语言交叉模型:CLIP和BLIP的介绍

注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:CLIP和BLIP模型。 揭秘视觉与语言交叉模型:CLIP和BLIP的介绍 🎯 [LB: 0.45836] ~ BLIP+CLIP | CLIP Interrogator | Kaggle 大纲: 背景介绍原理介绍和推导 CLIP模型BLIP模…

外观数列问题

给定一个正整数 n &#xff0c;输出外观数列的第 n 项。 「外观数列」是一个整数序列&#xff0c;从数字 1 开始&#xff0c;序列中的每一项都是对前一项的描述。 你可以将其视作是由递归公式定义的数字字符串序列&#xff1a; countAndSay(1) "1" countAndSay(n…

继续上一个爬虫,所以说selenium加browsermobproxy

继续&#xff0c;书接上回&#xff0c;这次我通过jsrpc&#xff0c;也学会了不少逆向的知识&#xff0c;感觉对于一般的网站应该都能应付了。当然我说的是简单的网站&#xff0c;遇到那些混淆的&#xff0c;还有那种猿人学里面的题目&#xff0c;还是免谈了。那种需要的水平太高…

python-爬虫-urllib3

导入模块 import urllib3urllib3&#xff1a;功能强大、条理清晰、用于HTTP客户端的python网络请求库 重要特征 1.线程安全 2.连接池 3.客户端SSL/TLS验证 4.使用分段编码长传文件 5.重试请求和处理HTTP复位的助手 6.支持gzip和deflate编码 7.HTTP和SOCKS的代理支持 8.100%的…

【Linux网络】TCP/IP三次握手、四次挥手流程

目录 一、三次握手&#xff0c;建立连接 二、四次挥手&#xff0c;断开连接 三、主要字段 1、标志位&#xff08;Flags&#xff09; 2、序号&#xff08;sequence number&#xff09; 3、确认号&#xff08;acknowledgement number&#xff09; 四、三次握手的报文变化 五…