Ejemplo n.º 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 _parse_open3d_log_file(open3d_ifp, image_dp, image_relative_fp_list, image_fp_type, op):
        cams = []
        with open(open3d_ifp, 'r') as open3d_file:

            lines = open3d_file.readlines()
            # Chunk size: 1 line meta data, 4 lines for the matrix
            chunk_size = 5
            assert len(lines) % chunk_size == 0
            chunks = Open3DFileHandler._chunker(lines, chunk_size)

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

            for chunk, image_relative_fp in zip(chunks, image_relative_fp_list):
                meta_data = chunk[0]
        
                matrix_list = [
                    Open3DFileHandler._read_matrix_row(chunk[1]),
                    Open3DFileHandler._read_matrix_row(chunk[2]),
                    Open3DFileHandler._read_matrix_row(chunk[3])]

                # Note: the transformation matrix in the .json file is the inverse of 
                #       the transformation matrix in the .log file 
                extrinsic_matrix = np.asarray(matrix_list, dtype=float)

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

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

                cams.append(cam)
        return cams
    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
    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:
            op.report({
                'ERROR'
            }, 'FILE FORMAT ERROR: Incorrect SfM/JSON file. Must contain the SfM reconstruction results: '
                      + 'view, intrinsics and poses.')
            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 = get_element(views, "poseId", view_index, op)

            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 = get_element(intrinsics, "intrinsicId",
                                           id_intrinsic, op)

            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
Ejemplo n.º 5
0
    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']}

        # 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_data = intrinsics[int(
                    id_intrinsic)]['value']['ptr_wrapper']['data']
                polymorphic_name = intrinsics[int(
                    id_intrinsic)]['value']['polymorphic_name']

                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