Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 26 additions & 11 deletions aevascenes/aevascenes.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@

import cv2
import numpy as np
import rerun as rr
from PIL import Image
from tqdm import tqdm

Expand All @@ -21,7 +20,6 @@

import aevascenes.configs as configs
from aevascenes import utils
from aevascenes.visualizer import RRVisualizer


class AevaScenes:
Expand All @@ -42,7 +40,7 @@ def __init__(self, dataroot: str) -> None:
dataroot: Path to the root directory of the AevaScenes dataset
"""
self.dataroot = dataroot
self.rr_visualizer = RRVisualizer()
Copy link
Collaborator

Choose a reason for hiding this comment

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

While taking out rerun from the initializer is probably a good idea. Where does RRVisualizer get initialized though in this PR?

self.rr_visualizer = None
metadata_path = os.path.join(self.dataroot, "metadata.json")
if os.path.exists(metadata_path):
self.metadata = utils.read_file(metadata_path)
Expand Down Expand Up @@ -211,7 +209,13 @@ def visualize_frame(
semantic_labels=semantic_labels,
)

pcds.append({"lidar_id": lidar_id, "pcd": rr.Points3D(xyz, colors=colors, labels=labels)})
pcd_data = {"lidar_id": lidar_id, "xyz": xyz, "colors": colors, "labels": labels}
try:
import rerun as rr
pcd_data["pcd"] = rr.Points3D(xyz, colors=colors, labels=labels)
except ImportError:
pass
pcds.append(pcd_data)

# Load camera metadata
camera_ids = sequence_metadata["sensors"]["cameras"]
Expand Down Expand Up @@ -268,16 +272,25 @@ def visualize_frame(
),
interpolation=cv2.INTER_LINEAR,
)
images.append({"camera_id": camera_id, "image": rr.Image(undistorted_image_resized)})
img_data = {"camera_id": camera_id, "image_np": undistorted_image_resized}
try:
import rerun as rr
img_data["image"] = rr.Image(undistorted_image_resized)
except ImportError:
pass
images.append(img_data)

# Load object detection boxes
boxes_serialized = frame["boxes"]
boxes = utils.deserialize_boxes(boxes_serialized)
boxes_rr = utils.convert_boxes_to_rr(boxes, color_map=configs.class_color_map)
arrows_rr = utils.convert_box_velocity_arrows_rr(boxes)

# Send to rerun visualizer
self.rr_visualizer.add_data(pcds=pcds, images=images, boxes=boxes_rr, arrows=arrows_rr)
# Send to rerun visualizer (if available)
if self.rr_visualizer is not None:
boxes_rr = utils.convert_boxes_to_rr(boxes, color_map=configs.class_color_map)
arrows_rr = utils.convert_box_velocity_arrows_rr(boxes)
self.rr_visualizer.add_data(pcds=pcds, images=images, boxes=boxes_rr, arrows=arrows_rr)

return {"pcds": pcds, "images": images, "boxes": boxes}

def visualize_sampled_frames_from_dataset(
self, pcd_color_mode: str = "velocity", project_points_on_image: bool = False, image_downsample_factor: int = 1
Expand All @@ -303,7 +316,8 @@ def visualize_sampled_frames_from_dataset(

sampled_frame_id = random.randint(0, len(frames) - 1)

self.rr_visualizer.set_frame_counter(frame_idx=sequence_idx)
if self.rr_visualizer is not None:
self.rr_visualizer.set_frame_counter(frame_idx=sequence_idx)
self.visualize_frame(
frames[sampled_frame_id],
sequence_data["metadata"],
Expand Down Expand Up @@ -332,7 +346,8 @@ def visualize_sequence(
frames = sequence_data["frames"]

for frame_idx in tqdm(range(len(frames)), desc="Visualizing frames"):
self.rr_visualizer.set_frame_counter(frame_idx=frame_idx, timestamp_ns=frames[frame_idx]["timestamp_ns"])
if self.rr_visualizer is not None:
self.rr_visualizer.set_frame_counter(frame_idx=frame_idx, timestamp_ns=frames[frame_idx]["timestamp_ns"])
self.visualize_frame(
frames[frame_idx],
sequence_data["metadata"],
Expand Down
21 changes: 21 additions & 0 deletions aevascenes/configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,24 @@
"sidewalk": [85, 0, 100], # purple
"other_ground": [150, 100, 0], # brown
}

# ── Semantic class groupings ─────────────────────────────────────────

ground_classes = {
"road", "lane_boundary", "road_marking", "reflective_marker",
"sidewalk", "other_ground",
}

lane_classes = {
"lane_boundary", "road_marking", "reflective_marker",
}

vehicle_classes = {
"car", "bus", "truck", "trailer", "vehicle_on_rails", "other_vehicle",
}

dynamic_classes = {
"car", "bus", "truck", "trailer", "vehicle_on_rails", "other_vehicle",
"bicycle", "motorcycle", "motorcyclist", "bicyclist",
"pedestrian", "animal",
}
11 changes: 7 additions & 4 deletions aevascenes/utils/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import rerun as rr
import transformations as tf
import yaml
from rerun.datatypes import Quaternion
from scipy.spatial.transform import Rotation as scipy_rot

from aevascenes.utils import colormaps
Expand Down Expand Up @@ -260,7 +258,7 @@ def deserialize_boxes(boxes: List[Dict[str, Any]]) -> List[Dict[str, Any]]:
return boxes


def convert_boxes_to_rr(boxes: List[Dict[str, Any]], color_map: Optional[Dict[str, List[int]]] = None) -> rr.Boxes3D:
def convert_boxes_to_rr(boxes: List[Dict[str, Any]], color_map: Optional[Dict[str, List[int]]] = None):
"""
Convert bounding boxes to Rerun Boxes3D format for 3D visualization.
Transforms a list of bounding boxes in AevaScenes format to a Rerun Boxes3D
Expand All @@ -280,6 +278,9 @@ def convert_boxes_to_rr(boxes: List[Dict[str, Any]], color_map: Optional[Dict[st
Returns:
Rerun Boxes3D object configured for visualization
"""
import rerun as rr
from rerun.datatypes import Quaternion

boxes_rr = {}
boxes_rr["half_sizes"] = np.array([box["dimensions"] / 2 for box in boxes])
boxes_rr["centers"] = np.array([box["center"] for box in boxes])
Expand All @@ -305,7 +306,7 @@ def convert_boxes_to_rr(boxes: List[Dict[str, Any]], color_map: Optional[Dict[st

def convert_box_velocity_arrows_rr(
boxes: List[Dict[str, Any]], color_map: Optional[Dict[str, List[int]]] = None
) -> rr.Arrows3D:
):
"""
Convert bounding box velocity data to Rerun Arrows3D format for motion visualization.
Creates 3D arrow vectors representing the linear velocity of bounding boxes,
Expand All @@ -324,6 +325,8 @@ def convert_box_velocity_arrows_rr(
Returns:
Rerun Arrows3D object configured for velocity visualization with:
"""
import rerun as rr

arrows_rr = {}
arrows_rr["centers"] = np.array([box["center"] for box in boxes])

Expand Down
5 changes: 4 additions & 1 deletion aevascenes/visualizer/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,7 @@
# The AevaScenes dataset is licensed separately under the AevaScenes Dataset License.
# See https://scenes.aeva.com/license for the full license text.

from .visualizer import RRVisualizer
try:
from .visualizer import RRVisualizer
except ImportError:
RRVisualizer = None
9 changes: 4 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ description = "AevaScenes Python SDK"
authors = [{name = "Aeva, Inc", email = "research@aeva.ai"}]
license = {file = "LICENSE-CODE"}
readme = "README.md"
requires-python = ">=3.10"
requires-python = ">=3.8"
dependencies = [
"tqdm",
"numpy",
Expand All @@ -17,7 +17,6 @@ dependencies = [
"pillow",
"scipy",
"opencv-python",
"rerun-sdk==0.24.1",
"rich",
]
keywords = ["aeva", "aevascenes", "lidar", "fmcw", "sdk"]
Expand All @@ -35,12 +34,12 @@ classifiers = [
"Topic :: Software Development :: Libraries",
]

[tool.setuptools]
packages = ["aevascenes"]
[tool.setuptools.packages.find]
where = ["."]

[tool.black]
line-length = 120
target-version = ["py310"]
target-version = ["py38"]

[tool.isort]
profile = "black"
Expand Down