Boundary-Aware Feature Computation
Cross-tile processing that eliminates edge artifacts and ensures consistent feature quality across tile boundaries.
π― What is Boundary-Aware Processing?β
Boundary-aware processing uses neighboring tile context when computing features near tile edges, eliminating the artificial discontinuities that occur when tiles are processed in isolation.
The Problemβ
Traditional tile-by-tile processing creates artifacts at boundaries:
Tile A | Tile B
|
Points near edge have:
- Incomplete neighborhoods
- Incorrect geometric features
- Edge artifacts in ML predictions
The Solutionβ
Boundary-aware processing loads neighbor tiles and includes their points when computing features:
Tile A + Buffer from B | Tile B + Buffer from A
|
Points near edge now have:
β
Complete neighborhoods
β
Accurate geometric features
β
Seamless predictions across tiles
π Usageβ
Enable Boundary-Aware Processingβ
# Basic usage
ign-lidar-hd process \
input_dir=data/raw/ \
output_dir=output/ \
features.boundary_aware=true
With Tile Stitchingβ
Boundary-aware processing works seamlessly with tile stitching:
# Multi-tile dataset with boundary-aware features
ign-lidar-hd process \
input_dir=data/raw/ \
output_dir=output/ \
stitching.enabled=true \
features.boundary_aware=true \
features.buffer_size=5.0
βοΈ Configurationβ
Key Parametersβ
Parameter | Type | Default | Description |
---|---|---|---|
features.boundary_aware | bool | false | Enable boundary-aware processing |
features.buffer_size | float | 5.0 | Buffer distance in meters |
features.neighbor_tiles | int | 8 | Number of neighbors to consider (1-8) |
features.edge_threshold | float | 2.0 | Distance from edge to apply buffer |
Buffer Size Selectionβ
Choose buffer size based on your feature scale:
# For local features (curvature, normal vectors)
features.buffer_size=2.0
# For neighborhood features (linearity, planarity)
features.buffer_size=5.0
# For contextual features (density, height variations)
features.buffer_size=10.0
π How It Worksβ
1. Neighbor Detectionβ
2. Buffer Extractionβ
# For each neighbor tile
1. Load neighbor point cloud
2. Extract points within buffer_size of shared boundary
3. Merge with current tile points
4. Compute features with complete neighborhood
3. Feature Computationβ
# Compute features with neighbor context
for point in tile_points:
if distance_to_edge(point) < edge_threshold:
neighborhood = get_neighbors(point, include_buffer=True)
else:
neighborhood = get_neighbors(point, include_buffer=False)
features = compute_features(neighborhood)
π¨ Visual Comparisonβ
Without Boundary-Aware Processingβ
Tile Boundary Issue:
βββββββββββββββ¬ββββββββββββββ
β Tile A β Tile B β
β β β
β XXXXXβXXXXX β β Artifacts at edge
β XXXXXβXXXXX β
β β β
βββββββββββββββ΄ββββββββββββββ
With Boundary-Aware Processingβ
Seamless Transition:
βββββββββββββββ¬ββββββββββββββ
β Tile A β Tile B β
β β β
β XXXXXXXXXXXXXXXXXX β β Smooth features
β XXXXXXXXXXXXXXXXXX β
β β β
βββββββββββββββ΄ββββββββββββββ
π Performance Impactβ
Processing Timeβ
Mode | Time per Tile | Overhead |
---|---|---|
Standard | 1.0x | 0% |
Boundary-Aware (1-4) | 1.1x | +10% |
Boundary-Aware (5-8) | 1.2x | +20% |
Memory Usageβ
Memory per tile = tile_size + (buffer_size Γ num_neighbors)
Example (50m tile, 5m buffer, 4 neighbors):
Standard: 100 MB
Boundary-aware: 120 MB (+20%)
π§ Advanced Usageβ
Custom Neighbor Selectionβ
# Only load orthogonal neighbors (faster)
ign-lidar-hd process \
input_dir=data/ \
output_dir=output/ \
features.boundary_aware=true \
features.neighbor_tiles=4
# Load all 8 neighbors (highest quality)
ign-lidar-hd process \
input_dir=data/ \
output_dir=output/ \
features.boundary_aware=true \
features.neighbor_tiles=8
Python APIβ
from ign_lidar.features import BoundaryAwareComputer
from ign_lidar.io import TileManager
# Initialize
tile_manager = TileManager(input_dir="data/raw/")
computer = BoundaryAwareComputer(
buffer_size=5.0,
neighbor_tiles=8,
edge_threshold=2.0
)
# Process with boundary awareness
tile = tile_manager.load_tile("tile_1234_5678")
neighbors = tile_manager.get_neighbors(tile)
features = computer.compute_features(tile, neighbors)
print(f"Features computed with {len(neighbors)} neighbors")
β Best Practicesβ
When to Useβ
β Use boundary-aware processing when:
- Processing multi-tile datasets
- Features depend on local neighborhoods
- Quality at boundaries is critical
- Training ML models on tile data
β Skip boundary-aware processing when:
- Processing single tiles
- Using global features only
- Performance is critical
- Tiles have no neighbors
Optimization Tipsβ
- Start small: Use
neighbor_tiles=4
for faster processing - Tune buffer: Match buffer size to feature scale
- Batch processing: Process tiles in groups for efficiency
- Cache neighbors: Reuse neighbor data when processing adjacent tiles
π Troubleshootingβ
Missing Neighborsβ
# Error: Cannot find neighbor tiles
Solution: Ensure all neighbor tiles are available in input_dir
# Check tile availability
ls -la data/raw/*.laz | wc -l
High Memory Usageβ
# Reduce buffer size
features.buffer_size=2.0
# Or reduce neighbors
features.neighbor_tiles=4
Slow Processingβ
# Process fewer neighbors
features.neighbor_tiles=4
# Or reduce buffer
features.buffer_size=3.0
# Or disable for non-edge points
features.edge_threshold=5.0 # Only process within 5m of edge
π Related Topicsβ
- Tile Stitching - Multi-tile dataset creation
- Feature Computation - Available features
- Configuration System - Advanced configuration
π Example Workflowsβ
Regional Dataset with Boundary-Aware Featuresβ
# 1. Download regional tiles
ign-lidar-hd download \
bbox="2.3,48.8,2.4,48.9" \
output_dir=data/raw/
# 2. Process with boundary-aware features
ign-lidar-hd process \
input_dir=data/raw/ \
output_dir=output/ \
stitching.enabled=true \
features.boundary_aware=true \
features.buffer_size=5.0 \
features=full
# 3. Results: Seamless features across all tiles
Next Steps:
- Learn about Tile Stitching
- Explore Configuration Options
- See Complete Workflows