Example #1
0
    def parse_cameras(
        json_data, image_dp, image_fp_type, suppress_distortion_warnings, op
    ):

        json_cameras_intrinsics = json_data["cameras"]
        views = json_data["shots"]

        cams = []
        for view_name in views:
            view = views[view_name]

            camera = Camera()
            camera.image_fp_type = image_fp_type
            camera.image_dp = image_dp
            camera._relative_fp = view_name
            camera._absolute_fp = os.path.join(image_dp, view_name)

            intrinsic_key = view["camera"]

            (
                focal_length,
                cx,
                cy,
                width,
                height,
                radial_distortion,
            ) = OpenSfMJSONFileHandler.convert_intrinsics(
                json_cameras_intrinsics[intrinsic_key],
                camera._relative_fp,
                suppress_distortion_warnings,
                op,
            )

            camera.height = height
            camera.width = width

            camera_calibration_matrix = np.array(
                [[focal_length, 0, cx], [0, focal_length, cy], [0, 0, 1]]
            )

            camera.set_calibration(
                camera_calibration_matrix, radial_distortion
            )

            rodrigues_vec = np.array(view["rotation"], dtype=float)
            rot_mat = OpenSfMJSONFileHandler.rodrigues_to_matrix(rodrigues_vec)

            camera.set_rotation_mat(rot_mat)
            camera.set_camera_translation_vector_after_rotation(
                np.array(view["translation"], dtype=float)
            )

            cams.append(camera)
        return cams
    def get_selected_cameras_and_vertices_of_meshes(self, odp):
        """Get selected cameras and vertices."""
        log_report("INFO", "get_selected_cameras_and_vertices_of_meshes: ...",
                   self)
        cameras = []
        points = []

        point_index = 0
        camera_index = 0
        for obj in bpy.context.selected_objects:
            if obj.type == "CAMERA":
                obj_name = str(obj.name).replace(" ", "_")
                log_report("INFO", "obj_name: " + obj_name, self)
                calibration_mat = self._get_calibration_mat(obj)
                # log_report('INFO', 'calibration_mat:', self)
                # log_report('INFO', str(calibration_mat), self)

                camera_matrix_computer_vision = (
                    self._get_computer_vision_camera_matrix(obj))

                cam = Camera()
                cam.id = camera_index
                cam.set_relative_fp(obj_name, Camera.IMAGE_FP_TYPE_NAME)
                cam.image_dp = odp
                cam.width = bpy.context.scene.render.resolution_x
                cam.height = bpy.context.scene.render.resolution_y

                cam.set_calibration(calibration_mat, radial_distortion=0)
                cam.set_4x4_cam_to_world_mat(camera_matrix_computer_vision)
                cameras.append(cam)
                camera_index += 1

            else:
                if obj.data is not None:
                    obj_points = []
                    for vert in obj.data.vertices:
                        coord_world = obj.matrix_world @ vert.co
                        obj_points.append(
                            Point(
                                coord=coord_world,
                                color=[0, 255, 0],
                                id=point_index,
                                scalars=[],
                            ))

                        point_index += 1
                    points += obj_points
        log_report(
            "INFO",
            "get_selected_cameras_and_vertices_of_meshes: Done",
            self,
        )
        return cameras, points
    def _parse_open3d_json_file(open3d_ifp, image_dp, image_relative_fp_list,
                                image_fp_type, op):
        cams = []

        with open(open3d_ifp, "r") as open3d_file:
            json_data = json.load(open3d_file)
            parameters = json_data["parameters"]

            if len(parameters) != len(image_relative_fp_list):
                # Create some dummy names for missing images
                image_relative_fp_list = (
                    Open3DFileHandler._create_dummy_fp_list(len(parameters)))

            for pinhole_camera_parameter, image_relative_fp in zip(
                    parameters, image_relative_fp_list):

                cam = Camera()
                cam.image_fp_type = image_fp_type
                cam.image_dp = image_dp
                cam._relative_fp = image_relative_fp
                cam._absolute_fp = os.path.join(image_dp, image_relative_fp)

                extrinsic = pinhole_camera_parameter["extrinsic"]
                # Note: the transformation matrix in the .json file is the inverse of
                #       the transformation matrix in the .log file
                extrinsic_mat = np.linalg.inv(
                    np.array(extrinsic, dtype=float).reshape((4, 4)).T)

                intrinsic = pinhole_camera_parameter["intrinsic"]

                cam.width = intrinsic["width"]
                cam.height = intrinsic["height"]

                # Accuracy of rotation matrices is too low => disable test
                cam.set_4x4_cam_to_world_mat(extrinsic_mat,
                                             check_rotation=False)

                intrinsic = intrinsic["intrinsic_matrix"]
                intrinsic_mat = (np.array(intrinsic, dtype=float).reshape(
                    (3, 3)).T)
                cam.set_calibration_mat(intrinsic_mat)

                cams.append(cam)
        return cams
