3d 如何计算此三维网格的体积?

3d 如何计算此三维网格的体积?,3d,kinect,3d,Kinect,我为一个项目工作。我们生成一个3D网格,我需要计算一个3D对象的几个体积 我不知道怎么计算,我想数学知识太少了。有没有办法计算这个 EDTI:我不是在寻找所有的代码,而是方向或伪代码我相信如果有一个标题要求计算乳房体积,你会得到更多的回应:) 首先,为了计算网格的体积,它应该是一个闭合的网格。因此,我认为您需要选择不需要的面/顶点,并将其从网格中移除。 然后找到关闭卷的方法: 在Meshlab中:尝试“点集”下的“泊松”选项 或使用搅拌器手动关闭音量 一旦这样做了,它就变得容易了 诀窍是根据

我为一个项目工作。我们生成一个3D网格,我需要计算一个3D对象的几个体积

我不知道怎么计算,我想数学知识太少了。有没有办法计算这个


EDTI:我不是在寻找所有的代码,而是方向或伪代码

我相信如果有一个标题要求计算乳房体积,你会得到更多的回应:)

首先,为了计算网格的体积,它应该是一个闭合的网格。因此,我认为您需要选择不需要的面/顶点,并将其从网格中移除。 然后找到关闭卷的方法:

  • 在Meshlab中:尝试“点集”下的“泊松”选项
  • 或使用搅拌器手动关闭音量
一旦这样做了,它就变得容易了

诀窍是根据三角形计算四面体的有符号体积,并在原点处结束。体积的符号来自三角形是否指向原点的方向。(三角形的法线本身取决于顶点的顺序,这就是为什么您看不到它在下面被明确引用的原因。)

这一切归结为以下简单函数:

float signedVolumeOfTriangle(pcl::PointXYZ p1, pcl::PointXYZ p2, pcl::PointXYZ p3) 
{
    float v321 = p3.x*p2.y*p1.z;
    float v231 = p2.x*p3.y*p1.z;
    float v312 = p3.x*p1.y*p2.z;
    float v132 = p1.x*p3.y*p2.z;
    float v213 = p2.x*p1.y*p3.z;
    float v123 = p1.x*p2.y*p3.z;
    return (1.0f/6.0f)*(-v321 + v231 + v312 - v132 - v213 + v123);
}
然后是计算网格体积的函数:

float volumeOfMesh(pcl::PolygonMesh mesh) 
{
    float vols = 0.0;
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
    pcl::fromPointCloud2(mesh.cloud,*cloud);
    for(int triangle=0;triangle<mesh.polygons.size();triangle++)
    {
        pcl::PointXYZ pt1 = cloud->points[mesh.polygons[triangle].vertices[0]];
        pcl::PointXYZ pt2 = cloud->points[mesh.polygons[triangle].vertices[1]];
        pcl::PointXYZ pt3 = cloud->points[mesh.polygons[triangle].vertices[2]];
        vols += signedVolumeOfTriangle(pt1, pt2, pt3);
    }
    return Math.Abs(vols.Sum());
}
浮动体积网格(pcl::多边形网格) { 浮动容积=0.0; pcl::PointCloud::Ptr cloud(新的pcl::PointCloud); pcl::fromPointCloud2(mesh.cloud,*cloud); 对于(int triangle=0;trianglepoints[mesh.polygons[triangle]。顶点[0]]; pcl::PointXYZ pt2=云->点[网格.多边形[三角形].顶点[1]]; pcl::PointXYZ pt3=云->点[网格.多边形[三角形].顶点[2]]; 体积+=三角体的签名体积(pt1、pt2、pt3); } 返回Math.Abs(vols.Sum()); }
我没有测试代码,也不知道你是否可以使用PCL,但这应该让你开始了。

我已经用ubuntu-18.04的PCL-1.8.1完成了@Deepfreeze的代码。报纸的url链接更新, 请注意,代码应为“pcl::fromPCLPointCloud2”

main.cpp

#include <iostream>
#include <pcl/point_types.h>
#include <pcl/io/obj_io.h>
#include <pcl/io/vtk_lib_io.h>
#include <pcl/conversions.h>
#include <cmath>
float signedVolumeOfTriangle (pcl::PointXYZ p1, pcl::PointXYZ p2, pcl::PointXYZ p3) 
{
    float v321 = p3.x*p2.y*p1.z;
    float v231 = p2.x*p3.y*p1.z;
    float v312 = p3.x*p1.y*p2.z;
    float v132 = p1.x*p3.y*p2.z;
    float v213 = p2.x*p1.y*p3.z;
    float v123 = p1.x*p2.y*p3.z;
    return (1.0f/6.0f)*(-v321 + v231 + v312 - v132 - v213 + v123);
}

float volumeOfMesh(pcl::PolygonMesh mesh) 
{
    float vols = 0.0;
    pcl::PointCloud<pcl::PointXYZ>::Ptr cloud (new pcl::PointCloud<pcl::PointXYZ>);
    pcl::fromPCLPointCloud2(mesh.cloud, *cloud);
    for(int triangle=0;triangle<mesh.polygons.size();triangle++)
    {
        pcl::PointXYZ pt1 = cloud->points[mesh.polygons[triangle].vertices[0]];
        pcl::PointXYZ pt2 = cloud->points[mesh.polygons[triangle].vertices[1]];
        pcl::PointXYZ pt3 = cloud->points[mesh.polygons[triangle].vertices[2]];
        vols += signedVolumeOfTriangle(pt1, pt2, pt3);
    }
    return abs(vols);
}

int main(int argc, char **argv) {
    pcl::PolygonMesh mesh;
    pcl::io::loadOBJFile(argv[1], mesh);
    std::cout << volumeOfMesh(mesh) << std::endl;
    return 0;
}

在此处发布您的代码/信息。没有人希望访问外部站点来help@JonathonReinhartpic补充说,我今天无法访问他们的网站。应该重新开始工作。虽然六年过去了,我们仍然努力获得乳房的大小。在我看来,他们不亚于B杯。
cmake_minimum_required(VERSION 2.8 FATAL_ERROR)

project(mesh_volume)

find_package(PCL 1.8 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})

add_executable (${PROJECT_NAME} main.cpp)
target_link_libraries (${PROJECT_NAME} ${PCL_LIBRARIES})