3D点云的纹理贴图

工业组-余秋蒲

2024-12-16 15:55
161

摘要:

随着3D计算机图形学和计算机视觉技术的不断发展,点云数据的处理和可视化成为了一个重要研究领域。点云数据通常来源于激光扫描仪、深度相机或其他3D测量设备,它们提供了三维空间中的点集信息。在实际应用中,点云常常需要进行处理和重建,形成可视化的3D模型。本文通过集成PCL、OpenMesh和OpenGL等开源库,展示了如何从点云数据中重建一个3D网格,并对其进行渲染。文章涵盖了点云去噪、法向量计算、泊松重建等步骤,并最终使用OpenGL进行3D网格的可视化。

引言:

在工业检测中我们经常会采集3D点云信息和2D的像素信息,如果我们想将二者结合,得到一个彩色的3D模型,就需要采取纹理贴图的方式实现

所用环境

window 11下的VS2022集成PCL、OpenMesh和OpenGL等开源库。


实现路径:

(1)初始化阶段:

引入库 → 定义类型 → 加载纹理图像 → 加载点云数据

(2)点云处理阶段:

点云去噪 → 计算法向量 → 泊松重建

(3)网格处理阶段:

加载重建网格 → 计算UV坐标 → 准备OpenGL数据

(4)渲染准备阶段:

初始化GLFW和GLEW → 编译链接着色器 → 配置OpenGL缓冲对象 → 加载纹理到GPU → 设置光照参数

(5)渲染循环:

清除屏幕 → 应用变换矩阵 → 绑定纹理 → 绘制网格 → 处理用户输入 → 更新显示

(6)结束阶段:

清理OpenGL资源 → 终止GLFW → 程序退出


关键代码原理讲解:

(1)点云滤波

该代码使用体素滤波器进行点云滤波,体素滤波器可以达到向下采样同时不破坏点云本身几何结构的功能,但是会移动点的位置。 此外体素滤波器可以去除一定程度的噪音点及离群点。主要功能是用来进行降采样。它的原理是根据输入的点云,首先计算一个能够刚好包裹住该点云的立方体,然后根据设定的分辨率,将该大立方体分割成不同的小立方体。对于每一个小立方体内的点,计算他们的质心,并用该质心的坐标来近似该立方体内的若干点。


(2)法向量估计:

基于局部表面拟合的方法进行法向量估计:点云的采样表面处处光滑的情况下,任何点的局部邻域都可以用平面进行很好的拟合;为此,对于点云中的每个扫描点p,搜索到与其最近邻的K个相邻点,然后计算这些点最小二乘意义上的局部平面P,此平面可以表示为:

 式中,i为平面P 的法向量,d为P到坐标原点的距离。可以认为由队个最近点拟合出的平面的法向量即当前扫描点的法向量。平面P的法向量可以由主成分分析(PCA)得到,由运算知P经过其K邻域点的质心P,且法向量满足五=1,先对式(2)中的协方差矩阵M进行特征值分解,求得M 的各特征值,的最小特征值所对应的特征向量即P的法向量。


(3)泊松表面重建:

在进行泊松表面重建的过程中,首先需要准备输入点云数据集,并对其进行预处理,包括滤波以去除噪声和离群点,以及下采样以降低点云密度,从而减少计算量。接下来,通过主成分分析(PCA)或其他局部几何方法对每个点估计法向量,这些法向量与点所在表面垂直,构成法向量场。然后,构造一个三维标量场函数Φ,使得在点云的每个点处,Φ的梯度近似于对应的法向量,满足泊松方程ΔΦ=∇⋅N,其中Δ为拉普拉斯算子,∇⋅N为法向量场的散度。通过将泊松方程离散化,并采用数值方法如多重网格方法进行求解,得到标量场函数Φ。随后,利用Marching Cubes算法从标量场Φ中提取等值面,生成多边形网格。最后,对生成的表面进行平滑处理、孔洞填补和细节增强等后处理步骤,以去除噪声并改善表面质量。泊松表面重建方法具有处理噪声数据能力强、生成表面平滑且闭合的优势,但其计算复杂度较高,并且对法向量估计的准确性依赖性较强,这在实际应用中需要权衡考虑。


(4)uv映射:

UV
映射是将三维表面转换为平面位图图像的二维坐标系

该代码通过简单的平面投影实现uv映射,具体步骤如下:


1.首先,代码遍历所有顶点,计算模型在X轴和Y轴的最小值和最大值(min_x, max_x, min_y, max_y)。这些边界值用于后续的归一化处理,确保所有UV坐标都在[0,1]的范围内。


2. 再次遍历所有顶点,将每个顶点的X和Y坐标映射到UV坐标。


3. U坐标:通过公式  将顶点的X坐标线性归一化到[0,1]范围。

4. V坐标:通过公式  将顶点的Y坐标线性归一化到[0,1]范围。


5. 使用mesh.set_texcoord2D(vh, OpenMesh::Vec2f(u, v));将计算得到的UV坐标设置到对应的顶点上。



(5)Phong光照模型:

Phong光照模型的主要结构由3个分量组成:环境(Ambient)、漫反射(Diffuse)和镜面(Specular)光照。下面这张图展示了这些光照分量看起来的样子:

在该代码片段着色器中,输入变量包括FragPos,表示片段在世界空间中的位置;Normal,表示片段的法向量;以及TexCoord,表示片段的纹理坐标。统一变量包括texture1,用于采样纹理图像的纹理采样器;lightPos,表示光源在世界空间中的位置;viewPos,表示观察者(相机)在世界空间中的位置;lightColor,表示光源的颜色;以及objectColor,表示物体的基础颜色。在光照计算过程中,首先设定环境光强度为0.3,并与光源颜色相乘,形成基础的环境光贡献。接着,将法向量和光线方向归一化,并计算它们的点积以得到漫反射强度diff,然后将其乘以光源颜色,得到漫反射光的贡献。在镜面反射部分,计算视线方向和反射光方向,并将它们的点积提升到32次方,以获得镜面反射强度spec,随后将其乘以镜面反射系数和光源颜色,得到镜面反射光的贡献。最终,将环境光、漫反射光和镜面反射光相加,再乘以物体颜色和纹理颜色,得到最终的片段颜色,并将其输出为FragColor。这一过程通过结合环境光、漫反射光和镜面反射光,实现了逼真的光照效果,使得渲染的物体在纹理映射下呈现出真实的视觉效果。


源码示例

准备一张jpg图片和一个ply点云图                                                                                                                                                                                                              运行代码:

                                              ABUIABAEGAAghbr-ugYokp_CrgEwqwY4-AQ.png


                                                                                                                                                                                         

实验室应用:

        

利用3D和RGB相机的结合产出带有颜色信息的点云图


参考来源:

[1]点云处理之点云滤波去噪_点云滤波和去噪的区别-CSDN博客

[2]PCL 计算点云法向量并显示_pcl计算法向量-CSDN博客

[3]PCL从理解到应用【10】 三维点云 | 表面重建 | 泊松Poisson_泊松表面重建-CSDN博客

[4]什么是 UV 映射和展开?完整指南 - 知乎 (zhihu.com)

[5]现代OpenGL教程(八):基础光照——Phong光照模型(ImGui+OpenGL3.3)_球体phong光照模型源文件-CSDN博客