当前位置: 首页 > 后端技术 > Python

Open3D人脸深度图转点云,点云表面重构

时间:2023-03-25 22:04:02 Python

01简介Open3D:一个现代的3D数据处理库Open3D是一个支持3D数据处理软件快速开发的开源库。Open3D前端公开了一组精心挑选的C++和Python数据结构和算法。后端经过高度优化并设置为并行化。我们欢迎来自开源社区的贡献。Open3D的核心功能包括:-3D数据结构-3D数据处理算法-现场重建-表面对齐-3D可视化-物理渲染(PBR)-3D机器学习支持PyTorch和TensorFlow-GPU加速核心3D操作-C++和Python版本可用官方:02从python开始,深度图到点云2.1安装安装系统ubuntu,macwin10都支持condacreate-nopen3dpython=3.7activateopen3d-ihttps://pypi.tuna.tsinghua.edu.cn/simple#Installpipinstallopen3d#Verifypython-c"importopen3daso3d;print(o3d.__version__)"测试可视化球体:test3d.pyimportopen3daso3dmesh=o3d.geometry.TriangleMesh.create_sphere()mesh.compute_vertex_normals()o3d。visualization.draw(mesh,raw_mode=True)2.2可视化人脸点云OPEN3D支持各种格式的3d文件,pcd,ply等importpandasaspdimportnumpyasnpimportopen3daso3d#ply_point_cloud=o3d.data.PLYPointCloud()pcd=o3d.io.read_point_cloud("./face.ply")#pcd=o3d.io.read_point_cloud("./my_points.txt",format='xyz')#pcd=o3d.io.read_point_cloud("./face.pcd")print(pcd)print(np.asarray(pcd.points))o3d.visualization.draw_geometries([pcd],zoom=0.3412,front=[0.4257,-0.2125,-0.8795],lookat=[2.6172,2.0475,1.532],up=[-0.0694,-0.9768,0.2024])2.3格式一般只有深度图,需要转换。python这里的方法是先把深度图转成3D坐标,存成numpy格式,然后直接用open3d转成视觉点云原始的csv可视化的深度图如下:data_path=./face.csv"w=320h=240data=pd.read_csv(data_path,header=None)points=np.zeros((w*h,3),dtype=np.float32)n=0foriinrange(h):forjinrange(w):deep=data.iloc[i,j]points[n][0]=jpoints[n][1]=i点[n][2]=深#points.append([j,i,deep])n=n+1pcd=o3d.geometry.PointCloud()pcd.points=o3d.utility.Vector3dVector(points)#o3d.io.write_point_cloud("../../test_data/sync.ply",pcd)print("==========")print(pcd)print(np.asarray(pcd.points)print(“===========”)o3d.visualization.draw_geometries([PCD],Zoom=0.3412,front=[0.4257,-0.2125,-0.8795],lookat=[2.6172,2.0475,2.0475,2.0475,2.0475,1.532],up=[-0.0694,-0.9768,0.2024]))点云:这里:这里这里是简单,没有是,没有没有根据内将熊猫导入为pdimportnumpyasnpimportopen3daso3d#ply_point_cloud=o3d.data.PLYPointCloud()#pcd=o3d.io.read_point_cloud("./face.ply")#pcd=o3d.io.read_point_cloud("./my_points.txt",format='xyz')#pcd=o3d.io.read_point_cloud("./face.pcd")data_path="./face.csv"camera_factor=1;camera_cx=180.8664;camera_cy=179.088;camera_fx=216.75;camera_fy=214.62;w=320h=240data=pd.read_csv(data_path,header=None)points=np.zeros((w*h,3),dtype=np.float32)n=0foriinrange(h):forjin范围(w):deep=data.iloc[i,j]points[n][2]=deep/camera_factorpoints[n][0]=(j-camera_cx)*points[n][2]/camera_fx点[n][1]=(i-camera_cy)*points[n][2]/camera_fy#points.append([j,i,deep])n=n+1pcd=o3d.geometry.PointCloud()pcd。points=o3d.utility.Vector3dVector(points)#o3d.io.write_point_cloud("../../test_data/sync.ply",pcd)print("==========")print(pcd)打印(np.asarray(pcd.points))print("==========")#knot_data=o3d.data.KnotMesh()#mesh=o3d.io.read_triangle_mesh("./face.ply")#print(网格)#o3d.io.write_triangle_mesh(“copy_of_knot.ply”,mesh)o3d.visualization.draw_geometries([[pcd],zoom=0.3412,front=[0.4257,-0.4257,-0.2125,-0.2125,-0.87995],-0.8795],lookat=[2.6172,2.0475,1.532],up=[-0.0694,-0.9768,0.2024])Side:2.4点云分割和聚类保留前景信息,使用聚类和分割函数,或者进行numpy预处理importpandasaspynumpdimportasnpimportopen3daso3dimportmatplotlib.pyplotasplt#ply_point_cloud=o3d.data.PLYPointCloud()#pcd=o3d.io.read_point_cloud("./face.ply")#pcd=o3d.io.read_point_cloud("./my_points.txt",格式='xyz')#pcd=o3d.io.read_point_cloud("./face.pcd")data_path="./face.csv"camera_factor=10;camera_cx=180.8664;camera_cy=179.088;camera_fx=二十一6.75;camera_fy=214.62;w=320h=240data=pd.read_csv(data_path,header=None)points=np.zeros((w*h,3),dtype=np.float32)n=0foriinrange(h):forjinrange(w):deep=data.iloc[i,j]points[n][2]=deep/camera_factorpoints[n][0]=(j-camera_cx)*points[n][2]/camera_fxpoints[n][1]=(i-camera_cy)*points[n][2]/camera_fy#points.append([j,i,deep])n=n+1points=points[points[:,2]<100]pcd=o3d.geometry.PointCloud()pcd.points=o3d.utility.Vector3dVector(points)#o3d.io.write_point_cloud("../../test_data/sync.ply",pcd)#pcd.paint_uniform_color([1,0.706,0])print("==========")print(pcd)print(np.asarray(pcd.points))print("==========")##聚类啦#witho3d.utility.VerbosityContextManager(#o3d.utility.VerbosityLevel.Debug)ascm:#labels=np.array(#pcd.cluster_dbscan(eps=0.02,min_points=10,print_progress=True))#max_label=labels.max()#print(f"点云有{max_label+1}簇”)#colors=plt.get_cmap("tab20")(labels/(max_labelifmax_label>0else1))#colors[labels<0]=0#pcd.colors=o3d.utility.utility.Vector3DVector(颜色[:3])brane_model,inliers=pcd.segment_plane(decance_threshold=0.01,ransac_n=3,num_iterations=1000)[a,b,b,c,c,c,c,d]方程:{a:.2f}x+{b:.2f}y+{c:.2f}z+{d:.2f}=0")inlier_cloud=pcd.select_by_index(inliers)inlier_cloud.paint_uniform_color([1.0,0,0])outlier_cloud=pcd.select_by_index(inliers,invert=True)#画个框玩aabb=pcd.get_axis_aligned_bounding_box()aabb.color=(1,0,0)obb=pcd.get_oriented_bounding_box()obb.color=(0,1,0)#knot_data=o3d.data.KnotMesh()#mesh=o3d.io.read_triangle_mesh("./face.ply")#print(mesh)#o3d.io.write_triangle_mesh("copy_of_knot.ply",mesh)o3d.visualization.draw_geometries([[outlier_cloud,aabb],zoom=0.3412,front=[0.4257,-0.2125,-0.8795],lookat=[2.6172,2.0475,1.532]SurfaceReconstruction3.1PoissonReconstruction在很多情况下,我们想要生成一个密集的三维几何体,例如,一个三角形网格。然而,从多视图立体视觉方法或深度传感器,我们只能获得非结构化的点云。为了从这个非结构化输入中获得三角形网格,我们需要进行表面重建。文献中有两种方法Open3D目前实现如下:alphashape(Edelsbrunner1983),sphererotation(Bernardini1999),Poissonsurfacereconstruction[Kazhdan2006]Poissonreconstruction需要法线估计,直接调用:pcd.normals=o3d.utility.Vector3dVector(np.zeros((1,3)))#使现有的normalspcd.estimate_normals()无效泊松曲面重建还将在点密度低的区域创建三角形,甚至可以外推到某些区域(请参见鹰输出上方图像的底部).create_from_point_cloud_poisson函数有第二个密度返回值,代表每个顶点的密度。低密度值意味着仅支持输入点云中的少量点。3.2Alphashapesalpha形状的重构[Edelsbrunner1983]是凸包的推广。tetra_mesh,pt_map=o3d.geometry.TetraMesh.create_from_point_cloud(pcd)foralphainnp.logspace(np.log10(2.5),np.log10(0.1),num=2):print(f"alpha={alpha:.3f}")mesh=o3d.geometry.TriangleMesh.create_from_point_cloud_alpha_shape(pcd,alpha,tetra_mesh,pt_map)mesh.compute_vertex_normals()o3d.visualization.draw_geometries([mesh],mesh_show_back_face=True)3.3球旋转[Bernardini1999]是一种alpha形状相关的表面重建方法。半径=[0.005,0.01,0.02,0.04]rec_mesh=o3d.geometry.TriangleMesh.create_from_point_cloud_ball_pivoting(pcd,o3d.utility.DoubleVector(radii))o3d.visualization.draw_geometries([pcsh,]rec_mesh