Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use GPS time for videos if the difference with creation time is too big #659

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

malconsei
Copy link
Contributor

Some cameras reset their internal clock when the battery runs out, or otherwise get out of sync with the world clock.

  1. Change PointWithFix to a more generic GpsPoint which contains GPS timestamps.
  2. If available, save the GPS timestamp of the last point in the JSON description.
  3. Upon upload, use it as timestamp of the CAMM track.
  4. Server-side, use this timestamp if it's more than 86400s (1 day) apart from the video creation time.

@@ -173,7 +173,7 @@ def _aggregate_float_values_same_length(
if timestamp is None or lon is None or lat is None:
continue
track.append(
geo.PointWithFix(
geo.GpsPoint(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here I guess we can keep using geo.Point as unix_timestamp == time?

@@ -44,12 +44,13 @@ def _parse_gps_box(gps_data: bytes) -> T.Generator[geo.Point, None, None]:
if not nmea.is_valid:
continue
epoch_ms = int(match.group(1))
yield geo.Point(
yield geo.GpsPoint(
time=epoch_ms,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems to be a bug here: Point.time should be always seconds (either seconds since epoch or offsets in seconds).

Could you change it to time=epoch_ms / 1000 and remove the / 1000 at L107?

time=epoch_ms,
lat=nmea.latitude,
lon=nmea.longitude,
alt=nmea.altitude,
angle=None,
unix_timestamp=int(epoch_ms / 1000),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't need as unix_timestamp == time

time=sample.time_offset,
lat=box.data.latitude,
lon=box.data.longitude,
alt=box.data.altitude,
angle=None,
unix_timestamp=int(_gps_timestamp_to_unix(box.data.time_gps_epoch)),
gps_fix=geo.GPSFix(box.data.gps_fix_type),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding gps_fix/gps_ground_speed/gps_horizontal_accuracy here will trigger gps filtering which affect GPS points and video slicing. Let's do it in a separate PR with proper testing to be safe.

for some info on GPS timestamp. Here we arbitrarily use the offset as of 2023, since we
are not interested in precision to the second.
"""
return ts + 315964800 - 18
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why minus 18?

def _gps_timestamp_to_unix(ts: float) -> float:
"""
Convert a GPS timestamp to UNIX timestamp.
See https://stackoverflow.com/questions/20521750/ticks-between-unix-epoch-and-gps-epoch
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's good to know!

def filter_points_by_elst(
points: T.Iterable[geo.Point], elst: T.Sequence[T.Tuple[float, float]]
) -> T.Generator[geo.Point, None, None]:
points: T.Iterable[geo.GpsPoint], elst: T.Sequence[T.Tuple[float, float]]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems no need to be GpsPoint here: can cast GpsPoint to Point to use this function.

lat=point.latitude,
lon=point.longitude,
alt=point.elevation,
angle=None,
gps_ground_speed=point.speed,
unix_timestamp=int(time),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need unix_timestamp here as time == unix_timestamp

lon=lon,
alt=alt,
angle=None,
unix_timestamp=int(time),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no need as time == unix_timestamp

gps_precision: T.Optional[float] = None
gps_ground_speed: T.Optional[float] = None
gps_horizontal_accuracy: T.Optional[float] = None
unix_timestamp: T.Optional[int] = None
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using float instead of int looks more consistent as time uses float (although it ended being rounded as video created time)

@ptpt
Copy link
Member

ptpt commented Oct 2, 2023

LGTM.

The only concern is the ground speed added in mapillary_tools/geotag/camm_parser.py. It is used to determine if a GPS point is noisy or not (and noisy points and corresponding frames will be removed). If the velocity values were populated incorrectly, then normal GPS points would be mistakenly removed too. Need to test this change on real CAMM videos.

@facebook-github-bot
Copy link
Contributor

Hi @malconsei!

Thank you for your pull request.

We require contributors to sign our Contributor License Agreement, and yours needs attention.

You currently have a record in our system, but the CLA is no longer valid, and will need to be resubmitted.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at [email protected]. Thanks!

@eneerhut
Copy link
Member

Keeping an eye on this one. It would great to have GPS time set as the default to avoid capture time data issues when the camera resets its clock. This is a common issue on GoPros.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants