feat: add manual ground-plane overlay to visualize_extrinsics.py
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
{"id":"py_workspace-0mu","title":"Implement --render-space in visualize_extrinsics.py","status":"closed","priority":2,"issue_type":"task","owner":"crosstyan@outlook.com","created_at":"2026-02-07T16:08:12.543309499Z","created_by":"crosstyan","updated_at":"2026-02-07T16:08:17.303232927Z","closed_at":"2026-02-07T16:08:17.303232927Z","close_reason":"Implemented --render-space with opencv/opengl choices and updated README"}
|
{"id":"py_workspace-0mu","title":"Implement --render-space in visualize_extrinsics.py","status":"closed","priority":2,"issue_type":"task","owner":"crosstyan@outlook.com","created_at":"2026-02-07T16:08:12.543309499Z","created_by":"crosstyan","updated_at":"2026-02-07T16:08:17.303232927Z","closed_at":"2026-02-07T16:08:17.303232927Z","close_reason":"Implemented --render-space with opencv/opengl choices and updated README"}
|
||||||
{"id":"py_workspace-0q7","title":"Fix basedpyright errors in aruco/pose_averaging.py","status":"closed","priority":2,"issue_type":"task","owner":"crosstyan@outlook.com","created_at":"2026-02-07T08:53:33.377735199Z","created_by":"crosstyan","updated_at":"2026-02-07T08:58:49.252312392Z","closed_at":"2026-02-07T08:58:49.252312392Z","close_reason":"Fixed basedpyright errors"}
|
{"id":"py_workspace-0q7","title":"Fix basedpyright errors in aruco/pose_averaging.py","status":"closed","priority":2,"issue_type":"task","owner":"crosstyan@outlook.com","created_at":"2026-02-07T08:53:33.377735199Z","created_by":"crosstyan","updated_at":"2026-02-07T08:58:49.252312392Z","closed_at":"2026-02-07T08:58:49.252312392Z","close_reason":"Fixed basedpyright errors"}
|
||||||
{"id":"py_workspace-214","title":"Migrate visualize_extrinsics to Plotly with diagnose mode","status":"closed","priority":2,"issue_type":"feature","owner":"crosstyan@outlook.com","created_at":"2026-02-07T15:14:40.547616056Z","created_by":"crosstyan","updated_at":"2026-02-07T15:25:00.354290874Z","closed_at":"2026-02-07T15:25:00.354290874Z","close_reason":"Fixed QA issues: Y-up enforcement, README sync, dependencies"}
|
{"id":"py_workspace-214","title":"Migrate visualize_extrinsics to Plotly with diagnose mode","status":"closed","priority":2,"issue_type":"feature","owner":"crosstyan@outlook.com","created_at":"2026-02-07T15:14:40.547616056Z","created_by":"crosstyan","updated_at":"2026-02-07T15:25:00.354290874Z","closed_at":"2026-02-07T15:25:00.354290874Z","close_reason":"Fixed QA issues: Y-up enforcement, README sync, dependencies"}
|
||||||
|
{"id":"py_workspace-2c1","title":"Add manual ground-plane overlay to visualize_extrinsics.py","status":"open","priority":2,"issue_type":"task","owner":"crosstyan@outlook.com","created_at":"2026-02-07T16:15:17.432846006Z","created_by":"crosstyan","updated_at":"2026-02-07T16:15:17.432846006Z"}
|
||||||
{"id":"py_workspace-62y","title":"Fix depth pooling fallback threshold","status":"closed","priority":2,"issue_type":"task","owner":"crosstyan@outlook.com","created_at":"2026-02-07T08:12:12.046607198Z","created_by":"crosstyan","updated_at":"2026-02-07T08:13:12.98625698Z","closed_at":"2026-02-07T08:13:12.98625698Z","close_reason":"Updated fallback threshold to strict comparison"}
|
{"id":"py_workspace-62y","title":"Fix depth pooling fallback threshold","status":"closed","priority":2,"issue_type":"task","owner":"crosstyan@outlook.com","created_at":"2026-02-07T08:12:12.046607198Z","created_by":"crosstyan","updated_at":"2026-02-07T08:13:12.98625698Z","closed_at":"2026-02-07T08:13:12.98625698Z","close_reason":"Updated fallback threshold to strict comparison"}
|
||||||
{"id":"py_workspace-6m5","title":"Robust Optimizer Implementation","status":"closed","priority":0,"issue_type":"task","owner":"crosstyan@outlook.com","created_at":"2026-02-07T05:22:45.183574374Z","created_by":"crosstyan","updated_at":"2026-02-07T05:22:53.151871639Z","closed_at":"2026-02-07T05:22:53.151871639Z","close_reason":"Implemented robust optimizer with least_squares and soft_l1 loss, updated tests"}
|
{"id":"py_workspace-6m5","title":"Robust Optimizer Implementation","status":"closed","priority":0,"issue_type":"task","owner":"crosstyan@outlook.com","created_at":"2026-02-07T05:22:45.183574374Z","created_by":"crosstyan","updated_at":"2026-02-07T05:22:53.151871639Z","closed_at":"2026-02-07T05:22:53.151871639Z","close_reason":"Implemented robust optimizer with least_squares and soft_l1 loss, updated tests"}
|
||||||
{"id":"py_workspace-6sg","title":"Document marker parquet structure","status":"closed","priority":2,"issue_type":"task","owner":"crosstyan@outlook.com","created_at":"2026-02-07T02:48:08.95742431Z","created_by":"crosstyan","updated_at":"2026-02-07T02:49:35.897152691Z","closed_at":"2026-02-07T02:49:35.897152691Z","close_reason":"Documented parquet structure in aruco/markers/PARQUET_FORMAT.md"}
|
{"id":"py_workspace-6sg","title":"Document marker parquet structure","status":"closed","priority":2,"issue_type":"task","owner":"crosstyan@outlook.com","created_at":"2026-02-07T02:48:08.95742431Z","created_by":"crosstyan","updated_at":"2026-02-07T02:49:35.897152691Z","closed_at":"2026-02-07T02:49:35.897152691Z","close_reason":"Documented parquet structure in aruco/markers/PARQUET_FORMAT.md"}
|
||||||
|
|||||||
@@ -75,6 +75,17 @@ Use `--birdseye` for a top-down X-Z view (looking down Y axis).
|
|||||||
uv run visualize_extrinsics.py -i output/extrinsics.json --birdseye --show
|
uv run visualize_extrinsics.py -i output/extrinsics.json --birdseye --show
|
||||||
```
|
```
|
||||||
|
|
||||||
|
**Ground Plane Overlay:**
|
||||||
|
Render a semi-transparent X-Z ground plane to anchor camera poses.
|
||||||
|
- `--show-ground/--no-show-ground`: Toggle ground plane (default: show).
|
||||||
|
- `--ground-y FLOAT`: Set the Y height of the plane (default: 0.0).
|
||||||
|
- `--ground-size FLOAT`: Set the side length of the plane in meters (default: 8.0).
|
||||||
|
|
||||||
|
*Example: Ground plane at Y=-1.5 with 10m size*
|
||||||
|
```bash
|
||||||
|
uv run visualize_extrinsics.py -i output/extrinsics.json --ground-y -1.5 --ground-size 10 --show
|
||||||
|
```
|
||||||
|
|
||||||
**Using ZED Configs for Accurate Frustums:**
|
**Using ZED Configs for Accurate Frustums:**
|
||||||
Load intrinsics from ZED calibration files to render accurate frustum shapes.
|
Load intrinsics from ZED calibration files to render accurate frustum shapes.
|
||||||
- **Directory**: Matches `SN<serial>.conf` files to camera serials in the JSON.
|
- **Directory**: Matches `SN<serial>.conf` files to camera serials in the JSON.
|
||||||
|
|||||||
@@ -457,6 +457,23 @@ def run_diagnostics(poses: Dict[str, np.ndarray], convention: str):
|
|||||||
is_flag=True,
|
is_flag=True,
|
||||||
help="Run numerical diagnostics on the poses.",
|
help="Run numerical diagnostics on the poses.",
|
||||||
)
|
)
|
||||||
|
@click.option(
|
||||||
|
"--show-ground/--no-show-ground",
|
||||||
|
default=True,
|
||||||
|
help="Show a ground plane at Y=ground-y.",
|
||||||
|
)
|
||||||
|
@click.option(
|
||||||
|
"--ground-y",
|
||||||
|
type=float,
|
||||||
|
default=0.0,
|
||||||
|
help="Y height of the ground plane.",
|
||||||
|
)
|
||||||
|
@click.option(
|
||||||
|
"--ground-size",
|
||||||
|
type=float,
|
||||||
|
default=8.0,
|
||||||
|
help="Size of the ground plane (side length in meters).",
|
||||||
|
)
|
||||||
def main(
|
def main(
|
||||||
input: str,
|
input: str,
|
||||||
output: Optional[str],
|
output: Optional[str],
|
||||||
@@ -471,6 +488,9 @@ def main(
|
|||||||
resolution: str,
|
resolution: str,
|
||||||
eye: str,
|
eye: str,
|
||||||
diagnose: bool,
|
diagnose: bool,
|
||||||
|
show_ground: bool,
|
||||||
|
ground_y: float,
|
||||||
|
ground_size: float,
|
||||||
):
|
):
|
||||||
"""Visualize camera extrinsics from JSON using Plotly."""
|
"""Visualize camera extrinsics from JSON using Plotly."""
|
||||||
try:
|
try:
|
||||||
@@ -526,6 +546,26 @@ def main(
|
|||||||
intrinsics=cam_intrinsics,
|
intrinsics=cam_intrinsics,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
if show_ground:
|
||||||
|
half_size = ground_size / 2.0
|
||||||
|
x_grid = np.linspace(-half_size, half_size, 2)
|
||||||
|
z_grid = np.linspace(-half_size, half_size, 2)
|
||||||
|
x_mesh, z_mesh = np.meshgrid(x_grid, z_grid)
|
||||||
|
y_mesh = np.full_like(x_mesh, ground_y)
|
||||||
|
|
||||||
|
fig.add_trace(
|
||||||
|
go.Surface(
|
||||||
|
x=x_mesh,
|
||||||
|
y=y_mesh,
|
||||||
|
z=z_mesh,
|
||||||
|
showscale=False,
|
||||||
|
opacity=0.15,
|
||||||
|
colorscale=[[0, "gray"], [1, "gray"]],
|
||||||
|
name="Ground Plane",
|
||||||
|
hoverinfo="skip",
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
# Configure layout
|
# Configure layout
|
||||||
scene_dict: Dict[str, Any] = dict(
|
scene_dict: Dict[str, Any] = dict(
|
||||||
xaxis_title="X (m)",
|
xaxis_title="X (m)",
|
||||||
|
|||||||
Reference in New Issue
Block a user