1

我正在尝试编写一个简短的脚本来将包含点坐标的文本文件转换为二进制层文件。想法是在开头添加一个标题,将文件类型更改为 ASCII ply,然后使用 plyfile 读取它并写入二进制 ply。我会使用 CloudCompare 或 Meshlab 手动执行此操作,但我有几千个文件要转换。

我找到了一个可以使用 CloudCompare 打开的 ASCII 层文件,但是当我尝试使用 PlyData.read 时出现 AttributeError。当我尝试在直接从 CloudCompare 保存的文件上运行它时,我得到了同样的错误。

这是我将代码简化为用于调试的内容:

import os
from glob import glob
from plyfile import PlyData, PlyElement

if __name__ == '__main__':
    #Request input if no system arguments found
    try:
        inputDirName = sys.argv[1]
    except IndexError:
        inputDirName = input('Enter directory containing ASCII ply files:\n')
    os.chdir(inputDirName)

    files = glob('*.ply')
    for file in files:
        with open(file, 'r+') as f:
            data = PlyData.read(f)
            PlyData([data]).write(file.split('.')[0] + '_binary.ply')

这是我运行它时遇到的错误

File "C:\Users\user\Miniconda3\lib\site-packages\plyfile.py", line 392, in read
   data = PlyData._parse_header(stream)
File "C:\Users\user\Miniconda3\lib\site-packages\plyfile.py", line 373, in _parse_header                         
   while parser.consume(stream.readline()):
File "C:\Users\user\Miniconda3\lib\site-packages\plyfile.py", line 120, in consume
   line = raw_line.decode('ascii').strip()
AttributeError: 'str' object has no attribute 'decode'
4

2 回答 2

1

如果您的任务只是将多个文件从 ply ascii 转换为 ply 二进制文件,则可以使用 meshlabserver,meshlabserver 是可编写脚本且非常适合此类任务的命令行版本。

此外,如果您真的很勇敢,您甚至可以尝试即将推出的 pymeshlab ( https://github.com/cnr-isti-vclab/PyMeshLab ),例如所有 meshlab 功能的 python 绑定;目前(2020 年 8 月)它处于非常 alpha 的状态,但已经几乎可用......

于 2020-08-10T18:49:25.907 回答
0

这并不能直接回答有关 AttributeError 的问题,但我能够通过自己将文件解析为 numpy 数组来解决该问题。最终结果如下所示:

#!/usr/bin/env python

import os
import sys
import numpy as np
from datetime import datetime
from glob import glob
from plyfile import PlyData, PlyElement
    
if __name__ == '__main__':
    #Request input if no system arguments found
    try:
        inputDirName = sys.argv[1]
    except IndexError:
        inputDirName = input('Enter directory containing files to be converted:\n')
    os.chdir(inputDirName)
    
    files = glob('*.txt')
    for file in files:
        with open(file, 'r+') as f:
            # Get number of vertices
            vertices = int(f.readline())
            
            # Create empty numpy array and define datatypes
            numpyArray = np.empty(vertices,dtype=[('x', 'f4'), ('y', 'f4'), ('z', 'f4'),
                                 ('red', 'u1'), ('green', 'u1'), ('blue', 'u1')])
            
            # Read file contents into array
            for index, line in enumerate(f):
                x, y, z, r, g, b = line.strip().split(' ')
                numpyArray[index] = (x, y, z, r, g, b)
            
            # Create PlyElement instance
            el = PlyElement.describe(numpyArray, 'vertex',
                                     comments=['Created ' + str(datetime.now())])
            
            # Write to binary ply file
            binaryFile = file.split('.')[0] + '_binary.ply'
            PlyData([el]).write(binaryFile)
            
        print('Saved ' + binaryFile)
于 2020-08-11T15:56:32.603 回答