abreza commited on
Commit
c78bea2
·
verified ·
1 Parent(s): b443e2a

Update visualization/logger.py

Browse files
Files changed (1) hide show
  1. visualization/logger.py +82 -86
visualization/logger.py CHANGED
@@ -4,20 +4,28 @@ from typing import Dict, Any, List
4
  from utils.geometry import vector3_to_numpy, euler_to_quaternion
5
 
6
 
7
- def create_subject_box(frame: Dict, dimensions: Dict) -> Dict[str, np.ndarray]:
 
 
 
 
8
  position = vector3_to_numpy(frame['position'])
9
- size = np.array([dimensions['width'], dimensions['height'], dimensions['depth']])
 
 
 
 
10
 
11
  return {
12
  'center': position,
13
- 'half_size': size / 2
14
  }
15
 
16
 
17
  class SimulationLogger:
18
  def __init__(self):
19
  rr.init("camera_simulation")
20
- rr.log("world", rr.ViewCoordinates.RIGHT_HAND_Y_UP)
21
 
22
  self.K = np.array([
23
  [500, 0, 960],
@@ -29,52 +37,72 @@ class SimulationLogger:
29
  if not instructions:
30
  return
31
 
32
- rr.log("metadata/instructions", rr.TextDocument(
33
- "\n".join([
34
- f"Instruction {i+1}:\n" +
35
- f" Movement: {inst.get('cameraMovement', 'N/A')}\n" +
36
- f" Easing: {inst.get('movementEasing', 'N/A')}\n" +
37
- f" Frames: {inst.get('frameCount', 'N/A')}\n" +
38
- f" Camera Angle: {inst.get('initialCameraAngle', 'N/A')}\n" +
39
- f" Shot Type: {inst.get('initialShotType', 'N/A')}\n" +
40
- f" Subject Index: {inst.get('subjectIndex', 'N/A')}"
41
- for i, inst in enumerate(instructions)
42
- ])
43
- ))
 
 
 
 
44
 
45
- def log_subjects(self, subjects: List[Dict[str, Any]], frame_idx: int = 0) -> None:
 
 
 
 
 
46
  if not subjects:
47
  return
48
 
49
- centers = []
50
- half_sizes = []
51
- colors = []
52
- labels = []
 
53
 
54
- for subject in subjects:
55
- try:
56
- # Use the frame at frame_idx, or the first frame if frame_idx is out of range
57
- frame = subject['frames'][min(frame_idx, len(subject['frames']) - 1)]
58
- box_params = create_subject_box(frame, subject['dimensions'])
59
- centers.append(box_params['center'])
60
- half_sizes.append(box_params['half_size'])
61
- colors.append([0.8, 0.2, 0.2, 1.0])
62
- labels.append(subject.get('objectClass', 'Unknown'))
63
- except Exception as e:
64
- print(f"Error creating box parameters: {str(e)}")
65
- continue
66
 
67
- if centers:
68
- rr.log(
69
- "world/subjects",
70
- rr.Boxes3D(
71
- centers=np.array(centers),
72
- half_sizes=np.array(half_sizes),
73
- colors=np.array(colors),
74
- show_labels=False,
75
- fill_mode="solid"
76
- )
77
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
 
79
  def log_camera_trajectory(self, camera_frames: List[Dict[str, Any]]) -> None:
80
  if not camera_frames:
@@ -88,36 +116,29 @@ class SimulationLogger:
88
  "world/camera_trajectory",
89
  rr.Points3D(
90
  camera_positions,
91
- colors=np.full((len(camera_positions), 4),
92
- [0.0, 0.8, 0.8, 1.0])
93
- )
94
  )
95
 
96
  if len(camera_positions) > 1:
97
- lines = np.stack(
98
- [camera_positions[:-1], camera_positions[1:]], axis=1)
99
  rr.log(
100
  "world/camera_trajectory/line",
101
  rr.LineStrips3D(
102
  lines,
103
  colors=[(0.0, 0.8, 0.8, 1.0)]
104
- )
 
105
  )
106
 
107
  except Exception as e:
108
  print(f"Error logging camera trajectory: {str(e)}")
109
 
110
- def log_camera_frames(self, camera_frames: List[Dict[str, Any]], subjects: List[Dict[str, Any]] = None) -> None:
111
- """Log camera frames and optionally their corresponding subjects"""
112
- if subjects is None:
113
- subjects = []
114
  if not camera_frames:
115
  return
116
 
117
- # First log the camera trajectory
118
- self.log_camera_trajectory(camera_frames)
119
-
120
- # Then log each frame with its corresponding subject positions
121
  for frame_idx, camera_frame in enumerate(camera_frames):
122
  try:
123
  rr.set_time_sequence("frame_idx", frame_idx)
@@ -142,9 +163,6 @@ class SimulationLogger:
142
  )
143
  )
144
 
145
- # Log subjects for this frame
146
- self.log_subjects(subjects, frame_idx)
147
-
148
  except Exception as e:
149
  print(f"Error logging camera frame {frame_idx}: {str(e)}")
150
 
@@ -161,32 +179,10 @@ class SimulationLogger:
161
  helper_positions,
162
  radii=np.full(len(helper_positions), 0.03),
163
  colors=np.full((len(helper_positions), 4), [1.0, 1.0, 0.0, 1.0]),
164
- )
 
165
  )
166
 
167
  for keyframe_idx, helper_keyframe in enumerate(helper_keyframes):
168
  try:
169
- position = vector3_to_numpy(helper_keyframe['position'])
170
- rotation_q = euler_to_quaternion(helper_keyframe['angle'])
171
-
172
- rr.log(
173
- f"world/helper_camera_{keyframe_idx}",
174
- rr.Transform3D(
175
- translation=position,
176
- rotation=rr.Quaternion(xyzw=rotation_q),
177
- scale=(.5, .5, .5)
178
- )
179
- )
180
-
181
- rr.log(
182
- f"world/helper_camera_{keyframe_idx}/image",
183
- rr.Pinhole(
184
- image_from_camera=self.K,
185
- width=1920,
186
- height=1080,
187
- )
188
- )
189
-
190
- except Exception as e:
191
- print(
192
- f"Error logging helper keyframe {keyframe_idx}: {str(e)}")
 
4
  from utils.geometry import vector3_to_numpy, euler_to_quaternion
5
 
6
 
7
+ def create_subject_box(frame: Dict[str, Any], dimensions: Dict[str, float]) -> Dict[str, np.ndarray]:
8
+ """
9
+ Given a single frame (position, rotation) and subject's dimensions,
10
+ return the center and half_size for a box representation.
11
+ """
12
  position = vector3_to_numpy(frame['position'])
13
+ half_size = np.array([
14
+ dimensions['width'] / 2.0,
15
+ dimensions['height'] / 2.0,
16
+ dimensions['depth'] / 2.0
17
+ ], dtype=np.float32)
18
 
19
  return {
20
  'center': position,
21
+ 'half_size': half_size
22
  }
23
 
24
 
25
  class SimulationLogger:
26
  def __init__(self):
27
  rr.init("camera_simulation")
28
+ rr.log("world", rr.ViewCoordinates.RIGHT_HAND_Y_UP, timeless=True)
29
 
