• 点云体积计算

  有时用激光扫描设备扫描零件或者用无人机进行测量后会想知道它们的体积。比如下面的土堆:

   如果扫描得到的数据是一系列三维点云,那么体积就比较难求,因为如何定义物体的边界比较困难。一种方法是提取三维点云的凸壳(包络体),然后再进行计算(当存在孔、洞时情况就很复杂了)。还有一种简便的估算方法如下图所示,将2.5D点云底面划分成离散的网格,计算每个网格对应单元的体积并相加求和。

point cloud dimension:
1.5D – function values along a line
  2D – positions in the plane
2.5D – function values in the plane
  3D – positions in 3D
  nD – multi-modal data 

  CloudCompare软件中提供了计算2.5D点云体积的功能:

   导入PCD格式的点云,其体积大概为1(在XYZ方向分别生成0-1的随机数,一共200个随机点):

   在体积计算界面中定义地面(Ground)及顶面(Ceil):这里地面选为常量,值为0;顶面选为点云,空单元(不包含数据点)不参与体积计算,这里将其选为leave empty。网格划分步长step不能选的太大或太小,选的太小将会有很多单元成为空单元,选的太大会出现较大的计算误差。下图可以看出步长设的太小,导致Matching cell为0,即全是空单元,因此计算出的体积也为零,显然不符合实际情况:

  设置合理的步长后点击Update进行计算,可以看到估算出的点云体积为1.311接近1:

 

 

  •  网格模型体积计算

  在VTK中可以使用vtkMassProperties类来计算模型的体积和表面积(The general assumption here is that the model is of closed surface. Currently only triangles are processed. Use vtkTriangleFilter to convert any strips or polygons to triangles)。因为只能处理三角面片的polydata,需要在pipline中前置vtkTriangleFilter将其他网格类型转换成三角网格类型。下面代码计算Solidworks中导出的STL网格模型的体积和表面积:

#!/usr/bin/env python
import vtk

filename = "C:\Users\Administrator\Desktop\part.stl"
 
reader = vtk.vtkSTLReader()
reader.SetFileName(filename)
reader.Update()
polydata = reader.GetOutput()

mass = vtk.vtkMassProperties()
mass.SetInputData(polydata)

print "Surface = ", mass.GetSurfaceArea()
print "Volume = ",  mass.GetVolume()

  Solidworks原始CAD模型导出成stl文件时由于精度限制,因此存在一定的误差。在CloudCompare软件中也可以很方便的对网格模型进行体积、表面积测量:

参考:

Algorithm for calculating the volume of the part of point cloud—stackoverflow

How Pix4Dmapper calculates the Volume?

Compute 2.5D volume

CloudCompare - 3D point cloud and mesh processing software 

Volume estimation

VTK体积&表面积测量