三维模型法向量计算及注意事项

【版权声明】
本文为博主原创文章,未经博主允许严禁转载,我们会定期进行侵权检索。

更多算法总结请关注我的博客:https://blog.csdn.net/suiyingy,或”乐乐感知学堂“公众号。
本文章来自于专栏《Python三维模型处理基础》的系列文章,专栏地址为:https://blog.csdn.net/suiyingy/category_12462636.html。

        上一节博文详细介绍了三维模型体积计算及其注意事项。在体积计算过程中,我们需要关注到三维模型的表面朝向,这个朝向可以通过法向量来进行观察,并且法向量的方向为正向,也就是我们默认能正常看到的部分。当然,我们也可以通过设置相机或视角位置来进行观察,这部分内容可在博文后续章节中进行查看。

1 表面法向量

        法向量是指垂直于平面的向量,并且法向量方向满足右手定则,下面将以三角面为例。三维点云在进行法向量计算的时候会根据临近点估算一个平面,然后针对该平面计算法向量。三维点云法向量计算方法及其程序请参考博文《点云法向量》,地址为“https://blog.csdn.net/suiyingy/article/details/124360873”。

        两个不共线的向量即可确定一个平面。三角面中的三个顶点两两之间可以组成3个向量,其中任意两个都能够用来表征其所在平面。假设三角形的3个顶点分别为A[0.0, 0.0, 1.0]、B[3.0, 0.0, 1.0]、C[0.0, 4.0, 1.0]。这是一个z高度为1.0的直角三角形。其3个向量分别为AB[3.0, 0.0, 0.0]、AC[0.0, 4.0, 0.0]、BC[-3.0, 4.0, 0.0]。垂直两个向量的法向量可用向量叉乘来进行计算,python numpy库中相应的计算函数为numpy.cross。通常情况下,平面法向量是经过归一化的,即模长为1。法向量直接计算结果的起点为坐标原点,即[0.0, 0.0, 0.0]。

AB × AC  -> [0.0, 0.0, 12.0] -> 归一化:[0.0, 0.0, 1.0]

AB × BC  -> [0.0, 0.0, 12.0] -> 归一化:[0.0, 0.0, 1.0]

AC × BC  -> [0.0, 0.0, 12.0] -> 归一化:[0.0, 0.0, 1.0]

AC × AB  -> [0.0, 0.0, -12.0] -> 归一化:[0.0, 0.0, -1.0]

BC × AB  -> [0.0, 0.0, -12.0] -> 归一化:[0.0, 0.0, -1.0]

BC × AC  -> [0.0, 0.0, -12.0] -> 归一化:[0.0, 0.0, -1.0]

        以上向量叉乘也满足右手定则,与平面法向量一致。AB × AC、AB × BC和AC × BC表示顶点顺序为A->B->C->A,是逆时针方向,法向量朝向为z轴正方向。AC × AB、BC × AB和BC × AC表示顶点顺序为A->C->B->A,法向量朝向为z轴负方向,是顺时针方向。这与之前的介绍完全一致,即三角面是具有方向性的,并且顶点顺序影响表面朝向。

扫描二维码关注公众号,回复: 17147499 查看本文章

        上述计算结果的详细Python示例程序下载地址为“https://download.csdn.net/download/suiyingy/88439241”,或者在”乐乐感知学堂“內回复”3d处理基础“即可。

2 open3d计算法向量

        三维点云的法向量也可以直接用open3d进行计算,这里主要介绍三角面及其顶点法向量计算过程。Open3d的三角面法向量计算函数为open3d.geometry.TriangleMesh.compute_triangle_normals [Python method, in open3d.geometry.TriangleMesh],顶点法向量计算函数为open3d.geometry.TriangleMesh.compute_vertex_normals [Python method, in open3d.geometry.TriangleMesh]。

        主要函数过程如下所示, 详细Python示例程序下载地址为“https://download.csdn.net/download/suiyingy/88439241”,或者在”乐乐感知学堂“內回复”3d处理基础“即可。A->B->C->A三角面([1, 2, 3])的法向量为[0.0, 0.0, 1.0], A->C->B->A三角面([1, 3, 2])的法向量为[0.0, 0.0, -1.0]。计算结果与numpy结果一致。

mesh.compute_triangle_normals()
print('triangle normals : ', np.array(mesh.triangle_normals))
mesh.compute_vertex_normals()
print('vertex normals: ', np.array(mesh.vertex_normals))

3 顶点法向量

        三维模型的顶点法向量计算是用来描述模型表面在某一点的朝向或者法线方向。它在渲染和光照计算中非常重要。一种常用的方法是使用模型的三角面片信息来计算顶点法向量。具体步骤如下:

        (1)首先,遍历模型的所有面片(由顶点组成的三角形)。

        (2)对于每个面片,计算该面片的法向量,可使用叉乘等方法来计算面片的法向量。

        (3)将计算得到的面片法向量加到该面片的每个顶点的法向量上。

        (4)遍历完所有面片后,对每个顶点的法向量进行归一化(即将其长度缩放到1)。

        通过这种方法,可以获得每个顶点的法向量,以便在渲染过程中进行光照计算、阴影生成等操作。需要注意的是,在三维模型中,顶点法向量的计算可能受到模型的三角面片拓扑结构以及法向量平滑等因素的影响。有时候,为了获得更平滑的表面效果,还会使用其他的法向量计算方法,如加权平均等。

        顶点法向量的计算对于实现真实感的渲染和光照效果非常重要,它可以影响模型的外观、光照反射以及阴影效果等。在使用三维模型进行渲染、游戏开发等领域时,了解和正确计算顶点法向量是必要的。

        Open3d中可直接compute_vertex_normals()来获取顶点法向量。三角面A->B->C->A的3个顶点的法向量与该平面一致,均为[0.0, 0.0, 1.0]。这里平面数量只有一个。经验证,open3d中顶点法向量的计算方式为加权求和后归一化得到。加权权重是所有与顶点相关的三角面片的表面积,即表面积越大,则权重越大。下面是一个三棱柱的顶点法向量结果, 详细Python示例程序下载地址为“https://download.csdn.net/download/suiyingy/88439241”,或者在”乐乐感知学堂“內回复”3d处理基础“即可。

