Beispiel #1
0
    def parse_synth_out(synth_out_ifp):
        points3D = []

        with open(synth_out_ifp, "r") as input_file:
            meta_data_line = input_file.readline()

            num_cameras, num_points = MVEFileHandler.readline_as_numbers(
                input_file, target_type=int)

            # The camera information provided in the synth_0.out file is incomplete
            # Thus, we use the camera information provided in the view folders

            # Consume the lines corresponding to the (incomplete) camera information
            for cam_idx in range(num_cameras):
                intrinsic_line = MVEFileHandler.readline_as_numbers(
                    input_file, target_type=float)
                rotation_mat = MVEFileHandler.parse_rotation_matrix(input_file)
                camera_translation = np.asarray(
                    MVEFileHandler.readline_as_numbers(input_file,
                                                       target_type=float))

            for point_idx in range(num_points):
                coord = MVEFileHandler.readline_as_numbers(input_file,
                                                           target_type=float)
                color = MVEFileHandler.readline_as_numbers(input_file,
                                                           target_type=int)
                measurement_line = MVEFileHandler.readline_as_numbers(
                    input_file, target_type=int)
                point = Point(coord=coord,
                              color=color,
                              id=point_idx,
                              scalars=[])
                points3D.append(point)

        return points3D
    def _parse_points_from_json_data(json_data, image_index_to_camera_index,
                                     op):

        points = []
        is_valid_file = "structure" in json_data

        if not is_valid_file:
            log_report(
                "ERROR",
                "FILE FORMAT ERROR: Incorrect SfM/JSON file. Must contain " +
                " the SfM reconstruction results: structure.",
                op,
            )
            return points

        structure = json_data["structure"]
        for json_point in structure:
            custom_point = Point(
                coord=np.array(json_point["X"], dtype=float),
                color=np.array(json_point["color"], dtype=int),
                id=int(json_point["landmarkId"]),
                scalars=[],
            )
            points.append(custom_point)
        return points
def add_points_as_object_with_particle_system(
    points,
    reconstruction_collection,
    mesh_type="CUBE",
    point_extent=0.01,
    add_particle_color_emission=True,
    particle_overwrite_color=None,
    op=None,
):
    """Add a point cloud as particle system."""
    log_report("INFO", "Adding Points as Particle System: ...", op)
    stop_watch = StopWatch()

    # The particle systems in Blender do not work for large particle numbers
    # (see https://developer.blender.org/T81103). Thus, we represent large
    # point clouds with multiple smaller particle systems.
    max_number_particles = 10000

    particle_system_collection = add_collection("Particle System",
                                                reconstruction_collection)

    point_cloud_obj_list = []
    for i in range(0, len(points), max_number_particles):

        particle_obj_name = f"Particle Shape {i}"
        particle_material_name = f"Point Cloud Material {i}"
        point_cloud_obj_name = f"Particle Point Cloud {i}"

        points_subset = points[i:i + max_number_particles]
        coords, colors = Point.split_points(points_subset,
                                            normalize_colors=True)

        particle_obj = _add_particle_obj(
            colors,
            particle_obj_name,
            particle_material_name,
            particle_overwrite_color,
            add_particle_color_emission,
            mesh_type,
            point_extent,
            particle_system_collection,
        )
        point_cloud_obj = _add_particle_system_obj(
            coords,
            particle_obj,
            point_cloud_obj_name,
            particle_system_collection,
        )
        point_cloud_obj_list.append(point_cloud_obj)

    bpy.context.view_layer.update()

    log_report("INFO", "Duration: " + str(stop_watch.get_elapsed_time()), op)
    log_report("INFO", "Adding Points as Particle System: Done", op)
    return point_cloud_obj_list
    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_points(json_data, op):
     points = []
     json_points = json_data["points"]
     for point_id in json_points:
         json_point = json_points[point_id]
         custom_point = Point(
             coord=np.array(json_point["coordinates"], dtype=float),
             color=np.array(json_point["color"], dtype=int),
             id=point_id,
             scalars=[],
         )
         points.append(custom_point)
     return points
Beispiel #6
0
    def _convert_points(id_to_col_points3D):
        # From photogrammetry_importer\ext\read_write_model.py
        #   Point3D = collections.namedtuple(
        #       "Point3D", ["id", "xyz", "rgb", "error", "image_ids", "point2D_idxs"])

        col_points3D = id_to_col_points3D.values()
        points3D = []
        for col_point3D in col_points3D:
            current_point = Point(
                coord=col_point3D.xyz,
                color=col_point3D.rgb,
                id=col_point3D.id,
                scalars=None,
            )
            points3D.append(current_point)

        return points3D
