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

这篇具有很好参考价值的文章主要介绍了python读取点云文件(.stl文件、.obj文件)(以及转换为obj方法)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

.1 文本方式读取 

代码如下

stl_path='/home/pxing/codes/point_improve/data/003_cracker_box/0.stl'



points=[]
f = open(stl_path)
lines = f.readlines()
prefix='vertex'
num=3
for line in lines:
    #print (line)

    if line.startswith(prefix):

        values = line.strip().split()
        #print(values[1:4])
        if num%3==0:
          points.append(values[1:4])
          num=0
        num+=1
    #print(type(line))
print(points)
f.close()

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

改进版本

import numpy as np

stl_path='/home/pxing/codes/point_improve/data/003_cracker_box/0.stl'
points=[]
f = open(stl_path)
lines = f.readlines()
prefix='vertex'
num=3
for line in lines:
    #print (line)

    if line.startswith(prefix):

        values = line.strip().split()
        #print(values[1:4])
        if num%3==0:
          points.append(values[1:4])
          num=0
        num+=1
    #print(type(line))
points=np.array(points)
f.close()
print(points.shape)
np.save("/home/pxing/codes/point_improve/feature_get/point_get/test.npy", points)

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

1.1 stl解析

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

stl和obj,# PointCloud,计算机视觉

那么读取该文件就需要知道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文件。如下图,利用文本编辑器将一个四面体的几何数据保存到文件中

效果如下图所示:

stl和obj,# PointCloud,计算机视觉

1.2 stl创建 

创建一个三角形面片

solid   mystl    
facet   normal  0 -1 0
outor   loop
vertex  -100 0 0 
vertex  100 0 0
vertex  0 0 -100 
endloop
endfacet 
end solid mystl

stl和obj,# PointCloud,计算机视觉

1.3 stl分割

完成了stl分割

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

stl和obj,# PointCloud,计算机视觉

1.4 obj读取

def read_obj_vertices(file_path):
    vertices = []

    with open(file_path, 'r') as file:
        for line in file:
            if line.startswith('v '):
                vertex = line.strip().split(' ')[1:]
                vertex = [float(coord) for coord in vertex]
                vertices.append(vertex)

    return vertices


if __name__=='__main__':
    obj_file_path = './object/nontextured.obj'
    vertices = read_obj_vertices(obj_file_path)

    list=[]

    for vertex in vertices:
        list.append(vertex)
    print(list[0])

.2 把点转换为.stl

import numpy as np
import sys
sys.path.append('/home/pxing/codes/grasp_ROI_get/')
from gripper_area import area_get

arr=np.array(area_get.main())
#print(arr[0,0:3])
with open('stl_process/data/test1.stl','a') as file0:
    print('solid   mystl ',file=file0)
    print('facet   normal' ,0,0,0,file=file0)
    print('outor   loop',file=file0)
    
    print('vertex',arr[0,0],arr[0,1],arr[0,2 ],file=file0)
    print('vertex',arr[1,0],arr[1,1],arr[1,2 ],file=file0)
    print('vertex',arr[2,0],arr[2,1],arr[2,2 ],file=file0)
    
    print('endloop\nendfacet',file=file0)
    print('end solid mystl',file=file0)

.3 stl组装

import os
import numpy as np

def stl_get(stl_path):
    points=[]
    f = open(stl_path)
    lines = f.readlines()
    prefix='vertex'
    num=3
    for line in lines:
        #print (line)

        if line.startswith(prefix):
            values = line.strip().split()
            #print(values[1:4])
            if num%3==0:
                points.append([values[1],values[2],values[3]])
                num=0
            num+=1
        #print(type(line))
    points=np.array(points,dtype='float64')

    #points=points*1000#3d打印用

    
    f.close()
    #print(points.shape)
    #np.save("/home/pxing/codes/point_improve/feature_get/point_get/index_mm_level.npy", t)
    return points

def stl_generate(arr,stl_path):
    with open(stl_path,'a') as file0:
        print('solid   mystl ',file=file0)
        for i in range((arr.shape[0]-3)):
            print('facet   normal' ,0,0,0,file=file0)
            print('outor   loop',file=file0)
            print('vertex',arr[i,0],arr[i,1],arr[i,2 ],file=file0)
            print('vertex',arr[i+1,0],arr[i+1,1],arr[i+1,2 ],file=file0)
            print('vertex',arr[i+2,0],arr[i+2,1],arr[i+2,2 ],file=file0)
            print('endloop\nendfacet',file=file0)
        
        print('end solid mystl',file=file0)
    print('generate success')

def mkdir(path):
 
	folder = os.path.exists(path)

	if not folder:#判断是否存在文件夹如果不存在则创建为文件夹
		os.makedirs(path) #makedirs 创建文件时如果路径不存在会创建这个路径




