Skip to content

viewpoint

viewpoint #

Angular separation between two cameras' optical axes.

Measures the angle between two cameras' optical axes (their forward directions), recovered from each Pose quaternion. Used to spread captures across viewing directions — the spatial-coverage signal a 3D/4D reconstruction needs, so every selected session looks at the subject from a meaningfully different angle.

ViewpointDistanceFunction #

Bases: BatchedDistanceFunction[Pose]

Angle between two poses' optical axes, normalized by sigma_deg.

Source code in capturegraph-lib/capturegraph/scheduling/distance/viewpoint.py
class ViewpointDistanceFunction(BatchedDistanceFunction[cg.Pose]):
    """Angle between two poses' optical axes, normalized by ``sigma_deg``."""

    def __init__(self, sigma_deg: float = 1.0) -> None:
        """Normalize the optical-axis angle by ``sigma_deg``."""
        self.sigma_deg = sigma_deg

    def __call__(self, a: cg.Pose, b: cg.Pose) -> float:
        """Angle between two poses' optical axes, normalized."""
        axes = _forward_axes(np.vstack([_stack(a), _stack(b)]))
        return float(_angle_deg(axes[:1], axes[1:])[0, 0]) / self.sigma_deg

    def extract(self, items: cg.Array[Any]) -> np.ndarray:
        """Extract each pose's forward optical axis as a three-column feature array."""
        quaternions = np.column_stack(
            [
                np.array(items.quaternion_w, dtype=np.float64),
                np.array(items.quaternion_x, dtype=np.float64),
                np.array(items.quaternion_y, dtype=np.float64),
                np.array(items.quaternion_z, dtype=np.float64),
            ]
        )
        return _forward_axes(quaternions)

    def pairwise(self, features_a: np.ndarray, features_b: np.ndarray) -> np.ndarray:
        """Compute pairwise optical-axis angles from extracted pose features."""
        return _angle_deg(features_a, features_b) / self.sigma_deg

__call__(a, b) #

Angle between two poses' optical axes, normalized.

Source code in capturegraph-lib/capturegraph/scheduling/distance/viewpoint.py
def __call__(self, a: cg.Pose, b: cg.Pose) -> float:
    """Angle between two poses' optical axes, normalized."""
    axes = _forward_axes(np.vstack([_stack(a), _stack(b)]))
    return float(_angle_deg(axes[:1], axes[1:])[0, 0]) / self.sigma_deg

__init__(sigma_deg=1.0) #

Normalize the optical-axis angle by sigma_deg.

Source code in capturegraph-lib/capturegraph/scheduling/distance/viewpoint.py
def __init__(self, sigma_deg: float = 1.0) -> None:
    """Normalize the optical-axis angle by ``sigma_deg``."""
    self.sigma_deg = sigma_deg

extract(items) #

Extract each pose's forward optical axis as a three-column feature array.

Source code in capturegraph-lib/capturegraph/scheduling/distance/viewpoint.py
def extract(self, items: cg.Array[Any]) -> np.ndarray:
    """Extract each pose's forward optical axis as a three-column feature array."""
    quaternions = np.column_stack(
        [
            np.array(items.quaternion_w, dtype=np.float64),
            np.array(items.quaternion_x, dtype=np.float64),
            np.array(items.quaternion_y, dtype=np.float64),
            np.array(items.quaternion_z, dtype=np.float64),
        ]
    )
    return _forward_axes(quaternions)

pairwise(features_a, features_b) #

Compute pairwise optical-axis angles from extracted pose features.

Source code in capturegraph-lib/capturegraph/scheduling/distance/viewpoint.py
def pairwise(self, features_a: np.ndarray, features_b: np.ndarray) -> np.ndarray:
    """Compute pairwise optical-axis angles from extracted pose features."""
    return _angle_deg(features_a, features_b) / self.sigma_deg

viewpoint(sigma_deg=1.0) #

Create a distance function based on camera optical-axis separation.

Recovers each pose's forward direction from its quaternion and measures the angle between them, so Void & Cluster selection spreads captures across viewing directions.

Parameters:

Name Type Description Default
sigma_deg float

Normalization factor in degrees. The returned distance is angle_deg / sigma_deg, so poses within sigma_deg of each other have distance < 1.0.

1.0

Returns:

Type Description
ViewpointDistanceFunction

A distance function with batch support: (pose_a, pose_b) -> float.

Source code in capturegraph-lib/capturegraph/scheduling/distance/viewpoint.py
def viewpoint(sigma_deg: float = 1.0) -> ViewpointDistanceFunction:
    """Create a distance function based on camera optical-axis separation.

    Recovers each pose's forward direction from its quaternion and measures the
    angle between them, so Void & Cluster selection spreads captures across
    viewing directions.

    Args:
        sigma_deg: Normalization factor in degrees. The returned distance is
            `angle_deg / sigma_deg`, so poses within sigma_deg of each other have
            distance < 1.0.

    Returns:
        A distance function with batch support: `(pose_a, pose_b) -> float`.
    """
    return ViewpointDistanceFunction(sigma_deg)