pyomeca / ezc3d

Easy to use C3D reader/writer for C++, Python and Matlab
https://pyomeca.github.io/Documentation/ezc3d/index.html
MIT License
142 stars 44 forks source link

More than 65535 frames #308

Closed KnSun99 closed 7 months ago

KnSun99 commented 7 months ago

Hi,

When saving a c3d file, if the data exceeds 65535 frames, it is saved to a maximum of 65535 frames. How should I solve this problem?

Thank you.

pariterre commented 7 months ago

Hi @KnSun99 I am surprised as this limit was managed quite a while ago... Do you have a piece of code that I could test?

KnSun99 commented 7 months ago

OK,

def _toc3d_data(data, points, fps, save_path): n_frame, feature_number = data.shape n_feature = len(points)

coord = np.zeros((4, n_feature, n_frame))
for i in range(4):
    if i < 3:
        coord[i, :, :] = data[:, i::3].T
    elif i == 3:
        coord[i, :, :] = n_feature * np.ones([n_feature, n_frame])

c3d = ezc3d.c3d()
c3d['parameters']['POINT']['RATE']['SCALE'] = [int(fps)]
c3d["parameters"]["POINT"]["FRAMES"]["value"][0] = int(n_frame)
c3d['parameters']['POINT']['RATE']['value'][0] = int(fps)
c3d['parameters']['POINT']['LABELS']['value'] = tuple(points)
c3d['data']['points'] = coord

# Add a custom parameter to the POINT group
c3d.add_parameter("POINT", "newParam", [1, 2, 3])
# Add a custom parameter a new group
c3d.add_parameter("NewGroup", "newParam", ["MyParam1", "MyParam2"])
c3d.write(str(save_path))

data is two-dimension np.array, [number frames, every points(x,y,z)] points is Point name fps is int save_path is pathlib object

pariterre commented 7 months ago

Dear @KnSun99 I had a look at the code you provided (and slightly modify it so I could load random data save the file, read it back, modify the new file with more data then read this on back too. As far as I am concerned, the snippet actually works. I suspect that you run an old version of ezc3d. Please make sure you update and everything should be fine.

The following code should work if you are running the latest version:

import ezc3d
import numpy as np

fps = 100
n_feature = 10
points = [f"point{i}" for i in range(n_feature)]
n_frame = 70_000
save_path = "debug/test.c3d"

coord = np.random.rand(4, n_feature, n_frame)
coord[3, :, :] = 1

c3d = ezc3d.c3d()
c3d['parameters']['POINT']['RATE']['SCALE'] = [int(fps)]
c3d["parameters"]["POINT"]["FRAMES"]["value"][0] = int(n_frame)
c3d['parameters']['POINT']['RATE']['value'][0] = int(fps)
c3d['parameters']['POINT']['LABELS']['value'] = tuple(points)
c3d['data']['points'] = coord

# Add a custom parameter to the POINT group
c3d.add_parameter("POINT", "newParam", [1, 2, 3])
# Add a custom parameter a new group
c3d.add_parameter("NewGroup", "newParam", ["MyParam1", "MyParam2"])

# Write the file
c3d.write(save_path)

# Read the file
c3d_2 = ezc3d.c3d(save_path)
print(c3d_2['parameters']['POINT']['FRAMES']['value'])

# Check if the data is the same
assert np.all(c3d['data']['points'] - c3d_2['data']['points'] < 0.000001)

# Change the number of frames
fps = 100
n_feature = 10
points = [f"point{i}" for i in range(n_feature)]
n_frame = 80_000
save_path = "debug/test_2.c3d"

# Create new data
coord = np.random.rand(4, n_feature, n_frame)
coord[3, :, :] = 1

c3d_2['parameters']['POINT']['RATE']['SCALE'] = [int(fps)]
c3d_2["parameters"]["POINT"]["FRAMES"]["value"][0] = int(n_frame)
c3d_2['parameters']['POINT']['RATE']['value'][0] = int(fps)
c3d_2['parameters']['POINT']['LABELS']['value'] = tuple(points)
c3d_2['data']['points'] = coord
del c3d_2['data']['meta_points']  # Let ezc3d define the meta points itself

# Write the file
c3d_2.write(save_path)

# Read the file
c3d_3 = ezc3d.c3d(save_path)
print(c3d_3['parameters']['POINT']['FRAMES']['value'])

# Check if the data is the same
assert np.all(c3d_2['data']['points'] - c3d_3['data']['points'] < 0.000001)

Regards!

pariterre commented 7 months ago

Please reopen if this does not solve the issue :)

KnSun99 commented 7 months ago

Thanks for your reply!

I tested the code It can be solved

The problem is that the mokka software is not fully displayed.

pariterre commented 7 months ago

Ok I see, it seems that this relates to #303 . Moving to this discussion then :)

KnSun99 commented 7 months ago

OK

KnSun99 commented 6 months ago

image

This.c3D file is longer than 65535 frames and can be displayed. It appears to be written by the py-c3d module https://github.com/EmbodiedCognition/py-c3d?tab=readme-ov-file

pariterre commented 5 months ago

Dear @KnSun99 Would this be possible to send me this specific file? I could not find where you got it? You can send it directly to my email :)

KnSun99 commented 5 months ago

OK!It has been sent to your email. image

This is a randomly generated test file. “test_points.c3d”