Example #4
0
    def parse_meta(meta_ifp, width, height, camera_name, op):

        view_specific_dir = os.path.dirname(meta_ifp)
        relative_image_fp = os.path.join(view_specific_dir, "undistorted.png")
        image_dp = os.path.dirname(view_specific_dir)

        camera = Camera()
        camera.image_fp_type = Camera.IMAGE_FP_TYPE_RELATIVE
        camera.image_dp = image_dp
        camera._relative_fp = relative_image_fp
        camera._absolute_fp = os.path.join(image_dp, relative_image_fp)
        camera.width = width
        camera.height = height

        ini_config = configparser.RawConfigParser()
        ini_config.read(meta_ifp)
        focal_length_normalized = float(
            ini_config.get(section="camera", option="focal_length"))
        pixel_aspect = float(
            ini_config.get(section="camera", option="pixel_aspect"))
        if pixel_aspect != 1.0:
            log_report(
                "WARNING",
                "Focal length differs in x and y direction," +
                " setting it to the average value.",
                op,
            )
            focal_length_normalized = (
                focal_length_normalized +
                focal_length_normalized * pixel_aspect) / 2

        max_extend = max(width, height)
        focal_length = focal_length_normalized * max_extend

        principal_point_str = ini_config.get(section="camera",
                                             option="principal_point")
        principal_point_list = MVEFileHandler.str_to_arr(principal_point_str,
                                                         target_type=float)
        cx_normalized = principal_point_list[0]
        cy_normalized = principal_point_list[1]
        cx = cx_normalized * width
        cy = cy_normalized * height

        calib_mat = Camera.compute_calibration_mat(focal_length, cx, cy)
        camera.set_calibration_mat(calib_mat)

        radial_distortion_str = ini_config.get(section="camera",
                                               option="radial_distortion")
        radial_distortion_vec = np.asarray(
            MVEFileHandler.str_to_arr(radial_distortion_str,
                                      target_type=float))
        check_radial_distortion(radial_distortion_vec, relative_image_fp, op)

        rotation_str = ini_config.get(section="camera", option="rotation")
        rotation_mat = np.asarray(
            MVEFileHandler.str_to_arr(rotation_str,
                                      target_type=float)).reshape((3, 3))

        translation_str = ini_config.get(section="camera",
                                         option="translation")
        translation_vec = np.asarray(
            MVEFileHandler.str_to_arr(translation_str, target_type=float))

        camera.set_rotation_mat(rotation_mat)
        camera.set_camera_translation_vector_after_rotation(translation_vec)
        return camera
    def _parse_cameras_from_json_data(json_data, image_dp, image_fp_type,
                                      suppress_distortion_warnings, op):

        cams = []
        image_index_to_camera_index = {}

        is_valid_file = ("views" in json_data and "intrinsics" in json_data
                         and "poses" in json_data)

        if not is_valid_file:
            log_report(
                "ERROR",
                "FILE FORMAT ERROR: Incorrect SfM/JSON file. Must contain the"
                + " SfM reconstruction results: view, intrinsics and poses.",
                op,
            )
            return cams, image_index_to_camera_index

        views = json_data["views"]  # is a list of dicts (view)
        intrinsics = json_data["intrinsics"]  # is a list of dicts (intrinsic)
        extrinsics = json_data["poses"]  # is a list of dicts (extrinsic)

        # IMPORTANT:
        # Views contain the number of input images
        # Extrinsics may contain only a subset of views!
        # (Not all views are necessarily contained in the reconstruction)

        for rec_index, extrinsic in enumerate(extrinsics):

            camera = Camera()
            view_index = int(extrinsic["poseId"])
            image_index_to_camera_index[view_index] = rec_index

            corresponding_view = MeshroomFileHandler._get_element(
                views, "poseId", view_index)

            camera.image_fp_type = image_fp_type
            camera.image_dp = image_dp
            camera._absolute_fp = str(corresponding_view["path"])
            camera._relative_fp = os.path.basename(
                str(corresponding_view["path"]))
            camera._undistorted_relative_fp = str(extrinsic["poseId"]) + ".exr"
            if image_dp is None:
                camera._undistorted_absolute_fp = None
            else:
                camera._undistorted_absolute_fp = os.path.join(
                    image_dp, camera._undistorted_relative_fp)

            camera.width = int(corresponding_view["width"])
            camera.height = int(corresponding_view["height"])
            id_intrinsic = int(corresponding_view["intrinsicId"])

            intrinsic_params = MeshroomFileHandler._get_element(
                intrinsics, "intrinsicId", id_intrinsic)

            focal_length = float(intrinsic_params["pxFocalLength"])
            cx = float(intrinsic_params["principalPoint"][0])
            cy = float(intrinsic_params["principalPoint"][1])

            if ("distortionParams" in intrinsic_params
                    and len(intrinsic_params["distortionParams"]) > 0):
                # TODO proper handling of distortion parameters
                radial_distortion = float(
                    intrinsic_params["distortionParams"][0])
            else:
                radial_distortion = 0.0

            if not suppress_distortion_warnings:
                check_radial_distortion(radial_distortion, camera._relative_fp,
                                        op)

            camera_calibration_matrix = np.array([[focal_length, 0, cx],
                                                  [0, focal_length, cy],
                                                  [0, 0, 1]])

            camera.set_calibration(camera_calibration_matrix,
                                   radial_distortion)
            extrinsic_params = extrinsic["pose"]["transform"]

            cam_rotation_list = extrinsic_params["rotation"]
            camera.set_rotation_mat(
                np.array(cam_rotation_list, dtype=float).reshape(3, 3).T)
            camera.set_camera_center_after_rotation(
                np.array(extrinsic_params["center"], dtype=float))
            camera.view_index = view_index

            cams.append(camera)
        return cams, image_index_to_camera_index
