Skip to content

io

3D Skeleton and Point Cloud I/OLink

This module provides functions for loading and saving 3D point clouds and skeleton data in various file formats, simplifying data interchange between different tools and libraries.

Key FeaturesLink

  • Load point clouds from XYZ, PLY and JSON formats
  • Load skeleton data from NetworkX graph files
  • Save tree structures to JSON and NetworkX pickle formats
  • Support for various coordinate formats and attribute handling

load_json Link

load_json(filename, key=None)

Load a point cloud or skeleton file from a JSON file.

Parameters:

Name Type Description Default
filename str or Path

Path to the JSON file to parse.

required
key str

The key of the JSON dictionary containing the point cloud or skeleton coordinates to load. If None, the entire JSON content is returned.

None

Returns:

Type Description
ndarray

The XYZ coordinates of the point cloud or skeleton as a NumPy array with shape (n, 3), where n is the number of points.

Examples:

>>> from skeleton_refinement.io import load_json
>>> # JSON file with structure: {"points": [[x1,y1,z1], [x2,y2,z2], ...]}
>>> points = load_json('point_cloud.json', key='points')
>>> print(points.shape)
(1000, 3)
>>> # JSON file with direct array: [[x1,y1,z1], [x2,y2,z2], ...]
>>> points = load_json('simple_points.json')
>>> print(points.shape)
(1000, 3)
Source code in skeleton_refinement/io.py
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
def load_json(filename, key=None):
    """Load a point cloud or skeleton file from a JSON file.

    Parameters
    ----------
    filename : str or pathlib.Path
        Path to the JSON file to parse.
    key : str, optional
        The key of the JSON dictionary containing the point cloud or skeleton
        coordinates to load. If ``None``, the entire JSON content is returned.

    Returns
    -------
    numpy.ndarray
        The XYZ coordinates of the point cloud or skeleton as a NumPy array
        with shape ``(n, 3)``, where ``n`` is the number of points.

    Examples
    --------
    >>> from skeleton_refinement.io import load_json
    >>> # JSON file with structure: {"points": [[x1,y1,z1], [x2,y2,z2], ...]}
    >>> points = load_json('point_cloud.json', key='points')
    >>> print(points.shape)
    (1000, 3)
    >>> # JSON file with direct array: [[x1,y1,z1], [x2,y2,z2], ...]
    >>> points = load_json('simple_points.json')
    >>> print(points.shape)
    (1000, 3)
    """
    import json
    with open(filename, mode='rb') as f:
        X = json.load(f)

    if key is not None:
        X = X[key]
    return np.array(X)

load_nx Link

load_nx(filename, key='position')

Load a tree graph from a pickled NetworkX file.

Parameters:

Name Type Description Default
filename str or Path

Path to the pickled NetworkX graph file to parse.

required
key str

The node attribute key containing the position data. Default is 'position'.

'position'

Returns:

Type Description
ndarray

The XYZ coordinates of the nodes as a NumPy array with shape (n, 3), where n is the number of nodes.

Examples:

>>> from skeleton_refinement.io import load_nx
>>> positions = load_nx('graph.pkl')
>>> print(positions.shape)
(50, 3)
>>> # Load custom attribute
>>> attributes = load_nx('graph.pkl', key='custom_attribute')
Notes

The NetworkX graph must have nodes with the specified attribute.

Source code in skeleton_refinement/io.py
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
def load_nx(filename, key='position'):
    """Load a tree graph from a pickled NetworkX file.

    Parameters
    ----------
    filename : str or pathlib.Path
        Path to the pickled NetworkX graph file to parse.
    key : str, optional
        The node attribute key containing the position data.
        Default is 'position'.

    Returns
    -------
    numpy.ndarray
        The XYZ coordinates of the nodes as a NumPy array with shape (n, 3),
        where n is the number of nodes.

    Examples
    --------
    >>> from skeleton_refinement.io import load_nx
    >>> positions = load_nx('graph.pkl')
    >>> print(positions.shape)
    (50, 3)
    >>> # Load custom attribute
    >>> attributes = load_nx('graph.pkl', key='custom_attribute')

    Notes
    -----
    The NetworkX graph must have nodes with the specified attribute.
    """
    import pickle
    with open(filename, mode='rb') as f:
        G = pickle.load(f)

    X = []
    for node in G.nodes:
        X.append(G.nodes[node][key])

    return np.array(X)