Beispiel #7
0
    def _parse_nvm_points(input_file, num_3D_points):

        points = []
        for point_index in range(num_3D_points):
            # From the VSFM docs:
            # <Point>  = <XYZ> <RGB> <number of measurements> <List of Measurements>
            point_line = input_file.readline()
            point_line_elements = (point_line.rstrip()).split()
            xyz_vec = list(map(float, point_line_elements[0:3]))
            rgb_vec = list(map(int, point_line_elements[3:6]))
            current_point = Point(coord=xyz_vec,
                                  color=rgb_vec,
                                  id=point_index,
                                  scalars=None)
            points.append(current_point)

        return points
Beispiel #8
0
def draw_points(
    points,
    add_points_to_point_cloud_handle,
    reconstruction_collection=None,
    object_anchor_handle_name="OpenGL Point Cloud",
    op=None,
):
    """Draw points using OpenGL."""
    log_report("INFO", "Add particle draw handlers", op)

    coords, colors = Point.split_points(points, normalize_colors=True)
    object_anchor_handle = _draw_coords_with_color(
        coords,
        colors,
        add_points_to_point_cloud_handle,
        reconstruction_collection,
        object_anchor_handle_name,
        op=op,
    )
    return object_anchor_handle
Beispiel #9
0
def draw_points(
    op,
    points,
    add_points_to_point_cloud_handle,
    reconstruction_collection=None,
    object_anchor_handle_name="OpenGL Point Cloud",
):

    log_report("INFO", "Add particle draw handlers", op)

    coords, colors = Point.split_points(points)
    object_anchor_handle = draw_coords_with_color(
        op,
        coords,
        colors,
        add_points_to_point_cloud_handle,
        reconstruction_collection,
        object_anchor_handle_name,
    )
    return object_anchor_handle
