-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'main' into change-internal-dependency-listing
- Loading branch information
Showing
34 changed files
with
458 additions
and
293 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
## Describe your changes | ||
|
||
|
||
## Checklist | ||
- [ ] Have you modified the changelog? | ||
- [ ] If you made changes to the hardware interfaces, have you tested them using the manual tests? |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
from airo_camera_toolkit.cameras.realsense.realsense import Realsense # noqa: F401 | ||
from airo_camera_toolkit.cameras.zed.zed2i import Zed2i # noqa: F401 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
Empty file.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
airo-camera-toolkit/airo_camera_toolkit/pinhole_operations/Readme.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
# Pinhole Operations | ||
|
||
This subpackage contains code to perform various geometric operations to convert between 3D positions and 2D image coordinates using the pinhole camera model. | ||
|
||
Most notably these include: | ||
|
||
- projection to go from 3D points to 2D image coordinates | ||
- triangulation to go from a set of corresponding image coordinates to a 3D point | ||
- unprojection to go from a 2D coordinate to a 3D point by intersecting the ray with depth information | ||
|
||
|
||
For mathematical background, see: | ||
|
||
- IRM course | ||
- Sleziski, [Computer Vision and Algorithms](https://szeliski.org/Book/) | ||
- Opencv page on [cameras](https://docs.opencv.org/4.x/d9/d0c/group__calib3d.html#) |
7 changes: 7 additions & 0 deletions
7
airo-camera-toolkit/airo_camera_toolkit/pinhole_operations/__init__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
from .projection import project_points_to_image_plane # noqa F401 | ||
from .triangulation import calculate_triangulation_errors, multiview_triangulation_midpoint # noqa F401 | ||
from .unprojection import ( # noqa F401 | ||
extract_depth_from_depthmap_heuristic, | ||
unproject_onto_depth_values, | ||
unproject_using_depthmap, | ||
) |
28 changes: 28 additions & 0 deletions
28
airo-camera-toolkit/airo_camera_toolkit/pinhole_operations/projection.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
from typing import Union | ||
|
||
from airo_spatial_algebra.operations import _HomogeneousPoints | ||
from airo_typing import CameraIntrinsicsMatrixType, Vector2DArrayType, Vector3DArrayType, Vector3DType | ||
|
||
|
||
def project_points_to_image_plane( | ||
positions_in_camera_frame: Union[Vector3DArrayType, Vector3DType], | ||
camera_intrinsics: CameraIntrinsicsMatrixType, | ||
) -> Vector2DArrayType: | ||
"""Projects an array of points from the 3D camera frame to their 2D pixel coordinates on the image plane. | ||
Make sure to transform them to the camera frame first if they are in the world frame. | ||
Args: | ||
positions_in_camera_frame: numpy array of shape (N, 3) containing the 3D positions of the points in the camera frame | ||
camera_intrinsics: camera intrinsics matrix as a numpy array of shape (3, 3) | ||
Returns: | ||
numpy array of shape (N, 2) containing the 2D pixel coordinates of the points on the image plane | ||
""" | ||
|
||
homogeneous_positions_in_camera_frame = _HomogeneousPoints(positions_in_camera_frame).homogeneous_points.T | ||
homogeneous_positions_on_image_plane = camera_intrinsics @ homogeneous_positions_in_camera_frame[:3, ...] | ||
positions_on_image_plane = ( | ||
homogeneous_positions_on_image_plane[:2, ...] / homogeneous_positions_on_image_plane[2, ...] | ||
) | ||
return positions_on_image_plane.T |
80 changes: 80 additions & 0 deletions
80
airo-camera-toolkit/airo_camera_toolkit/pinhole_operations/triangulation.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
from typing import List | ||
|
||
import numpy as np | ||
from airo_typing import CameraExtrinsicMatrixType, CameraIntrinsicsMatrixType, Vector2DArrayType, Vector3DType | ||
|
||
|
||
def multiview_triangulation_midpoint( | ||
extrinsics_matrices: List[CameraExtrinsicMatrixType], | ||
intrinsics_matrices: List[CameraIntrinsicsMatrixType], | ||
image_coordinates: Vector2DArrayType, | ||
) -> Vector3DType: | ||
"""triangulates a point from multiple views using the midpoint method. | ||
This method minimizes the L2 distance in the camera space between the estimated point and all rays | ||
cf. https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8967077 | ||
Args: | ||
extrinsics_matrices: list of extrinsics matrices for each viewpoint | ||
intrinsics_matrices: list of intrinsics matrices for each viewpoint | ||
image_points: list of image coordinates of the 3D point for each viewpoint | ||
Returns: | ||
estimated 3D position in the world frame as a numpy array of shape (3,). | ||
""" | ||
|
||
# determine the rays for each camera in the world frame | ||
rays = [] | ||
for extrinsics_matrix, intrinsics_matrix, image_point in zip( | ||
extrinsics_matrices, intrinsics_matrices, image_coordinates | ||
): | ||
ray = ( | ||
extrinsics_matrix[:3, :3] | ||
@ np.linalg.inv(intrinsics_matrix) | ||
@ np.array([image_point[0], image_point[1], 1]) | ||
) | ||
ray = ray / np.linalg.norm(ray) | ||
rays.append(ray) | ||
|
||
lhs = 0 | ||
rhs = 0 | ||
for i, ray in enumerate(rays): | ||
rhs += (np.eye(3) - ray[:, np.newaxis] @ ray[np.newaxis, :]) @ extrinsics_matrices[i][:3, 3] | ||
lhs += np.eye(3) - ray[:, np.newaxis] @ ray[np.newaxis, :] | ||
|
||
lhs_inv = np.linalg.inv(lhs) | ||
midpoint = lhs_inv @ rhs | ||
return midpoint | ||
|
||
|
||
def calculate_triangulation_errors( | ||
extrinsics_matrices: List[CameraExtrinsicMatrixType], | ||
intrinsics_matrices: List[CameraIntrinsicsMatrixType], | ||
image_coordinates: Vector2DArrayType, | ||
point: Vector3DType, | ||
) -> List[float]: | ||
"""calculates the Euclidean distances in the camera space between the estimated point and all rays, as a measure of triangulation error | ||
Args: | ||
extrinsics_matrices: list of extrinsics matrices for each viewpoint | ||
intrinsics_matrices: list of intrinsics matrices for each viewpoint | ||
image_points: list of image coordinates of the 3D point for each viewpoint | ||
point: 3D point in the world frame | ||
Returns: | ||
list of Euclidean distances between the point and the rays for each viewpoint | ||
""" | ||
errors = [] | ||
for extrinsics_matrix, intrinsics_matrix, image_point in zip( | ||
extrinsics_matrices, intrinsics_matrices, image_coordinates | ||
): | ||
ray = ( | ||
extrinsics_matrix[:3, :3] | ||
@ np.linalg.inv(intrinsics_matrix) | ||
@ np.array([image_point[0], image_point[1], 1]) | ||
) | ||
ray = ray / np.linalg.norm(ray) | ||
error = np.linalg.norm( | ||
(np.eye(3) - ray[:, np.newaxis] @ ray[np.newaxis, :]) @ ((extrinsics_matrix[:3, 3]) - point) | ||
) | ||
errors.append(error.item()) | ||
return errors |
Oops, something went wrong.