Package c3d
Python C3D Processing
This package provides pure Python modules for reading, writing, and editing binary motion-capture files in the C3D file format.
Installing
See the main page or github page.
Examples
Access to data blocks in a .c3d file is provided through the Reader
and Writer
classes.
Implementation of the examples below are provided in the examples/ directory in the github repository.
Reading
To read the frames from a C3D file, use a Reader
instance:
import c3d
with open('my-motion.c3d', 'rb') as file:
reader = c3d.Reader(file)
for i, points, analog in reader.read_frames():
print('frame {}: point {}, analog {}'.format(
i, points.shape, analog.shape))
The method Reader.read_frames()
generates tuples
containing the trial frame number, a numpy
array of point
data, and a numpy
array of analog data.
Writing
To write data frames to a C3D file, use a Writer
instance:
import c3d
import numpy as np
# Writes 100 frames recorded at 200 Hz.
# Each frame contains recordings for 24 coordinate markers.
writer = c3d.Writer(point_rate=200)
for _ in range(100):
writer.add_frames((np.random.randn(24, 5), ()))
writer.set_point_labels(['RFT1', 'RFT2', 'RFT3', 'RFT4',
'LFT1', 'LFT2', 'LFT3', 'LFT4',
'RSK1', 'RSK2', 'RSK3', 'RSK4',
'LSK1', 'LSK2', 'LSK3', 'LSK4',
'RTH1', 'RTH2', 'RTH3', 'RTH4',
'LTH1', 'LTH2', 'LTH3', 'LTH4'
])
writer.set_analog_labels(None)
with open('random-points.c3d', 'wb') as h:
writer.write(h)
The function Writer.add_frames()
take pairs of numpy
or python
arrays
, with the first array in each tuple defining point data and the second
analog data for the frame. Leaving one of the arrays empty indicates
to the writer that no analog — or point data— should be included in the file.
References of the data arrays are tracked until Writer.write()
is called, which serializes the metadata and data frames into a C3D binary file stream.
Editing
Editing c3d files is possible by combining the use of Reader
and Writer
instances through the Reader.to_writer()
method. To edit a file, open a file stream and pass
it to the Reader
constructor. Use the Reader.to_writer()
method to create
an independent Writer
instance containing a heap copy of its file contents.
To edit the sequence, one can now reread the data frames from the reader and through inserting the
frames in reverse to create a looped version of the original motion sequence!
import c3d
with open('my-motion.c3d', 'rb') as file:
reader = c3d.Reader(file)
writer = reader.to_writer('copy')
for i, points, analog in reader.read_frames():
writer.add_frames((points, analog), index=reader.frame_count)
with open('my-looped-motion.c3d', 'wb') as h:
writer.write(h)
Accessing Metadata
Metadata in a .c3d file exists in two forms, a Header
and ParamData
.
Reading metadata fields can be done though the Reader
but editing requires a
Writer
instance.
Header
fields can be accessed from the common Manager.header
attribute.
Parameters are available through a parameter Group
, and can be accessed
through the Manager.get()
and Group.get()
methods:
group = reader.get('POINT')
param = group.get('LABELS')
or simply use
param = reader.get('POINT:LABELS')
Note that for accessing parameters in the Reader
, Reader.get()
returns a GroupReadonly
instance. Convenience functions are provided
for some of the common metadata fields such as Manager.frame_count
.
In the case you require specific metadata fields, consider exploring
the C3D format manual and/or inspect the file using the c3d-metadata script.
Writing Metadata
Once a Writer
instance is created, to edit
parameter data Writer.get_create()
a group:
group = writer.get_create('ANALOG')
and to write a float32 entry, use the Group.add()
or Group.set()
functions
group.set('GEN_SCALE', 'Analog general scale factor', 4, '<f', value)
In this case, one can use the Writer.set_analog_general_scale()
method instead.
For serializing other types, see the source code for some of the convenience functions. For example:
Writer.set_point_labels()
(2D string array) or
Writer.set_analog_scales()
(1D float array).
Expand source code
"""
---------------------
Python C3D Processing
---------------------
This package provides pure Python modules for reading, writing, and editing binary
motion-capture files in the [C3D file format].
[C3D file format]: https://www.c3d.org/HTML/default.htm
Installing
----------
See the [main page] or [github page].
[main page]: https://mattiasfredriksson.github.io/py-c3d/
[github page]: https://github.com/EmbodiedCognition/py-c3d
.. include:: ../docs/examples.md
"""
from . import dtypes
from . import group
from . import header
from . import manager
from . import parameter
from . import utils
from .reader import Reader
from .writer import Writer
Sub-modules
c3d.dtypes
-
State object defining the data types associated with a given .c3d processor format.
c3d.group
-
Classes used to represent the concept of parameter groups in a .c3d file.
c3d.header
-
Defines the header class used for reading, writing and tracking metadata in the .c3d header.
c3d.manager
-
Manager base class defining common attributes for both Reader and Writer instances.
c3d.parameter
-
Classes used to represent the concept of a parameter in a .c3d file.
c3d.reader
-
Contains the Reader class for reading C3D files.
c3d.utils
-
Trailing utility functions.
c3d.writer
-
Contains the Writer class for writing C3D files.