Example #6
0
    def _convert_cameras(
        id_to_col_cameras,
        id_to_col_images,
        image_dp,
        image_fp_type,
        depth_map_idp=None,
        suppress_distortion_warnings=False,
        op=None,
    ):
        # From photogrammetry_importer\ext\read_write_model.py
        #   CameraModel = collections.namedtuple(
        #       "CameraModel", ["model_id", "model_name", "num_params"])
        #   Camera = collections.namedtuple(
        #       "Camera", ["id", "model", "width", "height", "params"])
        #   BaseImage = collections.namedtuple(
        #       "Image", ["id", "qvec", "tvec", "camera_id", "name", "xys", "point3D_ids"])

        cameras = []
        for col_image in id_to_col_images.values():
            current_camera = Camera()
            current_camera.id = col_image.id
            current_camera.set_rotation_with_quaternion(col_image.qvec)
            current_camera.set_camera_translation_vector_after_rotation(
                col_image.tvec)

            current_camera.image_fp_type = image_fp_type
            current_camera.image_dp = image_dp
            current_camera._relative_fp = col_image.name

            # log_report('INFO', 'image_dp: ' + str(image_dp))
            # log_report('INFO', 'col_image.name: ' + str(col_image.name))

            camera_model = id_to_col_cameras[col_image.camera_id]

            # log_report('INFO', 'image_id: ' + str(col_image.id))
            # log_report('INFO', 'camera_id: ' + str(col_image.camera_id))
            # log_report('INFO', 'camera_model: ' + str(camera_model))

            current_camera.width = camera_model.width
            current_camera.height = camera_model.height

            (
                fx,
                fy,
                cx,
                cy,
                skew,
                r,
            ) = ColmapFileHandler._parse_camera_param_list(camera_model, )
            if not suppress_distortion_warnings:
                check_radial_distortion(r, current_camera._relative_fp, op)

            camera_calibration_matrix = np.array([[fx, skew, cx], [0, fy, cy],
                                                  [0, 0, 1]])
            current_camera.set_calibration(camera_calibration_matrix,
                                           radial_distortion=0)

            if depth_map_idp is not None:
                geometric_ifp = os.path.join(depth_map_idp,
                                             col_image.name + ".geometric.bin")
                photometric_ifp = os.path.join(
                    depth_map_idp, col_image.name + ".photometric.bin")
                if os.path.isfile(geometric_ifp):
                    depth_map_ifp = geometric_ifp
                elif os.path.isfile(photometric_ifp):
                    depth_map_ifp = photometric_ifp
                else:
                    depth_map_ifp = None
                current_camera.set_depth_map_callback(
                    read_array,
                    depth_map_ifp,
                    Camera.DEPTH_MAP_WRT_CANONICAL_VECTORS,
                    shift_depth_map_to_pixel_center=False,
                )
            cameras.append(current_camera)
        return cameras
    def parse_cameras(json_data, image_dp, image_fp_type,
                      suppress_distortion_warnings, op):

        views = {item["key"]: item for item in json_data["views"]}
        intrinsics = {item["key"]: item for item in json_data["intrinsics"]}
        extrinsics = {item["key"]: item for item in json_data["extrinsics"]}

        # Regard 3D stores the polymorhic attribute in the first intrinsic
        default_polymorphic_name = (
            OpenMVGJSONFileHandler.get_default_polymorphic_name(intrinsics))

        # IMPORTANT:
        # Views contain the description about the dataset and attribute to Pose and Intrinsic data.
        # View -> id_pose, id_intrinsic
        # Since sometimes some views cannot be localized, there is some missing pose and intrinsic data.
        # Extrinsics may contain only a subset of views! (Potentially not all views are contained in the reconstruction)

        cams = []
        # Iterate over views, and create camera if Intrinsic and Pose data exist
        for id, view in views.items():  # Iterate over views

            id_view = view[
                "key"]  # Should be equal to view['value']['ptr_wrapper']['data']['id_view']
            view_data = view["value"]["ptr_wrapper"]["data"]
            id_pose = view_data["id_pose"]
            id_intrinsic = view_data["id_intrinsic"]

            # Check if the view is having corresponding Pose and Intrinsic data
            if (id_pose in extrinsics.keys()
                    and id_intrinsic in intrinsics.keys()):

                camera = Camera()

                camera.image_fp_type = image_fp_type
                camera.image_dp = image_dp
                camera._relative_fp = os.path.join(view_data["local_path"],
                                                   view_data["filename"])
                camera._absolute_fp = os.path.join(
                    json_data["root_path"],
                    view_data["local_path"],
                    view_data["filename"],
                )
                camera.width = view_data["width"]
                camera.height = view_data["height"]
                id_intrinsic = view_data["id_intrinsic"]

                # handle intrinsic params
                intrinsic_values = intrinsics[int(id_intrinsic)]["value"]
                intrinsic_data = intrinsic_values["ptr_wrapper"]["data"]

                if "polymorphic_name" in intrinsic_values:
                    polymorphic_name = intrinsic_values["polymorphic_name"]
                else:
                    polymorphic_name = default_polymorphic_name
                    log_report(
                        "WARNING",
                        "Key polymorphic_name in intrinsic with id " +
                        str(id_intrinsic) +
                        " is missing, substituting with polymorphic_name of first intrinsic.",
                        op,
                    )

                if polymorphic_name == "spherical":
                    camera.set_panoramic_type(
                        Camera.panoramic_type_equirectangular)
                    # create some dummy values
                    focal_length = 0
                    cx = camera.width / 2
                    cy = camera.height / 2
                else:

                    focal_length = intrinsic_data["focal_length"]
                    principal_point = intrinsic_data["principal_point"]
                    cx = principal_point[0]
                    cy = principal_point[1]

                # For Radial there are several options: "None", disto_k1, disto_k3
                if "disto_k3" in intrinsic_data:
                    radial_distortion = [
                        float(intrinsic_data["disto_k3"][0]),
                        float(intrinsic_data["disto_k3"][1]),
                        float(intrinsic_data["disto_k3"][2]),
                    ]
                elif "disto_k1" in intrinsic_data:
                    radial_distortion = float(intrinsic_data["disto_k1"][0])
                else:  # No radial distortion, i.e. pinhole camera model
                    radial_distortion = 0

                if not suppress_distortion_warnings:
                    check_radial_distortion(radial_distortion,
                                            camera._relative_fp, op)

                camera_calibration_matrix = np.array([[focal_length, 0, cx],
                                                      [0, focal_length, cy],
                                                      [0, 0, 1]])

                camera.set_calibration(camera_calibration_matrix,
                                       radial_distortion)
                extrinsic_params = extrinsics[id_pose]
                cam_rotation_list = extrinsic_params["value"]["rotation"]
                camera.set_rotation_mat(
                    np.array(cam_rotation_list, dtype=float))
                camera.set_camera_center_after_rotation(
                    np.array(extrinsic_params["value"]["center"], dtype=float))
                camera.view_index = id_view

                cams.append(camera)
        return cams