load_ply Link

load_ply(filename)

Load point cloud coordinates from a PLY file.

Parameters:

Name Type Description Default
filename str or Path

Path to the PLY file to parse.

required

Returns:

Type Description
The XYZ coordinates of the point cloud as a NumPy array

with shape (n, 3), where n is the number of points.

Examples:

>>> from skeleton_refinement.io import load_ply
>>> points = load_ply('point_cloud.ply')
>>> print(points.shape)
(1000, 3)
>>> print(points[:2])
[[ 1.2  3.4  5.6]
 [-0.1  0.2  0.3]]
Source code in skeleton_refinement/io.py
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
def load_ply(filename):
    """Load point cloud coordinates from a PLY file.

    Parameters
    ----------
    filename : str or pathlib.Path
        Path to the PLY file to parse.

    Returns
    -------
    The XYZ coordinates of the point cloud as a NumPy array
        with shape ``(n, 3)``, where ``n`` is the number of points.

    Examples
    --------
    >>> from skeleton_refinement.io import load_ply
    >>> points = load_ply('point_cloud.ply')
    >>> print(points.shape)
    (1000, 3)
    >>> print(points[:2])
    [[ 1.2  3.4  5.6]
     [-0.1  0.2  0.3]]
    """
    from plyfile import PlyData
    plydata = PlyData.read(filename)
    X = np.array([plydata['vertex']['x'], plydata['vertex']['y'], plydata['vertex']['z']]).T
    return X

load_xyz Link

load_xyz(filename)

Load a point cloud or skeleton file saved as a series of space-separated XYZ coordinates.

Parameters:

Name Type Description Default
filename str or Path

Path to the point cloud or skeleton file to parse.

required

Returns:

Type Description
ndarray

The XYZ coordinates of the point cloud or skeleton as a NumPy array with shape (n, 3), where n is the number of points.

Examples:

>>> from skeleton_refinement.io import load_xyz
>>> points = load_xyz('point_cloud.xyz')
>>> print(points.shape)
(1000, 3)
>>> print(points[:2])
[[ 1.2  3.4  5.6]
 [-0.1  0.2  0.3]]
Source code in skeleton_refinement/io.py
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
def load_xyz(filename):
    """Load a point cloud or skeleton file saved as a series of space-separated XYZ coordinates.

    Parameters
    ----------
    filename : str or pathlib.Path
        Path to the point cloud or skeleton file to parse.

    Returns
    -------
    numpy.ndarray
        The XYZ coordinates of the point cloud or skeleton as a NumPy array
        with shape ``(n, 3)``, where ``n`` is the number of points.

    Examples
    --------
    >>> from skeleton_refinement.io import load_xyz
    >>> points = load_xyz('point_cloud.xyz')
    >>> print(points.shape)
    (1000, 3)
    >>> print(points[:2])
    [[ 1.2  3.4  5.6]
     [-0.1  0.2  0.3]]
    """
    f = open(filename, "r")
    lines = f.readlines()
    org_x = []
    org_y = []
    org_z = []
    for l in lines:
        org_x.append(float(l.split(' ')[0]))
        org_y.append(float(l.split(' ')[1]))
        org_z.append(float(l.split(' ')[2]))
    f.close()
    X = np.column_stack((org_x, org_y, org_z))
    return X

save_json Link

save_json(filename, G, **kwargs)

Save a tree graph to a JSON file.

This function exports a NetworkX graph to a JSON file format, storing both node positions and edge connections.

Parameters:

Name Type Description Default
filename str or Path

Path to the JSON file to write.

required
G Graph

Graph to write. Nodes must have a 'position' attribute.

required
**kwargs

Additional keyword arguments to pass to json.dumps(). If 'indent' is not provided, it defaults to 2.

{}

Examples:

>>> import networkx as nx
>>> from skeleton_refinement.io import save_json
>>> G = nx.Graph()
>>> G.add_node(0, position=[0,0,0])
>>> G.add_node(1, position=[1,1,1])
>>> G.add_edge(0, 1)
>>> save_json('graph.json', G)
>>> # With custom JSON formatting
>>> save_json('pretty_graph.json', G, indent=4, sort_keys=True)
Notes

The output JSON structure will contain: - 'points': list of node positions - 'lines': list of edges

Source code in skeleton_refinement/io.py
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
def save_json(filename, G, **kwargs):
    """Save a tree graph to a JSON file.

    This function exports a NetworkX graph to a JSON file format,
    storing both node positions and edge connections.

    Parameters
    ----------
    filename : str or pathlib.Path
        Path to the JSON file to write.
    G : networkx.Graph
        Graph to write. Nodes must have a 'position' attribute.
    **kwargs
        Additional keyword arguments to pass to ``json.dumps()``.
        If 'indent' is not provided, it defaults to ``2``.

    Examples
    --------
    >>> import networkx as nx
    >>> from skeleton_refinement.io import save_json
    >>> G = nx.Graph()
    >>> G.add_node(0, position=[0,0,0])
    >>> G.add_node(1, position=[1,1,1])
    >>> G.add_edge(0, 1)
    >>> save_json('graph.json', G)
    >>> # With custom JSON formatting
    >>> save_json('pretty_graph.json', G, indent=4, sort_keys=True)

    Notes
    -----
    The output JSON structure will contain:
    - 'points': list of node positions
    - 'lines': list of edges
    """
    import json
    data = {
        "points": [G.nodes[node]['position'] for node in G.nodes],
        "lines": list(G.edges),
    }
    if 'indent' not in kwargs:
        kwargs.update({'indent': 2})
    with open(filename, 'w') as f:
        f.writelines(json.dumps(data, **kwargs))
    return

save_nx Link

save_nx(filename, G, **kwargs)

Save a tree graph to a pickle file.

This function saves a NetworkX graph to a pickle file for later retrieval.

Parameters:

Name Type Description Default
filename str or Path

Path to the pickle file to write.

required
G Graph

Graph to write.

required
**kwargs

Additional keyword arguments to pass to pickle.dump(). If 'protocol' is not provided, it defaults to pickle.HIGHEST_PROTOCOL.

{}

Examples:

>>> import networkx as nx
>>> from skeleton_refinement.io import save_nx
>>> G = nx.Graph()
>>> G.add_node(0, position=[0,0,0])
>>> G.add_node(1, position=[1,1,1])
>>> G.add_edge(0, 1)
>>> save_nx('graph.pkl', G)
>>> # With specific protocol
>>> save_nx('graph_v2.pkl', G, protocol=2)
Notes

The pickle format is not secure against erroneous or maliciously constructed data. Never unpickle data received from untrusted or unauthenticated sources.

Source code in skeleton_refinement/io.py
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
def save_nx(filename, G, **kwargs):
    """Save a tree graph to a pickle file.

    This function saves a NetworkX graph to a pickle file for later retrieval.

    Parameters
    ----------
    filename : str or pathlib.Path
        Path to the pickle file to write.
    G : networkx.Graph
        Graph to write.
    **kwargs
        Additional keyword arguments to pass to pickle.dump().
        If 'protocol' is not provided, it defaults to pickle.HIGHEST_PROTOCOL.

    Examples
    --------
    >>> import networkx as nx
    >>> from skeleton_refinement.io import save_nx
    >>> G = nx.Graph()
    >>> G.add_node(0, position=[0,0,0])
    >>> G.add_node(1, position=[1,1,1])
    >>> G.add_edge(0, 1)
    >>> save_nx('graph.pkl', G)
    >>> # With specific protocol
    >>> save_nx('graph_v2.pkl', G, protocol=2)

    Notes
    -----
    The pickle format is not secure against erroneous or maliciously constructed data.
    Never unpickle data received from untrusted or unauthenticated sources.
    """
    import pickle
    if 'protocol' not in kwargs:
        kwargs['protocol'] = pickle.HIGHEST_PROTOCOL
    if isinstance(filename, str):
        filename = Path(filename)
    with filename.open(mode='wb') as f:
        pickle.dump(G, f, **kwargs)
    return