shuishen
21 hours ago 8f75db57f3055b2a3575c86ee3e6acf1dd56ce47
capabilities/05-3d-pointcloud/apply_pointcloud_semantic_model.py
@@ -102,6 +102,25 @@
    return model, codes, classes
def write_prediction_preview(path: Path, xyz: np.ndarray, predictions: np.ndarray, class_schema: dict[int, dict[str, Any]]) -> None:
    """Write display RGB plus stable LAS-compatible labels for the review viewer."""
    colors = np.asarray([class_schema[int(code)]["color"] for code in predictions], dtype=np.uint8)
    records = np.empty(len(xyz), dtype=[("x", "<f4"), ("y", "<f4"), ("z", "<f4"), ("red", "u1"), ("green", "u1"), ("blue", "u1"), ("classification", "u1")])
    records["x"], records["y"], records["z"] = xyz[:, 0], xyz[:, 1], xyz[:, 2]
    records["red"], records["green"], records["blue"] = colors[:, 0], colors[:, 1], colors[:, 2]
    records["classification"] = predictions
    header = (
        "ply\nformat binary_little_endian 1.0\n"
        f"element vertex {len(records)}\n"
        "property float x\nproperty float y\nproperty float z\n"
        "property uchar red\nproperty uchar green\nproperty uchar blue\n"
        "property uchar classification\nend_header\n"
    ).encode("ascii")
    with path.open("wb") as stream:
        stream.write(header)
        records.tofile(stream)
def main() -> int:
    parser = argparse.ArgumentParser(description="Apply a local point-cloud semantic model to a new RGB point cloud.")
    parser.add_argument("--model", type=Path, required=True)
@@ -146,12 +165,8 @@
    args.output.mkdir(parents=True, exist_ok=True)
    preview_selection = np.arange(len(predictions), dtype=np.int64)
    preview = o3d.geometry.PointCloud()
    preview.points = o3d.utility.Vector3dVector(xyz[preview_selection])
    preview.colors = o3d.utility.Vector3dVector(np.asarray([class_schema[int(code)]["color"] for code in predictions[preview_selection]], dtype=np.float64) / 255.0)
    preview_path = args.output / "predicted-semantic-preview.ply"
    if not o3d.io.write_point_cloud(str(preview_path), preview, write_ascii=False):
        raise RuntimeError("Could not write predicted PLY preview.")
    write_prediction_preview(preview_path, xyz[preview_selection], predictions[preview_selection], class_schema)
    classified_las = args.output / "predicted-semantic-classified.las"
    if source_las is not None: