Repository navigation
Sync a GPX to the GPS clock of a timelapse, even one too noisy to publish - #849
Merged
Merged
Conversation
…lish A timelapse compresses time: each second of video spans several seconds of GPS time. A GPX was synced to it at 1x, so it landed at the wrong video times, most of it past the end of the video. The reported GoPro MAX2 clip is 1.24s of video covering 15.5s of GPS time, and its GPX landed at 0-12s. Read the GPS clock of the video as (video time, Unix time) pairs, anchored at the first pair at its own video time. Its rate is the least-squares slope of the pairs. It is used when both it and the median step between neighbouring pairs are over 1.5x, so that one timestamp far off cannot turn a normal video into a timelapse, and is 1x otherwise. A GPS5 block, which stamps ~1s of points with one timestamp, counts once. The reported clip's GPS is rejected as noise, so the GPX was synced from the start of the video, without a clock to read the rate from. In that case read the clock from the unfiltered points: they are never published, and their timestamps usually still keep time (the reported clip's do). This also keeps the make, model and filetype of the video. A GoPro stamps a placeholder date (2015-10-22 and similar) until it acquires GPS time, so a noisy clock that puts the GPX more than a day away from the video is ignored with a warning, and the GPX is synced from the start of the video as before. To verify, the tracks of 17 sample videos (GoPro MAX, MAX2, HERO7, HERO8, BlackVue, Labpano, Insta360) were exported as GPX and synced back to their videos. The median error went from 6.7-612s to under 0.2s on the seven timelapses among them, and did not change on the others. Across 519 sample files with a GPS clock, only the seven timelapses (two of them stored twice) are detected as such, at 2x to 30x.
caglarpir
force-pushed
the
sync-gpx-timelapse-clock
branch
from
October 20, 2026 08:04
a592d3e to
978649d
Compare
caglarpir
added a commit
to caglarpir/mapillary_tools
that referenced
this pull request
Oct 20, 2026
main reworked GPXVideoExtractor (mapillary#831, mapillary#847, mapillary#849): it syncs a GPX through a VideoClock, with a rate for timelapses, falls back to the start of the video when the video's GPS has no usable clock, and reports a GPX it cannot parse. This branch changed the same method, so take main's and re-apply this branch's changes to it: - Drop GPX points timestamped before 1980, and sort the rest. - Place the GPX by --video_start_time wherever the video has no clock to sync it with: no usable GPS, as before, and now also GPS without a clock, such as noise with a placeholder date, which main places at the start of the video. - Apply --interpolation_offset_time after the sync. The offset is in GPS seconds, so with a timelapse clock the track moves by offset / rate seconds of video; by the whole offset, frames would be picked offset * (rate - 1) seconds of track away from where they are geotagged. In factory.py, keep both main's EXTERNAL_GPS_SOURCES and this branch's _ALL_VIDEO_TYPES. Tests cover the clockless placement and the timelapse offset.
This was referenced Oct 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A timelapse compresses time: each second of video spans several seconds of GPS time. A GPX is synced to the video at 1x, so on a timelapse it lands at the wrong video times, most of it past the end of the video.
The GoPro MAX2 clip reported in #831 is 1.24 s of 12.5x timelapse covering 15.5 s of GPS time. Since #831 its GPX is accepted, but lands at 0 to 12 s. Its GPS is rejected as noise, so there is not even a clock to read the rate from: the GPX is synced from the start of the video.
Changes
Verification
The reported clip: its GPX lands at 0.16 to 1.13 s, where its GPS clock places it (0.16 to 1.12 s), with make and model GoPro / MAX2.
The tracks of 17 sample videos (GoPro MAX, MAX2, HERO7, HERO8, BlackVue, Labpano, Insta360) exported as GPX and synced back to their videos. Median error:
Across 519 sample files with a GPS clock (GoPro, BlackVue, CAMM cameras), only those seven are detected as timelapses (two of them stored twice).
Across 168 runs over sample files from over 20 cameras, this PR changes no output. The one timelapse with a GPX among them, from an Insta360 ONE X, has no GPS clock to read a rate from.
Unit: 750 passed, 18 skipped, 1 xfailed. Integration: 57 passed. Doctests pass.
mypy,ruff checkandruff format --checkare clean.Interactions with other open PRs
Whichever lands second needs these by hand:
clock.to_unix_time(0)andclock.to_unix_time(...)of its end.test_good_clock_days_away_is_still_usedthen expectsMapillaryOutsideGPXTrackError._place_without_video_gps()instead of_rebase_times(), or--video_start_timeis ignored there._gpx_offset(), which this PR replaces._read_video_clock()already anchors on the first point with a timestamp.