py4dgeo

repository·main·Indexed 40 days ago

https://github.com/3dgeo-heidelberg/py4dgeo

A C++ library with Python bindings for 3D/4D change analysis in multitemporal point clouds. Version 1.2.0 provides scientific methods for topographic change quantification, registration, and surface activity extraction, including the M3C2 algorithm, M3C2-EP, 4D objects-by-change (4D-OBC), and automatic stable area registration.

Tokens
30.1K
Snippets
93
Records
117
Agent score
99%

What's inside py4dgeo

  1. Overview of py4dgeo methods

    main

    The py4dgeo library provides several methods for 3D/4D change analysis in multitemporal point clouds:

    • M3C2 algorithm: Bitemporal point cloud distance computation.
    • M3C2-EP: Statistical signal-noise separation through error propagation.
    • 4D objects-by-change (4D-OBC): Time series-based extraction of surface activities.
    • Correspondence-driven plane-based M3C2: Lower uncertainty in 3D topographic change quantification (under active development).
    • Standard ICP registration: Calculating and applying affine transformations using standard ICP implementations.
    • Automatic stable area registration: Point cloud registration with automatic determination of stable areas for multitemporal change detection.
    • Hierarchical 3D surface change analysis: Near real-time analysis for permanent laser scanning point clouds.
  2. How py4dgeo's callback architecture works

    main

    py4dgeo uses a callback software architecture to allow users to flexibly change components of the core algorithm without sacrificing performance.

    Callbacks can be implemented in two ways:

    1. Python: Ideal for rapid prototyping and ease of use.
    2. C++: Recommended for production environments where high performance is required.

    By providing custom implementations for specific callback types, you can modify how distances are calculated or how the algorithm selects points for processing.

  3. Prerequisites for py4dgeo

    main

    To use py4dgeo, ensure you meet the following requirements:

    • Python: 64-bit Python version >= 3.10. (Note: 32-bit installations may cause dependency issues).
    • For building from source:
      • A C++17-compliant compiler.
      • Doxygen (optional, used for building documentation).
  4. Build py4dgeo from source

    main

    To build py4dgeo from source, you must have a C++17-compliant compiler installed. If you want to enable multi-threading, your toolchain must support OpenMP.

    Use the --editable flag to allow changes to Python sources without reinstalling, and the -v flag for verbose output (useful for debugging compilation issues). To recompile the C++ source after changes, run the install command again.

    git clone --recursive https://github.com/3dgeo-heidelberg/py4dgeo.git
    cd py4dgeo
    python -m pip install -v --editable .
  5. Perform spatiotemporal change analysis with SpatiotemporalAnalysis

    main

    To analyze surface dynamics over time, use the py4dgeo.SpatiotemporalAnalysis class. This object manages a time series of point clouds and calculates distances between them using a specified algorithm (like M3C2).

    Workflow:

    1. Initialize SpatiotemporalAnalysis with a directory containing your point cloud data.
    2. Define a reference_epoch by reading a point cloud file (e.g., using py4dgeo.read_from_las) and assigning it a .timestamp.
    3. Set analysis.corepoints (the points where distances will be calculated).
    4. Configure and assign an algorithm (e.g., M3C2) to analysis.m3c2.
    5. Add subsequent epochs using analysis.add_epochs(*epochs).

    Key attributes available after analysis:

    • analysis.distances: A 2D array of distances for each corepoint across epochs.
    • analysis.uncertainties: Uncertainty values (e.g., ['lodetection']).
    • analysis.timedeltas: Time differences relative to the reference epoch.
    import py4dgeo
    import os
    
    # 1. Initialize
    analysis = py4dgeo.SpatiotemporalAnalysis(pc_dir, force=True)
    
    # 2. Set reference epoch
    reference_epoch = py4dgeo.read_from_las(reference_epoch_file)
    reference_epoch.timestamp = timestamps[0]
    analysis.reference_epoch = reference_epoch
    
    # 3. Configure algorithm and corepoints
    analysis.corepoints = reference_epoch.cloud[::]
    analysis.m3c2 = py4dgeo.M3C2(cyl_radii=(1.0,), max_distance=10.0, registration_error=0.019)
    
    # 4. Add epochs
    analysis.add_epochs(*epochs)
  6. Prototype new algorithms by inheriting from M3C2LikeAlgorithm

    main

    To create a custom algorithm in py4dgeo, you should define a new class that inherits from py4dgeo.M3C2LikeAlgorithm or a more specialized class like py4dgeo.M3C2. This allows you to rapidly prototype new logic in Python while leveraging the existing framework.

    For example, you can override properties like name to change how the algorithm identifies itself.

    import py4dgeo
    
    class RenamedAlgorithm(py4dgeo.M3C2):
        @property
        def name(self):
            return "My super-duper M3C2 algorithm"
  7. How coordinate reduction points work in transformations

    main

    To ensure numerical robustness, py4dgeo uses a reduction point $\mathbf{x_0}$ when applying transformations. This shifts coordinates towards the origin before applying rotations.

    The transformation formula used is: $$\mathbf{Tx} = \left(\mathbf{R}(\mathbf{x}-\mathbf{x_0})\right) + \mathbf{t} + \mathbf{x_0}$$

    When using registration algorithms, the returned transformation object contains both the affine matrix $\mathbf{T}$ and the $\mathbf{x_0}$ used. You must provide both to the .transform() method to ensure the rotation is applied around the correct center.

  8. How to customize the 4D-OBC algorithm

    main

    The 4D Object By Change (4D-OBC) implementation in py4dgeo is designed to be extensible. To customize the algorithm, create a new class that inherits from py4dgeo.RegionGrowingAlgorithm and override specific methods to change its behavior. This allows you to modify distance measures, seed prioritization, object filtering, or seed point detection without rewriting the entire region-growing logic.

    class MyCustomAlgorithm(py4dgeo.RegionGrowingAlgorithm):
        # Override specific methods here
        pass
  9. How reduction points work for numerical stability

    main

    When calculating or applying transformations, specifying a reduction point $\mathbf{x_0}$ allows shifting coordinates towards the origin before applying rotations. This leads to more numerically robust operations, especially when working with large global coordinates (e.g., UTM), as it avoids coordinate correlation and floating-point overflow.

    The transformation algorithm using a reduction point is: $$ \mathbf{Tx} = (\mathbf{R}(\mathbf{x}-\mathbf{x_0})) + \mathbf{t} + \mathbf{x_0} $$

    Common choices for a reduction point include:

    • The center of gravity of the point cloud.
    • The coordinates of the first point in the point cloud.
    • The bounding box center.