Beispiel #10
0
def add_points_as_mesh_vertices(
    points,
    reconstruction_collection,
    add_color_as_custom_property=True,
    op=None,
):
    """Add a point cloud as mesh."""
    log_report("INFO", "Adding Points as Mesh: ...", op)
    stop_watch = StopWatch()
    point_cloud_obj_name = "Mesh Point Cloud"
    point_cloud_mesh = bpy.data.meshes.new(point_cloud_obj_name)
    point_cloud_mesh.update()
    point_cloud_mesh.validate()
    coords, colors = Point.split_points(points, normalize_colors=False)
    point_cloud_mesh.from_pydata(coords, [], [])
    point_cloud_obj = add_obj(point_cloud_mesh, point_cloud_obj_name,
                              reconstruction_collection)
    if add_color_as_custom_property:
        point_cloud_obj["colors"] = colors

    log_report("INFO", "Duration: " + str(stop_watch.get_elapsed_time()), op)
    log_report("INFO", "Adding Points as Mesh: Done", op)
    return point_cloud_obj
    def parse_point_data_file(ifp, op):
        log_report("INFO", "Parse Point Data File: ...")
        # https://pyntcloud.readthedocs.io/en/latest/io.html
        # https://www.cloudcompare.org/doc/wiki/index.php?title=FILE_I/O
        module_spec = importlib.util.find_spec("pyntcloud")
        if module_spec is None:
            log_report(
                "ERROR",
                "Importing this file type requires the pyntcloud library.",
                op,
            )
            assert False
        from pyntcloud import PyntCloud

        assert os.path.isfile(ifp)
        ext = os.path.splitext(ifp)[1].lower()
        if ext in [".asc", ".pts"]:
            sep = " "
            data_semantics = (
                PointDataFileHandler.get_data_semantics_from_ascii(
                    ifp, sep, has_header=True))
            names = PointDataFileHandler.convert_data_semantics_to_list(
                data_semantics)
            point_cloud = PyntCloud.from_file(ifp,
                                              sep=sep,
                                              header=0,
                                              names=names)
            pseudo_color = data_semantics.pseudo_color
        elif ext == ".csv":
            sep = ","
            data_semantics = (
                PointDataFileHandler.get_data_semantics_from_ascii(
                    ifp, sep, has_header=False))
            names = PointDataFileHandler.convert_data_semantics_to_list(
                data_semantics)
            point_cloud = PyntCloud.from_file(ifp,
                                              sep=sep,
                                              header=0,
                                              names=names)
            pseudo_color = data_semantics.pseudo_color
        else:
            pseudo_color = False
            point_cloud = PyntCloud.from_file(ifp)
        xyz_arr = point_cloud.points.loc[:, ["x", "y", "z"]].to_numpy()
        if set(["red", "green", "blue"]).issubset(point_cloud.points.columns):
            color_arr = point_cloud.points.loc[:, ["red", "green", "blue"
                                                   ]].to_numpy()
            if pseudo_color:
                color_arr *= 255
        else:
            color_arr = np.ones_like(xyz_arr) * 255
        num_points = xyz_arr.shape[0]
        points = []
        for idx in range(num_points):
            point = Point(
                coord=xyz_arr[idx].astype("float64"),
                color=color_arr[idx].astype("int"),
                id=idx,
                scalars=dict(),
            )
            points.append(point)
        log_report("INFO", f"Number Points {len(points)}")
        log_report("INFO", "Parse Point Data File: Done")
        return points
    def __ply_data_vertices_to_vetex_list(ply_data):

        vertex_data_type_names = ply_data["vertex"].data.dtype.names
        use_color = False
        if (
            "red" in vertex_data_type_names
            and "green" in vertex_data_type_names
            and "blue" in vertex_data_type_names
        ):
            use_color = True

        vertices = []
        value_keys = [
            x
            for x, y in sorted(
                ply_data["vertex"].data.dtype.fields.items(),
                key=lambda k: k[1],
            )
        ]
        non_scalar_value_keys = [
            "x",
            "y",
            "z",
            "red",
            "green",
            "blue",
            "nx",
            "ny",
            "nz",
            "measurements",
        ]
        scalar_value_keys = [
            value_key
            for value_key in value_keys
            if not value_key in non_scalar_value_keys
        ]
        log_report(
            "INFO", "Found the following vertex properties: " + str(value_keys)
        )

        # scalar_value_keys = [value_key for (value_key, some_value) in ]
        # logger.info(scalar_value_keys)

        log_report(
            "INFO", "Found " + str(len(ply_data["vertex"].data)) + " vertices"
        )
        for point_index, line in enumerate(ply_data["vertex"].data):
            coord = np.array([line["x"], line["y"], line["z"]])
            if use_color:
                color = np.array([line["red"], line["green"], line["blue"]])
            else:
                color = np.array([255, 255, 255])
            scalars = dict()
            for scalar_value_key in scalar_value_keys:
                scalars[scalar_value_key] = line[scalar_value_key]

            current_point = Point(
                coord=coord, color=color, id=point_index, scalars=None
            )
            vertices.append(current_point)

        ply_data_vertex_dtype = ply_data["vertex"].dtype
        ply_data_vertex_data_dtype = ply_data["vertex"].data.dtype

        return vertices, ply_data_vertex_dtype, ply_data_vertex_data_dtype
 def write_ply_file_from_vertex_mat(output_path_to_file, vertex_mat):
     vertices = []
     for entry in vertex_mat:
         vertices.append(Point(coord=entry))
     PLYFileHandler.write_ply_file(output_path_to_file, vertices)
    def parse_points(json_data, op, view_index_to_absolute_fp=None):

        compute_color = True
        try:
            from PIL import Image, ImageFile

            ImageFile.LOAD_TRUNCATED_IMAGES = True
        except ImportError:
            log_report(
                "WARNING",
                "Can not compute point cloud color information, since Pillow is not installed.",
                op,
            )
            compute_color = False

        if view_index_to_absolute_fp is None:
            log_report(
                "WARNING",
                "Can not compute point cloud color information, since path to images is not correctly set.",
                op,
            )
            compute_color = False

        if compute_color:
            log_report(
                "INFO",
                "Try to collect color information from files (this might take a while)",
                op,
            )
            view_index_to_image = {}
            for view_index, absolute_fp in view_index_to_absolute_fp.items():
                if os.path.isfile(absolute_fp):
                    pil_image = Image.open(absolute_fp)
                    view_index_to_image[view_index] = pil_image
                else:
                    log_report(
                        "WARNING",
                        "Can not compute point cloud color information, since image file path is incorrect.",
                        op,
                    )
                    compute_color = False
                    break

        if compute_color:
            log_report(
                "INFO",
                "Compute color information from files (this might take a while)",
                op,
            )

        points = []
        structure = json_data["structure"]
        for json_point in structure:

            r = g = b = 0

            # color information can only be computed if input files are provided
            if compute_color:
                for observation in json_point["value"]["observations"]:
                    view_index = int(observation["key"])

                    # REMARK: The order of ndarray.shape (first height, then width) is complimentary to
                    # pils image.size (first width, then height).
                    # That means
                    # height, width = segmentation_as_matrix.shape
                    # width, height = image.size

                    # Therefore: x_in_openmvg_file == x_image == y_ndarray
                    # and y_in_openmvg_file == y_image == x_ndarray
                    x_in_json_file = float(
                        observation["value"]["x"][0])  # x has index 0
                    y_in_json_file = float(
                        observation["value"]["x"][1])  # y has index 1

                    current_image = view_index_to_image[view_index]
                    current_r, current_g, current_b = current_image.getpixel(
                        (x_in_json_file, y_in_json_file))
                    r += current_r
                    g += current_g
                    b += current_b

                # normalize the rgb values
                amount_observations = len(json_point["value"]["observations"])
                r /= amount_observations
                g /= amount_observations
                b /= amount_observations

            custom_point = Point(
                coord=np.array(json_point["value"]["X"], dtype=float),
                color=np.array([r, g, b], dtype=int),
                id=int(json_point["key"]),
                scalars=[],
            )

            points.append(custom_point)
        return points