[[-0.72121845 -0.54091383  0.43273107]
 [ 0.72121845 -0.54091383  0.43273107]
 [ 0.          0.92847669  0.37139068]
 [-0.77790984 -0.58343238  0.23337295]
 [ 0.90144064  0.33804024  0.27043219]
 [ 0.          0.78086881  0.62469505]]

4 法向量可视化

4.1 open3d可视化

        点云法向量可视化可直接通过open3d的可视化函数来实现,但是mesh模型的法向量需要增加额外的处理。从上述结算结果可以看大,表面法向量和顶点法向量的起点都是坐标原点,因此将起点更改为表面中心或顶点可以达到更好的可视化效果。Open3d相应可视化程序的关键部分如下所示。 详细Python示例程序下载地址为“https://download.csdn.net/download/suiyingy/88439241”,或者在”乐乐感知学堂“內回复”3d处理基础“即可。

# 创建法向量可视化的 LineSet 对象
line_set = o3d.geometry.LineSet()
line_set.points = o3d.utility.Vector3dVector(np.concatenate([arrow_start_points, arrow_end_points], axis=0))
line_set.lines = o3d.utility.Vector2iVector(np.stack([np.arange(len(arrow_start_points)), np.arange(len(arrow_start_points)) + len(arrow_start_points)], axis=1))
line_colors = np.array([[0.0, 0.0, 1.0]] * len(arrow_start_points))
line_set.colors = o3d.utility.Vector3dVector(line_colors)

        可视化结果如下图所示,蓝色部分为法向量。示例程序提供两种法向量显示方式,分别是有箭头和无箭头两种。

图1 Open3d法向量可视化

4.2 MeshLab软件

        MeshLab可以直接计算并显示顶点法向量和三角面片法向量。计算方法为Render -> Show Normal。结果如下所示,蓝色线段为法向量。

图2 MeshLab法向量计算与可视化

5 法向量应用

        三维模型的法向量在计算机图形学和计算机视觉中具有重要的作用和意义,以下是其应用和重要性的几个方面:

        (1)表面渲染:法向量可以用于确定模型表面的朝向和法线方向,从而在渲染过程中产生真实感的光照效果。通过法向量的方向和光照方向的关系,可以计算出每个像素的光照强度,实现阴影、反射、折射等效果。

        (2)表面平滑:顶点法向量对于模型的表面平滑效果非常重要。通过计算周围三角面片的法向量,可以获得更平滑的表面效果。这在渲染曲面模型时尤为重要,可以消除模型的锯齿边和角度过渡不自然的问题,提高视觉质量。

        (3)光照计算:光照模型通常使用法向量来计算光的反射、折射和散射等效果。根据入射光线、表面法向量和材质属性,可以计算出每个像素的光照强度和颜色。

        (4)遮挡检测:法向量可以帮助确定模型表面上的遮挡物,例如阴影的生成和检测。通过比较法向量的方向和光照方向,可以确定哪些区域受到其他物体的遮挡而无法接收到光源的直接照射。

        (5)物体识别和分割:在计算机视觉中,可以使用法向量来识别和分割不同的物体。每个物体的法向量具有独特的模式和特征,可以通过计算法向量的相似度来进行物体的识别和分割。

        (6)几何形状分析:法向量可以用于对三维模型的几何形状进行分析。例如,通过计算顶点法向量的变化率,可以确定模型的曲率和表面的凹凸性质。这对于形状匹配、形状比较和形状分类等任务非常有用。

        总之,三维模型的法向量在计算机图形学和计算机视觉领域有着广泛的应用。它们对于实现真实感的渲染效果、物体识别和分割、形状分析等方面起着重要的作用,是处理三维数据和图形的关键信息之一。

        综上所述,法向量是垂直于平面的向量,用于描述三维模型表面的朝向。通过计算三角面的法向量可以得到顶点法向量,它在计算机图形学和计算机视觉中具有广泛的应用,包括表面渲染、光照计算、物体识别和分割等任务。了解和计算法向量对于实现真实感的渲染效果和几何形状分析非常重要。

【版权声明】
本文为博主原创文章,未经博主允许严禁转载,我们会定期进行侵权检索。

更多算法总结请关注我的博客:https://blog.csdn.net/suiyingy,或”乐乐感知学堂“公众号。
本文章来自于专栏《Python三维模型处理基础》的系列文章,专栏地址为:https://blog.csdn.net/suiyingy/category_12462636.html。

猜你喜欢

转载自blog.csdn.net/suiyingy/article/details/133816356
今日推荐