A Python toolkit for 3D tree reconstruction from aerial imagery using COLMAP structure-from-motion, deep learning segmentation, and ray-based point densification.
# Create Python virtual environment
python -m venv venv
source venv/bin/activate
# Install dependencies
pip install -r requirements.txt
# Load COLMAP (on HPC systems)
module load colmap/3.8-cuda-11.8-avx512
# Add your aerial images to the data/raw/ folder
cp /path/to/your/drone/images/* data/raw/cd scripts
# Basic usage (full 5-step pipeline)
python run_pipeline.py --images ../data/raw --model ../models/model.pth# Submit complete pipeline to cluster
bsub < run_pipeline.shThe complete pipeline consists of 5 automated steps:
- π― Segmentation - Generate tree masks using DeepLabV3
- ποΈ COLMAP Reconstruction - Create initial 3D point cloud from images
- π Point Filtering - Remove non-tree points using mask visibility
- β¨ Ray Enhancement - Add more points to sparse model via ray casting
- π Visualization - Create comparison plots
Input: Raw aerial images (+ pre-trained segmentation model)
Output: Enhanced sparse 3D point cloud + visualization + processing summary
BotanicalTreeReconstruction/
βββ README.md # This documentation
βββ requirements.txt # Python dependencies
βββ .gitignore # Git ignore patterns
βββ .gitattributes # Git LFS configuration
βββ data/ # Datasets (raw images, segmentation masks)
βββ models/ # Pre-trained segmentation model, Colmap models
βββ outputs/ # Generated visualizations and summaries
βββ scripts/ # All processing scripts
βββ run_pipeline.py # π― Complete automation script
βββ run_pipeline.sh # π HPC batch script
βββ segmentation_inference.py # π Tree segmentation with DeepLabV3
βββ colmap_reconstruction.py # ποΈ COLMAP reconstruction
βββ mask_based_filtering.py # π Point cloud filtering
βββ ray_based_enhancement.py # β¨ Ray-based point enhancement
βββ visualize_results.py # π Comprehensive visualization
βββ read_write_model.py # π οΈ COLMAP model I/O utilities
βββ logs/ # HPC job output logs
run_pipeline.py - Complete automation script that orchestrates all pipeline steps.
--images DIR- Input images directory (required)--model FILE- Path to segmentation model (.pth file)--mask-type {rough,fine,both}- Type of masks to generate (default: both)--max-features INT- Maximum features for COLMAP (default: 20000)--visibility-threshold FLOAT- Point filtering threshold 0.0-1.0 (default: 0.5)--combine-masks {or,and}- How to combine rough/fine masks (default: or)
--skip-segmentation- Use existing masks in data/segmentation_masks/--skip-colmap- Use existing model in models/colmap_reconstruction/--skip-filtering- Use existing filtered model in models/colmap_filtered/--skip-rays- Skip ray enhancement (faster, less dense)--skip-visualization- Skip final visualization
--colmap-model DIR- Path to existing COLMAP model (when skipping COLMAP)--filtered-model DIR- Path to existing filtered model (when skipping filtering)--continue-on-error- Continue pipeline even if a step fails--debug- Enable detailed error output
run_pipeline.sh - LSF batch script for cluster execution with GPU allocation.
- Resources: A100 GPU, 32GB RAM, 6-hour limit
- Environment: Loads COLMAP module, uses pip-installed requirements
- Logs: Output saved to
logs/JOBID.outandlogs/JOBID.err
# Submit pipeline to cluster
bsub < run_pipeline.shFor advanced users who need fine-grained control over individual pipeline steps.
Generate tree segmentation masks using trained DeepLabV3 model.
Key Arguments:
--model FILE- Path to trained segmentation model (.pth)--input DIR- Input images directory--output DIR- Output masks directory--mask-type {rough,fine,both}- Type of masks to generate--device {cpu,cuda,auto}- Processing device--patch-size INT- Patch size for fine segmentation (default: 512)
Usage:
# Generate both rough and fine masks
python segmentation_inference.py \
--model ../models/model.pth \
--input ../data/raw \
--output ../data/segmentation_masks \
--mask-type both --device cudaCreate COLMAP 3D reconstruction from images with automatic model merging.
Key Arguments:
image_dir- Path to input images directory (required)--output DIR- Output directory (default: ../models/colmap_output)--max-features INT- Max features per image (default: 20000)--log-level {DEBUG,INFO,WARNING,ERROR}- Logging level
Features:
- Automatic GPU/CPU detection - Uses GPU acceleration when available, falls back to CPU
- Model merging - Automatically merges multiple reconstructions when possible
- Smart model selection - Pipeline automatically uses the largest/best reconstruction
Usage:
# Basic reconstruction
python colmap_reconstruction.py ../data/raw
# High quality with 50k features
python colmap_reconstruction.py ../data/raw \
--output ../models/high_quality_colmap \
--max-features 50000Filter COLMAP 3D points using segmentation masks with visibility-based thresholding.
Key Arguments:
--colmap DIR- COLMAP model directory (required)--images DIR- Original images directory (required)--rough-mask DIR- Rough segmentation masks directory (required)--fine-mask DIR- Fine segmentation masks directory (required)--output DIR- Output directory for filtered model--visibility-threshold FLOAT- Keep points visible in β₯this fraction of images (default: 0.5)--threshold INT- Mask pixel threshold value (default: 10)--combine {or,and}- Mask combination method (default: or)--examples INT- Number of visualization examples to save (default: 5)
Usage:
# Filter using both rough and fine masks
python mask_based_filtering.py \
--colmap ../models/colmap_reconstruction/sparse/0 \
--images ../data/raw \
--rough-mask ../data/segmentation_masks \
--fine-mask ../data/segmentation_masks \
--visibility-threshold 0.5 \
--combine orNote: The pipeline automatically selects the best COLMAP model (merged model if available, otherwise the largest reconstruction).
Enhance sparse COLMAP model by adding more points using ray-casting and voxel-based sampling.
Key Arguments:
--colmap_model_dir DIR- Input COLMAP model directory (required)--rough_mask_dir DIR- Directory with rough masks (required)--fine_mask_dir DIR- Directory with fine masks (required)--output_dir DIR- Base output directory (required)--output-folder-name NAME- Specific folder name for output--mask_thresh INT- Mask threshold for combining rough/fine masks (default: 10)--samples_per_image INT- Sampled mask pixels per image (default: 1000)--depth_samples INT- Depth samples per ray (default: 50)--voxel_size FLOAT- Voxel size in meters (default: 0.02)--min_image_support INT- Minimum images supporting a voxel (default: 3)--chunk_size FLOAT- Spatial chunk size in meters for processing (smaller = less memory, more runtime)(default: 4)
Usage:
# Enhance sparse model using ray casting
python ray_based_enhancement.py \
--colmap_model_dir ../models/colmap_filtered \
--rough_mask_dir ../data/segmentation_masks \
--fine_mask_dir ../data/segmentation_masks \
--output_dir ../models \
--output-folder-name colmap_ray_enhanced \
--samples_per_image 1000Create comprehensive visualizations showing all pipeline stages.
Key Arguments:
--images DIR- Original images directory (required)--original_model DIR- Original COLMAP model directory (required)--filtered_model DIR- Filtered COLMAP model directory (required)--ray_model DIR- Ray-enhanced COLMAP model directory--output FILE- Output visualization image path (required)--masks DIR- Segmentation masks directory--n_images INT- Number of sample images to visualize (default: 3)--point_size FLOAT- Size of projected points (default: 1.0)--mask_type {rough,fine,both}- Type of masks to display (default: both)--show_combined- Show additional column with combined filtered + ray points
Usage:
# Create 5-column visualization (default)
python visualize_results.py \
--images ../data/raw \
--masks ../data/segmentation_masks \
--original_model ../models/colmap_reconstruction/sparse/0 \
--filtered_model ../models/colmap_filtered \
--ray_model ../models/colmap_ray_enhanced \
--n_images 3
# Create 6-column visualization with combined view
python visualize_results.py \
--images ../data/raw \
--masks ../data/segmentation_masks \
--original_model ../models/colmap_reconstruction/sparse/0 \
--filtered_model ../models/colmap_filtered \
--ray_model ../models/colmap_ray_enhanced \
--n_images 3 \
--show_combinedCreates a 5-column visualization showing:
- Original Image - Raw input images
- Segmentation Mask - Combined tree segmentation overlaid on images
- Original COLMAP - Points from initial reconstruction (red)
- Filtered COLMAP - Points after mask-based filtering (blue)
- New Ray Points - Only newly added points from ray enhancement (green)
With --show_combined, adds a 6th column:
6. Combined (Filtered + Ray) - All points in final enhanced model (purple)
After running the complete pipeline, your outputs will be organized as:
data/
βββ segmentation_masks/ # Step 1 - Generated masks
βββ image1_rough.png
βββ image1_fine.png
βββ image2_rough.png
βββ image2_fine.png
models/
βββ colmap_reconstruction/ # Step 2 - Initial COLMAP reconstruction
β βββ database.db
β βββ sparse/
β βββ 0/ # Best reconstruction (merged if multiple existed)
β βββ 1/ # Second reconstruction (if multiple)
βββ colmap_filtered/ # Step 3 - Filtered points using masks
β βββ cameras.bin
β βββ images.bin
β βββ points3D.bin
βββ colmap_ray_enhanced/ # Step 4 - Enhanced sparse model from ray casting
βββ cameras.bin
βββ images.bin
βββ points3D.bin
outputs/
βββ pipeline_visualization.png # Step 5 - 5-column comparison plot
βββ processing_summary.txt # Detailed processing log
βββ point_statistics.txt # Point counts for each stage
**Notes:**
- **Multiple COLMAP models**: If COLMAP creates disconnected reconstructions, both will be kept and the pipeline will automatically use the largest one
- **Model merging**: When possible, separate reconstructions are merged and the result overwrites the smaller model
- **Automatic selection**: The pipeline selects the best model (largest by points/images) without manual intervention
"COLMAP not found"
- Ensure COLMAP is installed and in PATH
- On HPC:
module load colmapbefore running - Test with:
colmap --help
"CUDA out of memory"
- Reduce
--max-features(try 10000) - Use
--mask-type roughonly - Add
--device cpufor segmentation
"Model file not found"
- Ensure model is tracked with Git LFS:
git lfs pull - Check file size is >100MB:
ls -lh models/
"No images found"
- Check image directory structure: images should be directly in specified folder
- Supported formats: .jpg, .jpeg, .png
- Ensure absolute paths or run from correct directory