From b462048b7eaff224937b0e329774d1a61e65bc28 Mon Sep 17 00:00:00 2001 From: Dominik Winkelbauer Date: Thu, 29 Jul 2021 09:59:26 +0200 Subject: [PATCH] feat(camera): Replaces source_frame with local_frame_change and world_frame_change in CameraInterface --- examples/advanced/stereo_matching/README.md | 2 +- examples/advanced/stereo_matching/config.yaml | 2 +- examples/basics/camera_object_pose/README.md | 2 +- .../basics/camera_object_pose/config.yaml | 2 +- examples/datasets/suncg_basic/README.md | 4 +-- examples/datasets/suncg_basic/config.yaml | 2 +- src/camera/CameraInterface.py | 33 ++++++++++++++----- 7 files changed, 32 insertions(+), 15 deletions(-) diff --git a/examples/advanced/stereo_matching/README.md b/examples/advanced/stereo_matching/README.md index 9300f0b52..b3a29db67 100644 --- a/examples/advanced/stereo_matching/README.md +++ b/examples/advanced/stereo_matching/README.md @@ -68,7 +68,7 @@ Indicate the desired output image resolution globally inside of the settings of "config": { "path": "", "file_format": "location rotation/value _ _ _ _ _ _", - "source_frame": ["X", "-Z", "Y"], + "world_frame_change": ["X", "-Z", "Y"], "default_cam_param": { "rotation": { "format": "forward_vec" diff --git a/examples/advanced/stereo_matching/config.yaml b/examples/advanced/stereo_matching/config.yaml index 7473b317d..f13e98b79 100644 --- a/examples/advanced/stereo_matching/config.yaml +++ b/examples/advanced/stereo_matching/config.yaml @@ -34,7 +34,7 @@ "config": { "path": "", "file_format": "location rotation/value _ _ _ _ _ _", - "source_frame": ["X", "-Z", "Y"], + "world_frame_change": ["X", "-Z", "Y"], "default_cam_param": { "rotation": { "format": "forward_vec" diff --git a/examples/basics/camera_object_pose/README.md b/examples/basics/camera_object_pose/README.md index 0ff059048..9d327fe88 100644 --- a/examples/basics/camera_object_pose/README.md +++ b/examples/basics/camera_object_pose/README.md @@ -82,7 +82,7 @@ The arguments afterwards are used to fill placeholders like `` inside th { "module": "camera.CameraLoader", "config": { - "source_frame": ["X", "-Y", "-Z"], + "local_frame_change": ["X", "-Y", "-Z"], "cam_poses": [ "cam2world_matrix": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] ], diff --git a/examples/basics/camera_object_pose/config.yaml b/examples/basics/camera_object_pose/config.yaml index fce76d821..2259b9a93 100644 --- a/examples/basics/camera_object_pose/config.yaml +++ b/examples/basics/camera_object_pose/config.yaml @@ -58,7 +58,7 @@ { "module": "camera.CameraLoader", "config": { - "source_frame": ["X", "-Y", "-Z"], #OpenCV to Blender coordinates + "local_frame_change": ["X", "-Y", "-Z"], #OpenCV to Blender coordinates "cam_poses": [ "cam2world_matrix": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] ], diff --git a/examples/datasets/suncg_basic/README.md b/examples/datasets/suncg_basic/README.md index bf14c7c03..68464a587 100644 --- a/examples/datasets/suncg_basic/README.md +++ b/examples/datasets/suncg_basic/README.md @@ -74,7 +74,7 @@ The `SuncgLoader` also sets the `category_id` of each object, such that semantic "config": { "path": "", "file_format": "location rotation/value _ _ _ _ _ _", - "source_frame": ["X", "-Z", "Y"], + "world_frame_change": ["X", "-Z", "Y"], "default_cam_param": { "rotation": { "format": "forward_vec" @@ -92,7 +92,7 @@ Here the cam poses from the given file are loaded. This text based file describes one camera pose per line. The `file_format` describes how each line should be parsed (Here we use the format used by files created by `scn2cam`; `_` denotes values which should be skipped). -It's also necessary here to specify a different `source_frame`, as `scn2cam` does not use the same coordinate frame as Blender. +It's also necessary here to specify a different `world_frame_change`, as `scn2cam` does not use the same coordinate frame as Blender. In `default_cam_param` we set parameters which are the same across all cam poses: We change the `rotation/format`. This is necessary as rotations are specified via a forward vector in the camera file. diff --git a/examples/datasets/suncg_basic/config.yaml b/examples/datasets/suncg_basic/config.yaml index 2d97c5a6a..9b11ad952 100644 --- a/examples/datasets/suncg_basic/config.yaml +++ b/examples/datasets/suncg_basic/config.yaml @@ -27,7 +27,7 @@ "config": { "path": "", "file_format": "location rotation/value _ _ _ _ _ _", - "source_frame": ["X", "-Z", "Y"], + "world_frame_change": ["X", "-Z", "Y"], "default_cam_param": { "rotation": { "format": "forward_vec" diff --git a/src/camera/CameraInterface.py b/src/camera/CameraInterface.py index b30da9b38..47d31004f 100644 --- a/src/camera/CameraInterface.py +++ b/src/camera/CameraInterface.py @@ -23,7 +23,7 @@ class CameraInterface(Module): "config": { "path": "", "file_format": "location rotation/value _ _ _ _ _ _", - "source_frame": ["X", "-Z", "Y"], + "world_frame_change": ["X", "-Z", "Y"], "default_cam_param": { "rotation": { "format": "forward_vec" @@ -44,11 +44,18 @@ class CameraInterface(Module): * - Parameter - Description - Type - * - source_frame - - Can be used if the given positions and rotations are specified in frames different from the blender - frame. Has to be a list of three strings. Example: ['X', '-Z', 'Y']: Point (1,2,3) will be transformed + * - world_frame_change + - Can be used if the given camera poses are specified in frames different from the blender + frame. This parameter changes the world coordinate frame of points and matrices. + Has to be a list of three strings. Example: ['X', '-Z', 'Y']: Point (1,2,3) will be transformed to (1, -3, 2). Default: ["X", "Y", "Z"]. " Available: ['X', 'Y', 'Z', '-X', '-Y', '-Z']. - list + * - local_frame_change + - Can be used if the given camera poses are specified in frames different from the blender + frame. This parameter changes the local coordinate frame of matrices. It is currently only + available when setting camera poses via the cam2world_matrix parameter. + Has to be a list of three strings. Default: ["X", "Y", "Z"]. " Available: ['X', 'Y', 'Z', '-X', '-Y', '-Z']. + - list * - cam_poses - A list of dicts, where each dict specifies one cam pose. See the next table for details about specific properties. @@ -168,7 +175,11 @@ class CameraInterface(Module): def __init__(self, config): Module.__init__(self, config) - self.source_frame = self.config.get_list("source_frame", ["X", "Y", "Z"]) + # Raise an exception if the deprecated source_frame parameter is used + if self.config.has_param("source_frame"): + raise Exception("The parameter `source_frame` parameter is not available anymore. Use `local_frame_change` instead, if you are setting camera poses via `cam2world_matrix`, or use `world_frame_change` instead, if you are setting camera poses via `location` and `rotation`.") + self.local_frame_change = self.config.get_list("local_frame_change", ["X", "Y", "Z"]) + self.world_frame_change = self.config.get_list("world_frame_change", ["X", "Y", "Z"]) def _set_cam_intrinsics(self, cam, config): """ Sets camera intrinsics from a source with following priority @@ -262,13 +273,18 @@ def _cam2world_matrix_from_cam_extrinsics(self, config: Config) -> np.ndarray: :return: The 4x4 cam to world transformation matrix. """ if not config.has_param("cam2world_matrix"): - position = MathUtility.change_coordinate_frame_of_point(config.get_vector3d("location", [0, 0, 0]), self.source_frame) + # Print warning if local_frame_change is used with other attributes than cam2world_matrix + if self.local_frame_change != ["X", "Y", "Z"]: + print("Warning: The local_frame_change parameter is at the moment only supported when setting the cam2world_matrix attribute.") + + position = MathUtility.change_coordinate_frame_of_point(config.get_vector3d("location", [0, 0, 0]), self.world_frame_change) # Rotation rotation_format = config.get_string("rotation/format", "euler") value = config.get_vector3d("rotation/value", [0, 0, 0]) # Transform to blender coord frame - value = MathUtility.change_coordinate_frame_of_point(value, self.source_frame) + value = MathUtility.change_coordinate_frame_of_point(value, self.world_frame_change) + if rotation_format == "euler": # Rotation, specified as euler angles rotation_matrix = Euler(value, 'XYZ').to_matrix() @@ -288,5 +304,6 @@ def _cam2world_matrix_from_cam_extrinsics(self, config: Config) -> np.ndarray: cam2world_matrix = MathUtility.build_transformation_mat(position, rotation_matrix) else: cam2world_matrix = np.array(config.get_list("cam2world_matrix")).reshape(4, 4).astype(np.float32) - cam2world_matrix = MathUtility.change_source_coordinate_frame_of_transformation_matrix(cam2world_matrix, self.source_frame) + cam2world_matrix = MathUtility.change_source_coordinate_frame_of_transformation_matrix(cam2world_matrix, self.local_frame_change) + cam2world_matrix = MathUtility.change_target_coordinate_frame_of_transformation_matrix(cam2world_matrix, self.world_frame_change) return cam2world_matrix