Skip to content

seeding

seeding #

seed and splat_centers — the points a splat's gaussians start from.

A seed is a PointCloud of coloured world points. seed back-projects the frames' pixels: each frame's own captured depth map, or every pixel at one constant distance along its ray when a capture measured none. splat_centers takes the centres of trained splats instead, so a scene's splat starts from its sessions'.

CONSTANT_GRID = (48, 36) module-attribute #

Pixels sampled per frame, across and down, when seeding at a constant distance.

DEPTH_CONFIDENCE = 0.5 module-attribute #

The least confidence a captured depth pixel needs to seed a point.

seed(frames, distance_meters=None) #

The frames' pixels as coloured world points.

Each frame contributes its confident captured depth pixels, evenly thinned to POINTS_PER_FRAME, back-projected through its pose; a frame without depth contributes nothing. With distance_meters every frame instead contributes a grid of pixels cast that far along their rays, for captures that measured no depth at all. The cloud is thinned to MAX_POINTS.

Parameters:

Name Type Description Default
frames Array[PosedImage]

The posed images.

required
distance_meters float | None

A constant distance to seed at instead of measured depth.

None
Source code in capturegraph-lib/capturegraph/recipes/splats/seeding.py
@pure_function("splats.seed/1")
def seed(frames: Array[PosedImage], distance_meters: float | None = None) -> PointCloud:
    """The frames' pixels as coloured world points.

    Each frame contributes its confident captured depth pixels, evenly
    thinned to ``POINTS_PER_FRAME``, back-projected through its pose; a frame
    without depth contributes nothing. With ``distance_meters`` every frame
    instead contributes a grid of pixels cast that far along their rays, for
    captures that measured no depth at all. The cloud is thinned to
    ``MAX_POINTS``.

    Args:
        frames: The posed images.
        distance_meters: A constant distance to seed at instead of measured depth.
    """
    positions: list[np.ndarray] = []
    colors: list[np.ndarray] = []
    with step("Seeding frames", total=len(frames)) as seeding:
        for frame in seeding.track(frames):
            if distance_meters is not None:
                points = _at_distance(frame, distance_meters)
            elif not is_missing(frame.depth):
                points = _from_depth(frame)
            else:
                continue
            positions.append(points[0])
            colors.append(points[1])
    if not positions:
        return PointCloud.of_points(np.zeros((0, 3), np.float32), np.zeros((0, 3), np.uint8))
    return PointCloud.of_points(*_thinned(np.concatenate(positions), np.concatenate(colors)))

splat_centers(splats) #

Every gaussian centre and colour of splats, thinned to MAX_POINTS.

Raises:

Type Description
ValueError

If every splat is missing.

Source code in capturegraph-lib/capturegraph/recipes/splats/seeding.py
@pure_function("splats.splat_centers/1")
def splat_centers(splats: Array[Splat]) -> PointCloud:
    """Every gaussian centre and colour of ``splats``, thinned to ``MAX_POINTS``.

    Raises:
        ValueError: If every splat is missing.
    """
    present = [splat.centers() for splat in splats if not is_missing(splat)]
    if not present:
        raise ValueError("every splat is missing")
    return PointCloud.of_points(
        *_thinned(
            np.concatenate([positions for positions, _ in present]),
            np.concatenate([colors for _, colors in present]),
        )
    )