"""
Contains reading and writing functions for ply files as well as a conversion function and other useful functions related to ply files
"""
# -*- coding: utf-8 -*-
# Created on Sun Jul 14 10:17:54 2019
# @author: Cédric Perion | Arthur Dujardin
import numpy as np
import plyfile
[docs]def read_plyfile(file_name):
"""
Read and extract the data of a ply file.
Parameters
----------
file_name : str
The path to the ply file.
Raises
------
FileNotFoundError
If the file is not found, raises an error.
Returns
-------
plydata : plyfile.PlyData
The data of the cloud points file.
"""
try:
ply = open(file_name, mode='rb')
except FileNotFoundError:
raise FileNotFoundError("ply file not found")
plydata = plyfile.PlyData.read(ply)
return plydata
[docs]def write_plydata(plydata, data_channel,
new_channel_name, outfile_name="my_cloud.ply"):
"""
Create a ply file from plydata.
Can add an additional channel to the plydata.
Parameters
----------
plydata : plyfile.PlyData
The plydata to write in the file.
data_channel : numpy.ndarray
Data of the added channel.
new_channel_name : str
Name of the new added channel.
outfile_name : str, optionnal
Name of the ply file created.
The default is "my_cloud.ply".
Returns
-------
None
"""
dtype = plydata.elements[0].data.dtype.descr
# If there is a channel added
dtype = dtype + [(new_channel_name, 'u1')]
vertex = plydata.elements[0].name
data = []
for i in range(len(data_channel)):
l = tuple(list(plydata[vertex][i]) + [data_channel[i]])
data.append(l)
data = np.array(data, dtype)
el = plyfile.PlyElement.describe(data, 'vertex')
plyfile.PlyData([el], text=True).write(outfile_name)
[docs]def plydata_to_array(plydata):
"""
Convert a plydata to numpy array.
Parameters
----------
plydata : plyfile.PlyData
The plydata to convert.
Returns
-------
numpy.ndarray
The converted data, containing the 3D coordinates of the plydata's points.
"""
data = np.array([plydata.elements[0].data['x'],
plydata.elements[0].data['y'],
plydata.elements[0].data['z']])
return np.transpose(data)
[docs]def add_channel_from_plydata(plydata, coord, channel):
"""
Add a channel to the numpy data.
Parameters
----------
plydata : plyfile.PlyData
Raw data.
coord : numpy.ndarray
The coordinates of the 3D points.
channel : str
Name of the channel to add.
Returns
-------
data : TYPE
DESCRIPTION.
"""
data = np.column_stack((coord, plydata.elements[0].data[channel]))
return data
# TODO: delete this
# def add_channel_from_data(data, channel_data, channel_name):
# """
# Add a channel (usually generated by a projection into other images)
# to the numpy data.
# Parameters
# ----------
# data : numpy.ndarray
# The data which contains the coordinates of every points.
# channel_data : numpy.ndarray
# Vector of the channel's values.
# channel_name : str
# DESCRIPTION.
# Returns
# -------
# coord : TYPE
# DESCRIPTION.
# """
# if len(channel_data) != len(data):
# print("\nERROR : different size between the channel added and the matrix of coordinates points\n\n")
# else:
# coord = np.column_stack((data, channel_data))
# return coord