file_path='/home/pxing/codes/point_improve/data/process_projection/'#stl储存的位置
goods_list=os.listdir(file_path)
for i in goods_list:
    #对所有0子文件夹进行组装
    index=0
    file_stl_path=file_path+i+'/'+str(index)
    stl_list=os.listdir(file_stl_path)
    
    if stl_list:
        arr_assembly=np.array([[0,0,0]])#创建一个空数组来组成后面的元素
        for j in stl_list:
            print(stl_list)
            stl_path=file_stl_path+'/'+j
            arr=stl_get(stl_path)
            arr_assembly=np.concatenate((arr_assembly,arr),axis=0)
        
        arr_assembly=np.delete(arr_assembly,[0,0],axis=0)
        file_save_path='/home/pxing/codes/point_improve/data/auto_assembly_data/'+i+'/'+str(index)
        mkdir(file_save_path)
        stl_save_path=file_save_path+'/'+str(index)+'.stl'
        stl_generate(arr_assembly,stl_save_path)
            
        
    else:
        pass

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

import numpy as np



def stl_get(stl_path):
    points=[]
    f = open(stl_path)
    lines = f.readlines()
    prefix='vertex'
    num=3
    for line in lines:
        #print (line)

        if line.startswith(prefix):
            values = line.strip().split()
            #print(values[1:4])
            if num%3==0:
                points.append([values[1],values[2],values[3]])
                num=0
            num+=1
        #print(type(line))
    points=np.array(points,dtype='float64')

    #points=points*1000#3d打印用

    
    f.close()
    #print(points.shape)
    #np.save("/home/pxing/codes/point_improve/feature_get/point_get/index_mm_level.npy", t)
    return points

# 点云数据

stl_path='/home/pxing/codes/point_improve/data/rotation_data/assembly_projection_isaac.stl'
points = stl_get(stl_path)

# 计算点云的法向量
def compute_normals(points):
    normals = []
    for i, p0 in enumerate(points):
        v1 = points[(i+1) % len(points)] - p0
        v2 = points[(i+2) % len(points)] - p0
        normals.append(np.cross(v1, v2))
    return normals

normals = compute_normals(points)

# 将点云和法向量保存为OBJ格式文件
with open('/home/pxing/codes/point_improve/data/obj/point_f_assembly.obj', 'w') as f:
    for i, p in enumerate(points):
        f.write(f'v {p[0]} {p[1]} {p[2]}\n')
        n = normals[i]
        f.write(f'vn {n[0]} {n[1]} {n[2]}\n')

生成带面的obj文章来源地址https://www.toymoban.com/news/detail-715917.html

import numpy as np



def stl_get(stl_path):
    points=[]
    f = open(stl_path)
    lines = f.readlines()
    prefix='vertex'
    num=3
    for line in lines:
        #print (line)

        if line.startswith(prefix):
            values = line.strip().split()
            #print(values[1:4])
            if num%3==0:
                points.append([values[1],values[2],values[3]])
                num=0
            num+=1
        #print(type(line))
    points=np.array(points,dtype='float64')

    #points=points*1000#3d打印用

    
    f.close()
    #print(points.shape)
    #np.save("/home/pxing/codes/point_improve/feature_get/point_get/index_mm_level.npy", t)
    return points

# 点云数据

stl_path='/home/pxing/codes/point_improve/data/rotation_data/assembly_projection_isaac.stl'
points = stl_get(stl_path)
 

# 计算点云的法向量
def compute_normals(points):
    normals = []
    for i, p0 in enumerate(points):
        v1 = points[(i+1) % len(points)] - p0
        v2 = points[(i+2) % len(points)] - p0
        normals.append(np.cross(v1, v2))
    return normals

normals = compute_normals(points)

# 将点云和法向量保存为OBJ格式文件
with open('/home/pxing/codes/point_improve/data/obj/point_f_assembly.obj', 'w') as f:
    for i, p in enumerate(points):
        f.write(f'v {p[0]} {p[1]} {p[2]}\n')
        n = normals[i]
        f.write(f'vn {n[0]} {n[1]} {n[2]}\n')

    # 将点云转换为面信息
    for i in range(0, len(points), 3):
        f.write(f'f {i+1}//{i+1} {i+2}//{i+2} {i+3}//{i+3}\n')

.5 ply生成

import numpy as np

def stl_get(stl_path):
    points=[]
    f = open(stl_path)
    lines = f.readlines()
    prefix='vertex'
    num=3
    for line in lines:
        #print (line)

        if line.startswith(prefix):
            values = line.strip().split()
            #print(values[1:4])
            if num%3==0:
                points.append([values[1],values[2],values[3]])
                num=0
            num+=1
        #print(type(line))
    points=np.array(points,dtype='float64')

    #points=points*1000#3d打印用

    
    f.close()
    #print(points.shape)
    #np.save("/home/pxing/codes/point_improve/feature_get/point_get/index_mm_level.npy", t)
    return points

# 点云数据

stl_path='/home/pxing/codes/point_improve/data/rotation_data/assembly_projection_isaac.stl'
points = stl_get(stl_path)

