当前位置:   article > 正文

python读取点云文件(.stl文件、.obj文件)(以及转换为obj方法)_python stl

python stl

.1 文本方式读取 

代码如下

  1. stl_path='/home/pxing/codes/point_improve/data/003_cracker_box/0.stl'
  2. points=[]
  3. f = open(stl_path)
  4. lines = f.readlines()
  5. prefix='vertex'
  6. num=3
  7. for line in lines:
  8. #print (line)
  9. if line.startswith(prefix):
  10. values = line.strip().split()
  11. #print(values[1:4])
  12. if num%3==0:
  13. points.append(values[1:4])
  14. num=0
  15. num+=1
  16. #print(type(line))
  17. print(points)
  18. f.close()

该代码可以直接将stl文件中对点直接都输出

改进版本

  1. import numpy as np
  2. stl_path='/home/pxing/codes/point_improve/data/003_cracker_box/0.stl'
  3. points=[]
  4. f = open(stl_path)
  5. lines = f.readlines()
  6. prefix='vertex'
  7. num=3
  8. for line in lines:
  9. #print (line)
  10. if line.startswith(prefix):
  11. values = line.strip().split()
  12. #print(values[1:4])
  13. if num%3==0:
  14. points.append(values[1:4])
  15. num=0
  16. num+=1
  17. #print(type(line))
  18. points=np.array(points)
  19. f.close()
  20. print(points.shape)
  21. np.save("/home/pxing/codes/point_improve/feature_get/point_get/test.npy", points)

把输出的点转换为npy并且保存

1.1 stl解析

.stl文件格式如下图所示:

那么读取该文件就需要知道stl的构成

stl是一种表示三角网格的文件格式

STL只能用来表示封闭的面或者体,stl文件有两种:一种是ASCII明码格式,另一种是二进制格式

ASCII明码格式:

STL文件的首行给出了文件路径及文件名

STL三维模型就是由一系列这样的三角面片构成

三角面片的信息单元 facet 是一个带矢量方向的三角面片

每一个facet由7 行数据组成:

facet normal 是三角面片指向实体外部的法矢量坐标

outer loop 代表随后的3行数据分别是三角面片的3个顶点坐标

3顶点沿指向实体外部的法矢量方向逆时针排列

solid [filename] //文件名,可以是任何字符

facet normal [i j k] //面的法线,i、j、k为三个分量,各分量之间用空格隔开,不能用逗号隔开

outor loop

vertex [x y z] //三角面片的第一个点,x、y、z三个坐标之间要用空格隔开

vertex [x y z] //三角面片的第二个点

vertex [x y z] //三角面片的第三个点

endloop

endfacet //完成一个三角面片的定义

、、、、 //其他facet

endsolid [filename] //完成一个stl文件的定义

示例:

在电脑上新建一个txt文件,然后编辑。编辑完了之后保存,并将文件后缀名改为stl,即可完成一个创建了一个stl文件。如下图,利用文本编辑器将一个四面体的几何数据保存到文件中

效果如下图所示:

1.2 stl创建 

创建一个三角形面片

  1. solid mystl
  2. facet normal 0 -1 0
  3. outor loop
  4. vertex -100 0 0
  5. vertex 100 0 0
  6. vertex 0 0 -100
  7. endloop
  8. endfacet
  9. end solid mystl

1.3 stl分割

完成了stl分割

  1. stl_path='/home/harry/projects/spoon_to_scoop/object_process/spilt/decomp.stl'
  2. with open(stl_path, "r") as f:
  3. lines = f.readlines()
  4. target_end = "endsolid"
  5. i=0
  6. for line in lines:
  7. with open('/home/harry/projects/spoon_to_scoop/object_process/spilt/'+'bow_'+str(i)+".stl", "a") as new_f:
  8. new_f.write(line)
  9. if target_end in line:
  10. i+=1

1.4 obj读取

  1. def read_obj_vertices(file_path):
  2. vertices = []
  3. with open(file_path, 'r') as file:
  4. for line in file:
  5. if line.startswith('v '):
  6. vertex = line.strip().split(' ')[1:]
  7. vertex = [float(coord) for coord in vertex]
  8. vertices.append(vertex)
  9. return vertices
  10. if __name__=='__main__':
  11. obj_file_path = './object/nontextured.obj'
  12. vertices = read_obj_vertices(obj_file_path)
  13. list=[]
  14. for vertex in vertices:
  15. list.append(vertex)
  16. print(list[0])

