-
Notifications
You must be signed in to change notification settings - Fork 28
Description
(an issue suggested by Claude :-)
Bug
PoseBody.fps is documented and typed as float in pose_body.py, but several locations in the codebase cast it to int, silently losing precision for non-integer framerates like 29.97 fps (NTSC standard).
Affected locations
1. utils/openpose.py — load_openpose()
# load_openpose() accepts fps as float, but casts to int
body = NumPyPoseBody(fps=int(fps), data=masked_data, confidence=confidence)The fps parameter is typed as float, but explicitly cast to int before constructing the body. A video at 29.97 fps becomes 29 fps.
2. tensorflow/pose_body.py — TFRecord serialization
# Record description defines fps as int64
'fps': tf.io.FixedLenFeature([], tf.int64, default_value=0),
# Serialization stores fps as int64
'fps': tf.train.Feature(int64_list=tf.train.Int64List(value=[self.fps])),FPS is stored as int64 in TFRecords. On deserialization it's cast back to float32, but the fractional part is already lost.
3. utils/generic.py — fake_pose()
# Function signature types fps as int
def fake_pose(num_frames: int, fps: int=25, ...):
body = NumPyPoseBody(fps=int(fps), ...)Minor (test utility), but reinforces the pattern.
Impact
Any video with a non-integer framerate (29.97, 23.976, 59.94 fps — all common standards) will have its framerate silently truncated. This causes audio/video sync drift and incorrect timing when the .pose file is used downstream.
Suggested fix
- Remove the
int()casts inload_openpose()andfake_pose(), passfpsthrough as-is - Change the TFRecord field from
tf.int64totf.float32(or serialize as bytes) - Update
fake_pose()signature tofps: float = 25.0