30
  self.K = np.array([
31
  [500, 0, 960],
 
37
  if not instructions:
38
  return
39
 
40
+ rr.log(
41
+ "metadata/instructions",
42
+ rr.TextDocument(
43
+ "\n".join([
44
+ f"Instruction {i+1}:\n"
45
+ f" Movement: {inst.get('cameraMovement', 'N/A')}\n"
46
+ f" Easing: {inst.get('movementEasing', 'N/A')}\n"
47
+ f" Frames: {inst.get('frameCount', 'N/A')}\n"
48
+ f" Camera Angle: {inst.get('initialCameraAngle', 'N/A')}\n"
49
+ f" Shot Type: {inst.get('initialShotType', 'N/A')}\n"
50
+ f" Subject Index: {inst.get('subjectIndex', 'N/A')}"
51
+ for i, inst in enumerate(instructions)
52
+ ])
53
+ ),
54
+ timeless=True
55
+ )
56
 
57
+ def log_subjects(self, subjects: List[Dict[str, Any]]) -> None:
58
+ """
59
+ Updated to handle dynamic subjects:
60
+ - Each subject has multiple frames (position, rotation).
61
+ - Subject dimensions (width, height, depth) remain constant across frames.
62
+ """
63
  if not subjects:
64
  return
65
 
66
+ # For each subject, log each frame at a different time index.
67
+ for subject_idx, subject in enumerate(subjects):
68
+ dimensions = subject.get("dimensions", {})
69
+ frames = subject.get("frames", [])
70
+ label = subject.get('objectClass', f"Subject_{subject_idx}")
71
 
72
+ for frame_idx, frame in enumerate(frames):
73
+ rr.set_time_sequence("frame_idx", frame_idx)
 
 
 
 
 
 
 
 
 
 
74
 
75
+ try:
76
+ box_params = create_subject_box(frame, dimensions)
77
+ center = box_params['center']
78
+ half_size = box_params['half_size']
79
+
80
+ # Convert Euler angles to quaternion for rotation
81
+ rotation_q = euler_to_quaternion(frame['rotation'])
82
+
83
+ # 1) Log a transform for the subject so the box is placed at 'center' with correct rotation
84
+ rr.log(
85
+ f"world/subjects/subject_{subject_idx}",
86
+ rr.Transform3D(
87
+ translation=center,
88
+ rotation=rr.Quaternion(xyzw=rotation_q)
89
+ )
90
+ )
91
+
92
+ # 2) Log a box at the origin of the subject's local transform
93
+ rr.log(
94
+ f"world/subjects/subject_{subject_idx}/box",
95
+ rr.Boxes3D(
96
+ centers=np.array([[0.0, 0.0, 0.0]], dtype=np.float32),
97
+ half_sizes=np.array([half_size], dtype=np.float32),
98
+ colors=np.array([[0.8, 0.2, 0.2, 1.0]], dtype=np.float32),
99
+ labels=[label],
100
+ show_labels=False,
101
+ fill_mode="solid"
102
+ )
103
+ )
104
+ except Exception as e:
105
+ print(f"Error creating box parameters for subject {subject_idx}, frame {frame_idx}: {str(e)}")
106
 
107
  def log_camera_trajectory(self, camera_frames: List[Dict[str, Any]]) -> None:
108
  if not camera_frames:
 
116
  "world/camera_trajectory",
117
  rr.Points3D(
118
  camera_positions,
119
+ colors=np.full((len(camera_positions), 4), [0.0, 0.8, 0.8, 1.0])
120
+ ),
121
+ timeless=True
122
  )
123
 
124
  if len(camera_positions) > 1:
125
+ lines = np.stack([camera_positions[:-1], camera_positions[1:]], axis=1)
 
126
  rr.log(
127
  "world/camera_trajectory/line",
128
  rr.LineStrips3D(
129
  lines,
130
  colors=[(0.0, 0.8, 0.8, 1.0)]
131
+ ),
132
+ timeless=True
133
  )
134
 
135
  except Exception as e:
136
  print(f"Error logging camera trajectory: {str(e)}")
137
 
138
+ def log_camera_frames(self, camera_frames: List[Dict[str, Any]]) -> None:
 
 
 
139
  if not camera_frames:
140
  return
141
 
 
 
 
 
142
  for frame_idx, camera_frame in enumerate(camera_frames):
143
  try:
144
  rr.set_time_sequence("frame_idx", frame_idx)
 
163
  )
164
  )
165
 
 
 
 
166
  except Exception as e:
167
  print(f"Error logging camera frame {frame_idx}: {str(e)}")
168
 
 
179
  helper_positions,
180
  radii=np.full(len(helper_positions), 0.03),
181
  colors=np.full((len(helper_positions), 4), [1.0, 1.0, 0.0, 1.0]),
182
+ ),
183
+ timeless=True
184
  )
185
 
186
  for keyframe_idx, helper_keyframe in enumerate(helper_keyframes):
187
  try:
188
+