# 将点云保存为含有顶点和面信息的PLY格式文件
with open('/home/pxing/codes/point_improve/data/obj/point_cloud.ply', 'w') as f:
    # 写入PLY文件头
    f.write('ply\n')
    f.write('format ascii 1.0\n')
    f.write(f'element vertex {len(points)}\n')
    f.write('property float x\n')
    f.write('property float y\n')
    f.write('property float z\n')
    f.write(f'element face {len(points)}\n')
    f.write('property list uchar int vertex_indices\n')
    f.write('end_header\n')

    # 写入点云数据
    for p in points:
        f.write(f'{p[0]} {p[1]} {p[2]}\n')

    # 写入面数据
    for i in range(len(points)):
        f.write(f'3 {i} {i} {i}\n')

到了这里,关于python读取点云文件(.stl文件、.obj文件)(以及转换为obj方法)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • vue-3d-model js在线预览obj,dae,ply,json,fbx,stl,gltf格式的3D文件

    在线预览地址vue-3d-model js在线预览obj,dae,ply,json,fbx,stl,gltf格式的3D文件 效果: 例子使用了.obj 3D文件格式,自带了截图和旋转功能,其他的3D格式只需要切换一个vue的模板标签即可。具体标签格式如下: 可支持obj,dae,ply,json,fbx,stl,gltf等格式的3D文件格式显示。只需要单页面html即

    2024年02月12日
    浏览(58)
  • Python读取一个csv文件并转换为Numpy矩阵

    利用pandas库读取,转为numpy矩阵 注意读取csv文件时第一行数据默认不读,因此需要给csv加一行。   运行结果  

    2024年02月12日
    浏览(43)
  • [visionOS] [Apple Vision Pro] 3D模型文件格式转换:obj转usdz

    1,先要安装好Python3.7 【必须是Python3.7.x版本】 到Python官方去下载macOS版的Python3.7.x安装包 Python Releases for macOS | Python.org 要注意找一下,有些 3.7.x版本没有macOS安装包, 这里直接给出其中两个可以下载的 Python 3.7.8rc1 - June 17, 2020 Download macOS 64-bit installer Python 3.7.9 - Aug. 17, 2020

    2024年02月16日
    浏览(110)
  • python hdfs远程连接以及上传文件,读取文件内容,删除文件

    目录 一、python连接操作hdfs 1 往hdfs上传文件 2 处理并存储到hdfs 3 读取hdfs上的txt文件 这里使用的是 pip 安装,很方便:      

    2024年02月11日
    浏览(56)
  • python读取文件夹下的文件以及子文件夹中文件

    os.listdir() 读取目标文件夹下的文件名和子文件夹名,不会递归读取子文件夹下 方法一: root, dirs, files = os.walk() 递归读取文件夹和 子文件夹下所有文件 。方法二:也可以用os.listdir(),判断是文件夹再os.listdir()自己写一个递归程序 示例

    2024年02月16日
    浏览(70)
  • Python3.7+PyQt5 pyuic5将.ui文件转换为.py文件、Python读取配置文件、生成日志

    1.实际开发项目时,是使用Qt Designer来设计UI界面,得到一个.ui的文件,然后利用PyQt5安装时自带的工具 pyuic5 将.ui文件转换为.py文件: 样式图 QT5 UI: 转换的pyqt5: 效果: 2.Python学习之读取配置文件: 初始配置文件test.conf: 步骤1:导入配置文件模块 步骤2:创建配置文件对象 步骤

    2024年01月25日
    浏览(50)
  • C# 读取pcd、ply点云文件数据

            最近研究了下用pcl读取点云数据,又做了个C#的dll,方便读取,同样这个dll基于pcl 最新版本1.13.1版本开发。         上次做的需要先得到点云长度,再获取数据。这次这个定义了一个PointCloudXYZ类来存数据。将下面的dll拷贝到可执行目录下,引用Q_PclSharp.dll使用

    2024年02月12日
    浏览(50)
  • 推荐:vue-3d-loader支持.dae/.fbx/.gltf/.glb/.obj/.ply/.stl/.json,并支持同一个场景导入多个不同3D模型,支持mtl材质以及jpg/png等图片纹理

    vue-3d-loader是vueJS + threeJS整合的一个3d展示组件。 支持.dae/.fbx/.gltf/.glb/.obj/.ply/.stl/.json,并支持同一个场景导入多个不同3D模型,支持mtl材质以及jpg/png等图片纹理 vue3请安装 2.0.0 及以上版本࿰

    2024年02月10日
    浏览(54)
  • Python点云处理(一)点云数据读取与写入

    当处理点云数据时,我们通常需要读取各种不同格式的点云文件。Python作为一种强大的编程语言,在点云处理领域提供了许多库和工具,可以帮助我们读取和处理各种格式的点云文件。本文将介绍如何使用Python读取和写入各种格式的点云文件。 LAS(Lidar Data Exchange)和LAZ(L

    2024年02月08日
    浏览(40)
  • Unity场景素材导出为 OBJ文件的方法

    一、Unity场景素材导出为 FBX文件的方法:http://t.csdn.cn/Xyjxe 二、Unity场景素材导出为 OBJ文件的方法:http://t.csdn.cn/08RY3 三、Unity地形导出为 OBJ文件的方法 (大家可以打开我的博客主页进行查看此系列其它文章) 目录 系列文章目录 前言 一、Unity场景素材导出OBJ文件 安装插件

    2024年02月10日
    浏览(65)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包