feat: Implement time-weighted triangulation for enhanced 3D point reconstruction

- Added two new functions: `triangulate_one_point_from_multiple_views_linear_time_weighted` and `triangulate_points_from_multiple_views_linear_time_weighted` to perform triangulation with time-based weighting, improving accuracy in 3D point estimation.
- Introduced a method to group detections by camera while preserving the latest detection, enhancing tracking state management.
- Updated the `update_tracking` function to incorporate time-weighted triangulation, allowing for more robust updates to tracking states based on new detections.
- Refactored the `TrackingState` to utilize a mapping of historical detections by camera, improving data organization and access.
This commit is contained in:
2025-05-03 17:17:47 +08:00
parent 20b2cf59f2
commit 1f8d70803f
2 changed files with 249 additions and 15 deletions

View File

@ -13,9 +13,9 @@ from typing import (
TypeAlias,
TypedDict,
TypeVar,
Union,
cast,
overload,
Union,
)
import jax.numpy as jnp
@ -23,9 +23,11 @@ from beartype import beartype
from beartype.typing import Mapping, Sequence
from jax import Array
from jaxtyping import Array, Float, Int, jaxtyped
from pyrsistent import PVector, v
from pyrsistent import PVector, v, PRecord, PMap
from app.camera import Detection
from app.camera import Detection, CameraID
TrackingID: TypeAlias = int
class TrackingPrediction(TypedDict):
@ -440,7 +442,7 @@ class TrackingState:
The last active timestamp of the tracking
"""
historical_detections: PVector[Detection]
historical_detections_by_camera: PMap[CameraID, Detection]
"""
Historical detections of the tracking.
@ -449,13 +451,13 @@ class TrackingState:
class Tracking:
id: int
id: TrackingID
state: TrackingState
velocity_filter: GenericVelocityFilter
def __init__(
self,
id: int,
id: TrackingID,
state: TrackingState,
velocity_filter: Optional[GenericVelocityFilter] = None,
):
@ -512,6 +514,15 @@ class Tracking:
# pylint: disable-next=unsubscriptable-object
return self.velocity_filter.predict(timestamp)["keypoints"]
def update(self, new_3d_pose: Float[Array, "J 3"], timestamp: datetime) -> None:
"""
update the tracking with a new 3D pose
Note:
equivalent to call `velocity_filter.update(new_3d_pose, timestamp)`
"""
self.velocity_filter.update(new_3d_pose, timestamp)
@property
def velocity(self) -> Float[Array, "J 3"]:
"""
@ -537,7 +548,7 @@ class AffinityResult:
indices_T: Int[Array, "T"] # pylint: disable=invalid-name
indices_D: Int[Array, "D"] # pylint: disable=invalid-name
def tracking_detections(
def tracking_association(
self,
) -> Generator[tuple[float, Tracking, Detection], None, None]:
"""