.2 把点转换为.stl

  1. import numpy as np
  2. import sys
  3. sys.path.append('/home/pxing/codes/grasp_ROI_get/')
  4. from gripper_area import area_get
  5. arr=np.array(area_get.main())
  6. #print(arr[0,0:3])
  7. with open('stl_process/data/test1.stl','a') as file0:
  8. print('solid mystl ',file=file0)
  9. print('facet normal' ,0,0,0,file=file0)
  10. print('outor loop',file=file0)
  11. print('vertex',arr[0,0],arr[0,1],arr[0,2 ],file=file0)
  12. print('vertex',arr[1,0],arr[1,1],arr[1,2 ],file=file0)
  13. print('vertex',arr[2,0],arr[2,1],arr[2,2 ],file=file0)
  14. print('endloop\nendfacet',file=file0)
  15. print('end solid mystl',file=file0)

.3 stl组装

  1. import os
  2. import numpy as np
  3. def stl_get(stl_path):
  4. points=[]
  5. f = open(stl_path)
  6. lines = f.readlines()
  7. prefix='vertex'
  8. num=3
  9. for line in lines:
  10. #print (line)
  11. if line.startswith(prefix):
  12. values = line.strip().split()
  13. #print(values[1:4])
  14. if num%3==0:
  15. points.append([values[1],values[2],values[3]])
  16. num=0
  17. num+=1
  18. #print(type(line))
  19. points=np.array(points,dtype='float64')
  20. #points=points*1000#3d打印用
  21. f.close()
  22. #print(points.shape)
  23. #np.save("/home/pxing/codes/point_improve/feature_get/point_get/index_mm_level.npy", t)
  24. return points
  25. def stl_generate(arr,stl_path):
  26. with open(stl_path,'a') as file0:
  27. print('solid mystl ',file=file0)
  28. for i in range((arr.shape[0]-3)):
  29. print('facet normal' ,0,0,0,file=file0)
  30. print('outor loop',file=file0)
  31. print('vertex',arr[i,0],arr[i,1],arr[i,2 ],file=file0)
  32. print('vertex',arr[i+1,0],arr[i+1,1],arr[i+1,2 ],file=file0)
  33. print('vertex',arr[i+2,0],arr[i+2,1],arr[i+2,2 ],file=file0)
  34. print('endloop\nendfacet',file=file0)
  35. print('end solid mystl',file=file0)
  36. print('generate success')
  37. def mkdir(path):
  38. folder = os.path.exists(path)
  39. if not folder:#判断是否存在文件夹如果不存在则创建为文件夹
  40. os.makedirs(path) #makedirs 创建文件时如果路径不存在会创建这个路径
  41. file_path='/home/pxing/codes/point_improve/data/process_projection/'#stl储存的位置
  42. goods_list=os.listdir(file_path)
  43. for i in goods_list:
  44. #对所有0子文件夹进行组装
  45. index=0
  46. file_stl_path=file_path+i+'/'+str(index)
  47. stl_list=os.listdir(file_stl_path)
  48. if stl_list:
  49. arr_assembly=np.array([[0,0,0]])#创建一个空数组来组成后面的元素
  50. for j in stl_list:
  51. print(stl_list)
  52. stl_path=file_stl_path+'/'+j
  53. arr=stl_get(stl_path)
  54. arr_assembly=np.concatenate((arr_assembly,arr),axis=0)
  55. arr_assembly=np.delete(arr_assembly,[0,0],axis=0)
  56. file_save_path='/home/pxing/codes/point_improve/data/auto_assembly_data/'+i+'/'+str(index)
  57. mkdir(file_save_path)
  58. stl_save_path=file_save_path+'/'+str(index)+'.stl'
  59. stl_generate(arr_assembly,stl_save_path)
  60. else:
  61. pass

.4 stl转obj(带f法向量的obj)

  1. import numpy as np
  2. def stl_get(stl_path):
  3. points=[]
  4. f = open(stl_path)
  5. lines = f.readlines()
  6. prefix='vertex'
  7. num=3
  8. for line in lines:
  9. #print (line)
  10. if line.startswith(prefix):
  11. values = line.strip().split()
  12. #print(values[1:4])
  13. if num%3==0:
  14. points.append([values[1],values[2],values[3]])
  15. num=0
  16. num+=1
  17. #print(type(line))
  18. points=np.array(points,dtype='float64')
  19. #points=points*1000#3d打印用
  20. f.close()
  21. #print(points.shape)
  22. #np.save("/home/pxing/codes/point_improve/feature_get/point_get/index_mm_level.npy", t)
  23. return points
  24. # 点云数据
  25. stl_path='/home/pxing/codes/point_improve/data/rotation_data/assembly_projection_isaac.stl'
  26. points = stl_get(stl_path)
  27. # 计算点云的法向量
  28. def compute_normals(points):
  29. normals = []
  30. for i, p0 in enumerate(points):
  31. v1 = points[(i+1) % len(points)] - p0
  32. v2 = points[(i+2) % len(points)] - p0
  33. normals.append(np.cross(v1, v2))
  34. return normals
  35. normals = compute_normals(points)
  36. # 将点云和法向量保存为OBJ格式文件
  37. with open('/home/pxing/codes/point_improve/data/obj/point_f_assembly.obj', 'w') as f:
  38. for i, p in enumerate(points):
  39. f.write(f'v {p[0]} {p[1]} {p[2]}\n')
  40. n = normals[i]
  41. f.write(f'vn {n[0]} {n[1]} {n[2]}\n')

生成带面的obj

  1. import numpy as np
  2. def stl_get(stl_path):
  3. points=[]
  4. f = open(stl_path)
  5. lines = f.readlines()
  6. prefix='vertex'
  7. num=3
  8. for line in lines:
  9. #print (line)
  10. if line.startswith(prefix):
  11. values = line.strip().split()
  12. #print(values[1:4])
  13. if num%3==0:
  14. points.append([values[1],values[2],values[3]])
  15. num=0
  16. num+=1
  17. #print(type(line))
  18. points=np.array(points,dtype='float64')
  19. #points=points*1000#3d打印用
  20. f.close()
  21. #print(points.shape)
  22. #np.save("/home/pxing/codes/point_improve/feature_get/point_get/index_mm_level.npy", t)
  23. return points
  24. # 点云数据
  25. stl_path='/home/pxing/codes/point_improve/data/rotation_data/assembly_projection_isaac.stl'
  26. points = stl_get(stl_path)
  27. # 计算点云的法向量
  28. def compute_normals(points):
  29. normals = []
  30. for i, p0 in enumerate(points):
  31. v1 = points[(i+1) % len(points)] - p0
  32. v2 = points[(i+2) % len(points)] - p0
  33. normals.append(np.cross(v1, v2))
  34. return normals
  35. normals = compute_normals(points)
  36. # 将点云和法向量保存为OBJ格式文件
  37. with open('/home/pxing/codes/point_improve/data/obj/point_f_assembly.obj', 'w') as f:
  38. for i, p in enumerate(points):
  39. f.write(f'v {p[0]} {p[1]} {p[2]}\n')
  40. n = normals[i]
  41. f.write(f'vn {n[0]} {n[1]} {n[2]}\n')
  42. # 将点云转换为面信息
  43. for i in range(0, len(points), 3):
  44. f.write(f'f {i+1}//{i+1} {i+2}//{i+2} {i+3}//{i+3}\n')

.5 ply生成

  1. import numpy as np
  2. def stl_get(stl_path):
  3. points=[]
  4. f = open(stl_path)
  5. lines = f.readlines()
  6. prefix='vertex'
  7. num=3
  8. for line in lines:
  9. #print (line)
  10. if line.startswith(prefix):
  11. values = line.strip().split()
  12. #print(values[1:4])
  13. if num%3==0:
  14. points.append([values[1],values[2],values[3]])
  15. num=0
  16. num+=1
  17. #print(type(line))
  18. points=np.array(points,dtype='float64')
  19. #points=points*1000#3d打印用
  20. f.close()
  21. #print(points.shape)
  22. #np.save("/home/pxing/codes/point_improve/feature_get/point_get/index_mm_level.npy", t)
  23. return points
  24. # 点云数据
  25. stl_path='/home/pxing/codes/point_improve/data/rotation_data/assembly_projection_isaac.stl'
  26. points = stl_get(stl_path)
  27. # 将点云保存为含有顶点和面信息的PLY格式文件
  28. with open('/home/pxing/codes/point_improve/data/obj/point_cloud.ply', 'w') as f:
  29. # 写入PLY文件头
  30. f.write('ply\n')
  31. f.write('format ascii 1.0\n')
  32. f.write(f'element vertex {len(points)}\n')
  33. f.write('property float x\n')
  34. f.write('property float y\n')
  35. f.write('property float z\n')
  36. f.write(f'element face {len(points)}\n')
  37. f.write('property list uchar int vertex_indices\n')
  38. f.write('end_header\n')
  39. # 写入点云数据
  40. for p in points:
  41. f.write(f'{p[0]} {p[1]} {p[2]}\n')
  42. # 写入面数据
  43. for i in range(len(points)):
  44. f.write(f'3 {i} {i} {i}\n')

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/黑客灵魂/article/detail/952778
推荐阅读
相关标签
  

闽ICP备14008679号