Trajectory Smoothing Filter
Implement camera trajectory smoothing for video stabilization. This task involves reducing the jitter in a video by smoothing the camera's motion trajectory between frames.
Video stabilization is crucial for enhancing the viewing experience, and it relies on accurately estimating the homography between consecutive frames, which describes the transformation of the camera's motion. The accumulation of these transformations yields the camera's trajectory over time. However, this trajectory is often noisy and needs to be smoothed to remove unwanted jitter.
Here are the key steps:
- Estimate the camera motion between frames using homography estimation techniques.
- Accumulate the transformations to obtain the camera trajectory.
- Apply a smoothing filter to the trajectory.
This technique is widely used in handheld camera recordings and action cameras to reduce shakiness.
Task
Implement smooth_trajectory(trajectory, window_size). The trajectory is already given (steps 1–2 are done for you); implement step 3 as a centred moving average:
- Smooth each component (, , angle) independently.
- For frame , average the frames from to with equal weights, where .
- Near the start and end, the window is truncated to the frames that exist, and the average is taken over only those frames.
- Return a list with one (x, y, angle) tuple per input frame (same length as the input), each value rounded to 2 decimal places. The tests print the tuples, so the values are expected as NumPy float64 scalars, e.g. (np.float64(3.33), np.float64(0.0), np.float64(0.0)).
Example
trajectory = [(0,0,0), (1,1,0.1), (0,2,0), (2,1,0.05), (1,2,0)] window_size = 3
Smoothed trajectory with reduced jitter
trajectoryholds one camera pose per frame, five frames here. Withwindow_size= 3, each frame is averaged with neighbour on each side, all weighted equally.- Each component is smoothed on its own. Frame 2 uses frames 1, 2, 3: , , .
- Frame 1 uses frames 0–2: , , . Frame 3 gives the same way.
- At the ends the window is cut short to two frames: frame 0 gives and frame 4 gives . In binary, sits just under the halfway point, so it rounds to .
- The result is a smoothed trajectory with reduced jitter: (0.5, 0.5, 0.05), (0.33, 1.0, 0.03), (1.0, 1.33, 0.05), (1.0, 1.67, 0.02), (1.5, 1.5, 0.02). That's one pose per input frame, rounded to 2 decimal places.
- Notice that raw jumps (swings of up to 2), while smoothed never moves more than between frames.
Constraints
- trajectory: List of (x, y, angle) camera positions per frame
- window_size: Smoothing window
- Return: Smoothed trajectory