Example #8
0
    def _parse_cameras(
        json_data,
        image_dp,
        image_fp_type,
        suppress_distortion_warnings,
        op=None,
    ):

        # For each input image there exists an entry in "views". In contrast,
        # "extrinsics" contains only information of registered images (i.e.
        # reconstructed camera poses) and may contain only information for a
        # subset of images.
        views = {item["key"]: item for item in json_data["views"]}
        intrinsics = {item["key"]: item for item in json_data["intrinsics"]}
        extrinsics = {item["key"]: item for item in json_data["extrinsics"]}

        # Regard 3D stores the polymorhic attribute in the first intrinsic
        default_polymorphic_name = (
            OpenMVGJSONFileHandler._get_default_polymorphic_name(intrinsics))

        cams = []
        # Iterate over views and create a camera if intrinsic and extrinsic
        # parameters exist
        for id, view in views.items():  # Iterate over views

            id_view = view["key"]
            # view["value"]["ptr_wrapper"]["data"] should be equal to
            # view["value"]["ptr_wrapper"]["data"]["id_view"]
            view_data = view["value"]["ptr_wrapper"]["data"]
            id_pose = view_data["id_pose"]
            id_intrinsic = view_data["id_intrinsic"]

            # Check if the view is having corresponding Pose and Intrinsic data
            if (id_pose in extrinsics.keys()
                    and id_intrinsic in intrinsics.keys()):

                camera = Camera()

                camera.image_fp_type = image_fp_type
                camera.image_dp = image_dp
                camera._relative_fp = os.path.join(view_data["local_path"],
                                                   view_data["filename"])
                camera._absolute_fp = os.path.join(
                    json_data["root_path"],
                    view_data["local_path"],
                    view_data["filename"],
                )
                camera.width = view_data["width"]
                camera.height = view_data["height"]
                id_intrinsic = view_data["id_intrinsic"]

                # Handle intrinsic params
                intrinsic_values = intrinsics[int(id_intrinsic)]["value"]
                intrinsic_data = intrinsic_values["ptr_wrapper"]["data"]

                if "polymorphic_name" in intrinsic_values:
                    polymorphic_name = intrinsic_values["polymorphic_name"]
                else:
                    polymorphic_name = default_polymorphic_name
                    log_report(
                        "WARNING",
                        "Key polymorphic_name in intrinsic with id " +
                        str(id_intrinsic) +
                        " is missing, substituting with polymorphic_name of" +
                        " first intrinsic.",
                        op,
                    )

                if polymorphic_name == "spherical":
                    camera.set_panoramic_type(
                        Camera.panoramic_type_equirectangular)
                    # create some dummy values
                    focal_length = 0
                    cx = camera.width / 2
                    cy = camera.height / 2
                else:

                    focal_length = intrinsic_data["focal_length"]
                    principal_point = intrinsic_data["principal_point"]
                    cx = principal_point[0]
                    cy = principal_point[1]

                # For Radial there are several options:
                # "None", disto_k1, disto_k3
                if "disto_k3" in intrinsic_data:
                    radial_distortion = [
                        float(intrinsic_data["disto_k3"][0]),
                        float(intrinsic_data["disto_k3"][1]),
                        float(intrinsic_data["disto_k3"][2]),
                    ]
                elif "disto_k1" in intrinsic_data:
                    radial_distortion = float(intrinsic_data["disto_k1"][0])
                else:  # No radial distortion, i.e. pinhole camera model
                    radial_distortion = 0

                if not suppress_distortion_warnings:
                    check_radial_distortion(radial_distortion,
                                            camera._relative_fp, op)

                camera_calibration_matrix = np.array([[focal_length, 0, cx],
                                                      [0, focal_length, cy],
                                                      [0, 0, 1]])

                camera.set_calibration(camera_calibration_matrix,
                                       radial_distortion)
                extrinsic_params = extrinsics[id_pose]
                cam_rotation_list = extrinsic_params["value"]["rotation"]
                camera.set_rotation_with_rotation_mat(
                    np.array(cam_rotation_list, dtype=float))
                camera.set_camera_center_after_rotation(
                    np.array(extrinsic_params["value"]["center"], dtype=float))
                camera.view_index = id_view

                cams.append(camera)
        return cams