Skip to content

Commit

Permalink
Resolve merge conflict
Browse files Browse the repository at this point in the history
  • Loading branch information
senselessdev1 committed Sep 5, 2023
2 parents ea532a9 + 2007ba5 commit 2e4eda5
Show file tree
Hide file tree
Showing 40 changed files with 1,055 additions and 251 deletions.
8 changes: 8 additions & 0 deletions .github/scripts/download_single_benchmark.sh
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@ function download_and_unzip_dataset_files {
# Tanks and Temples Dataset, "Barn" scene.
WGET_URL1=https://github.com/johnwlambert/gtsfm-datasets-mirror/releases/download/tanks-and-temples-barn/Tanks_and_Temples_Barn_410.zip
ZIP_FNAME=Tanks_and_Temples_Barn_410.zip

elif [ "$DATASET_NAME" == "south-building-128" ]; then
WGET_URL1=https://github.com/johnwlambert/gtsfm-datasets-mirror/releases/download/south-building-128/south-building-128.zip
ZIP_FNAME=south-building-128.zip

fi

# Download the data.
Expand Down Expand Up @@ -139,6 +144,9 @@ function download_and_unzip_dataset_files {
unzip gerrard-hall-100.zip
ls -ltrh gerrard-hall-100

elif [ "$DATASET_NAME" == "south-building-128" ]; then
unzip south-building-128.zip

elif [ "$DATASET_NAME" == "tanks-and-temples-barn-410" ]; then
unzip -qq Tanks_and_Temples_Barn_410.zip
fi
Expand Down
22 changes: 14 additions & 8 deletions .github/scripts/execute_single_benchmark.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
DATASET_NAME=$1
CONFIG_NAME=$2
MAX_FRAME_LOOKAHEAD=$3
IMAGE_EXTENSION=$4
LOADER_NAME=$5
MAX_RESOLUTION=$6
SHARE_INTRINSICS=$7
LOADER_NAME=$4
MAX_RESOLUTION=$5
SHARE_INTRINSICS=$6

# Extract the data, configure arguments for runner.
if [ "$DATASET_NAME" == "door-12" ]; then
Expand All @@ -33,10 +32,14 @@ elif [ "$DATASET_NAME" == "gerrard-hall-100" ]; then
elif [ "$DATASET_NAME" == "tanks-and-temples-barn-410" ]; then
DATASET_ROOT="Tanks_and_Temples_Barn_410"
SCENE_NAME="Barn"
elif [ "$DATASET_NAME" == "south-building-128" ]; then
IMAGES_DIR=south-building-128/images
#COLMAP_FILES_DIRPATH=south-building-128/colmap-official-2016-10-05
COLMAP_FILES_DIRPATH=south-building-128/colmap-2023-07-28-txt
fi

echo "Config: ${CONFIG_NAME}, Loader: ${LOADER_NAME}"
echo "Max. Frame Lookahead: ${MAX_FRAME_LOOKAHEAD}, Image Extension: ${IMAGE_EXTENSION}, Max. Resolution: ${MAX_RESOLUTION}"
echo "Max. Frame Lookahead: ${MAX_FRAME_LOOKAHEAD}, Max. Resolution: ${MAX_RESOLUTION}"
echo "Share intrinsics for all images? ${SHARE_INTRINSICS}"

# Setup the command line arg if intrinsics are to be shared
Expand All @@ -50,7 +53,8 @@ fi
if [ "$LOADER_NAME" == "olsson-loader" ]; then
python gtsfm/runner/run_scene_optimizer_olssonloader.py \
--dataset_root $DATASET_ROOT \
--config_name ${CONFIG_NAME}.yaml \
--config_name unified \
--correspondence_generator_config_name ${CONFIG_NAME} \
--max_frame_lookahead $MAX_FRAME_LOOKAHEAD \
--max_resolution ${MAX_RESOLUTION} \
${SHARE_INTRINSICS_ARG} \
Expand All @@ -60,7 +64,8 @@ elif [ "$LOADER_NAME" == "colmap-loader" ]; then
python gtsfm/runner/run_scene_optimizer_colmaploader.py \
--images_dir ${IMAGES_DIR} \
--colmap_files_dirpath $COLMAP_FILES_DIRPATH \
--config_name ${CONFIG_NAME}.yaml \
--config_name unified \
--correspondence_generator_config_name ${CONFIG_NAME} \
--max_frame_lookahead $MAX_FRAME_LOOKAHEAD \
--max_resolution ${MAX_RESOLUTION} \
${SHARE_INTRINSICS_ARG} \
Expand All @@ -69,7 +74,8 @@ elif [ "$LOADER_NAME" == "colmap-loader" ]; then
elif [ "$LOADER_NAME" == "astrovision" ]; then
python gtsfm/runner/run_scene_optimizer_astrovision.py \
--data_dir $DATASET_ROOT \
--config_name ${CONFIG_NAME}.yaml \
--config_name unified \
--correspondence_generator_config_name ${CONFIG_NAME} \
--max_frame_lookahead $MAX_FRAME_LOOKAHEAD \
--max_resolution ${MAX_RESOLUTION} \
${SHARE_INTRINSICS_ARG} \
Expand Down
9 changes: 4 additions & 5 deletions .github/scripts/execute_single_benchmark_self_hosted.sh
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,9 @@ DATASET_PREFIX=/usr/local/gtsfm-data
DATASET_NAME=$1
CONFIG_NAME=$2
MAX_FRAME_LOOKAHEAD=$3
IMAGE_EXTENSION=$4
LOADER_NAME=$5
MAX_RESOLUTION=$6
SHARE_INTRINSICS=$7
LOADER_NAME=$4
MAX_RESOLUTION=$5
SHARE_INTRINSICS=$6

# Extract the data, configure arguments for runner.
if [ "$DATASET_NAME" == "skydio-501" ]; then
Expand All @@ -26,7 +25,7 @@ fi


echo "Config: ${CONFIG_NAME}, Loader: ${LOADER_NAME}"
echo "Max. Frame Lookahead: ${MAX_FRAME_LOOKAHEAD}, Image Extension: ${IMAGE_EXTENSION}, Max. Resolution: ${MAX_RESOLUTION}"
echo "Max. Frame Lookahead: ${MAX_FRAME_LOOKAHEAD}, Max. Resolution: ${MAX_RESOLUTION}"
echo "Share intrinsics for all images? ${SHARE_INTRINSICS}"

# Setup the command line arg if intrinsics are to be shared
Expand Down
4 changes: 1 addition & 3 deletions .github/workflows/benchmark-self-hosted.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
PYTHON_VERSION: 3.8

steps:
- uses: actions/checkout@v3.5.3
- uses: actions/checkout@v4.0.0
- name: Cache frontend
uses: actions/cache@v3
env:
Expand Down Expand Up @@ -68,7 +68,6 @@ jobs:
DATASET_NAME=${{ matrix.config_dataset_info[1] }}
CONFIG_NAME=${{ matrix.config_dataset_info[0] }}
MAX_FRAME_LOOKAHEAD=${{ matrix.config_dataset_info[2] }}
IMAGE_EXTENSION=${{ matrix.config_dataset_info[3] }}
LOADER_NAME=${{ matrix.config_dataset_info[5] }}
MAX_RESOLUTION=${{ matrix.config_dataset_info[6] }}
SHARE_INTRINSICS=${{ matrix.config_dataset_info[7] }}
Expand All @@ -79,7 +78,6 @@ jobs:
$DATASET_NAME \
$CONFIG_NAME \
$MAX_FRAME_LOOKAHEAD \
$IMAGE_EXTENSION \
$LOADER_NAME \
$MAX_RESOLUTION \
$SHARE_INTRINSICS
Expand Down
33 changes: 16 additions & 17 deletions .github/workflows/benchmark.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,20 +12,21 @@ jobs:
matrix:
config_dataset_info:
[
# config dataset lookahead img-extension source loader max-res share-intrinsics
[sift_front_end, door-12, 12, JPG, test_data, olsson-loader, 1296, true],
[deep_front_end, door-12, 12, JPG, test_data, olsson-loader, 1296, true],
[sift_front_end, skydio-8, 8, jpg, gdrive , colmap-loader, 760, true],
[deep_front_end, skydio-8, 8, jpg, gdrive, colmap-loader, 760, true],
[sift_front_end, skydio-32, 32, jpg, gdrive, colmap-loader, 760, true],
[deep_front_end, skydio-32, 32, jpg, gdrive, colmap-loader, 760, true],
[sift_front_end, palace-fine-arts-281, 25, jpg, wget, olsson-loader, 320, true],
[deep_front_end, notre-dame-20, 20, jpg, gdrive, colmap-loader, 760, false],
[sift_front_end_astrovision, 2011205_rc3, 65, png, wget, astrovision, 1024, true],
[deep_front_end_astrovision, 2011205_rc3, 65, png, wget, astrovision, 1024, true],
[sift_front_end, gerrard-hall-100, 0, jpg, wget, colmap-loader, 760, true],
[deep_front_end, gerrard-hall-100, 0, jpg, wget, colmap-loader, 760, true],
[synthetic_front_end, tanks-and-temples-barn-410, 4, jpg, wget, tanks-and-temples, 1080, true],
# config dataset lookahead img-extension source loader max-res share-intrinsics
[sift, door-12, 15, JPG, test_data, olsson-loader, 1296, true],
[lightglue, door-12, 15, JPG, test_data, olsson-loader, 1296, true],
[sift, skydio-8, 15, jpg, gdrive , colmap-loader, 760, true],
[lightglue, skydio-8, 15, jpg, gdrive, colmap-loader, 760, true],
[sift, skydio-32, 15, jpg, gdrive, colmap-loader, 760, true],
[lightglue, skydio-32, 15, jpg, gdrive, colmap-loader, 760, true],
[sift, palace-fine-arts-281, 15, jpg, wget, olsson-loader, 320, true],
[lightglue, notre-dame-20, 15, jpg, gdrive, colmap-loader, 760, false],
[sift, 2011205_rc3, 15, png, wget, astrovision, 1024, true],
[lightglue, 2011205_rc3, 15, png, wget, astrovision, 1024, true],
[sift, gerrard-hall-100, 15, jpg, wget, colmap-loader, 760, true],
[lightglue, gerrard-hall-100, 15, jpg, wget, colmap-loader, 760, true],
[sift, south-building-128, 15, jpg, wget, colmap-loader, 760, true],
[lightglue, south-building-128, 15, jpg, wget, colmap-loader, 760, true],
]
defaults:
run:
Expand All @@ -35,7 +36,7 @@ jobs:
PYTHON_VERSION: 3.8

steps:
- uses: actions/checkout@v3.5.3
- uses: actions/checkout@v4.0.0
- name: Cache frontend
uses: actions/cache@v3
env:
Expand Down Expand Up @@ -64,15 +65,13 @@ jobs:
DATASET_NAME=${{ matrix.config_dataset_info[1] }}
CONFIG_NAME=${{ matrix.config_dataset_info[0] }}
MAX_FRAME_LOOKAHEAD=${{ matrix.config_dataset_info[2] }}
IMAGE_EXTENSION=${{ matrix.config_dataset_info[3] }}
LOADER_NAME=${{ matrix.config_dataset_info[5] }}
MAX_RESOLUTION=${{ matrix.config_dataset_info[6] }}
SHARE_INTRINSICS=${{ matrix.config_dataset_info[7] }}
bash .github/scripts/execute_single_benchmark.sh \
$DATASET_NAME \
$CONFIG_NAME \
$MAX_FRAME_LOOKAHEAD \
$IMAGE_EXTENSION \
$LOADER_NAME \
$MAX_RESOLUTION \
$SHARE_INTRINSICS
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-wheels.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
shell: bash -l {0}

steps:
- uses: actions/checkout@v3.5.3
- uses: actions/checkout@v4.0.0
- uses: conda-incubator/setup-miniconda@v2
with:
mamba-version: "*"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-python.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
PYTHON_VERSION: 3.8

steps:
- uses: actions/checkout@v3.5.3
- uses: actions/checkout@v4.0.0
- uses: conda-incubator/setup-miniconda@v2
with:
mamba-version: "*"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test-reproducibility.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jobs:
PYTHON_VERSION: 3.8

steps:
- uses: actions/checkout@v3.5.3
- uses: actions/checkout@v4.0.0
- uses: conda-incubator/setup-miniconda@v2
with:
mamba-version: "*"
Expand Down
10 changes: 3 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,13 @@ To run SfM with a dataset with only an image directory and EXIF, with image file
and run

```python
python gtsfm/runner/run_scene_optimizer_olssonloader.py --config_name {CONFIG_NAME} --dataset_root {DATASET_ROOT} --image_extension jpg --num_workers {NUM_WORKERS}
python gtsfm/runner/run_scene_optimizer_olssonloader.py --config_name {CONFIG_NAME} --dataset_root {DATASET_ROOT} --num_workers {NUM_WORKERS}
```

For example, if you had 4 cores available and wanted to use the Deep Front-End (recommended) on the "door" dataset, you should run:

```bash
python gtsfm/runner/run_scene_optimizer_olssonloader.py --dataset_root tests/data/set1_lund_door --image_extension JPG --config_name deep_front_end.yaml --num_workers 4
python gtsfm/runner/run_scene_optimizer_olssonloader.py --dataset_root tests/data/set1_lund_door --config_name deep_front_end.yaml --num_workers 4
```

(or however many workers you desire).
Expand All @@ -87,7 +87,7 @@ Currently we require EXIF data embedded into your images (or you can provide gro
If you would like to compare GTSfM output with COLMAP output, please run:

```python
python gtsfm/runner/run_scene_optimizer_colmaploader.py --config_name {CONFIG_NAME} --images_dir {IMAGES_DIR} --colmap_files_dirpath {COLMAP_FILES_DIRPATH} --image_extension jpg --num_workers {NUM_WORKERS} --max_frame_lookahead {MAX_FRAME_LOOKAHEAD}
python gtsfm/runner/run_scene_optimizer_colmaploader.py --config_name {CONFIG_NAME} --images_dir {IMAGES_DIR} --colmap_files_dirpath {COLMAP_FILES_DIRPATH} --num_workers {NUM_WORKERS} --max_frame_lookahead {MAX_FRAME_LOOKAHEAD}
```

where `COLMAP_FILES_DIRPATH` is a directory where .txt files such as `cameras.txt`, `images.txt`, etc have been saved.
Expand Down Expand Up @@ -145,7 +145,3 @@ Open-source Python implementation:
```

Note: authors are listed in alphabetical order (by last name).

## Compiling Additional Verifiers

On Linux, we have made `pycolmap`'s LORANSAC available in [pypi](https://pypi.org/project/pycolmap/). However, on Mac, `pycolmap` must be built from scratch. See the instructions [here](https://github.com/borglab/gtsfm/blob/master/gtsfm/frontend/verifier/loransac.py#L10).
2 changes: 1 addition & 1 deletion environment_linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,5 @@ dependencies:
- colour
- pycolmap>=0.1.0
- trimesh[easy]
- gtsam==4.2a8
- gtsam==4.2
- pydot
2 changes: 1 addition & 1 deletion environment_linux_cpuonly.yml
Original file line number Diff line number Diff line change
Expand Up @@ -52,5 +52,5 @@ dependencies:
- colour
- pycolmap>=0.1.0
- trimesh[easy]
- gtsam==4.2a8
- gtsam==4.2
- pydot
2 changes: 1 addition & 1 deletion environment_mac.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,5 +57,5 @@ dependencies:
- colour
- trimesh[easy]
- pycolmap>=0.1.0
- gtsam==4.2a8
- gtsam==4.2
- pydot
45 changes: 39 additions & 6 deletions gtsfm/averaging/rotation/rotation_averaging_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
Authors: Jing Wu, Ayush Baid
"""
import abc
import time
from typing import Dict, List, Optional, Tuple

import dask
Expand Down Expand Up @@ -54,14 +55,45 @@ def run_rotation_averaging(
underconstrained system or ill-constrained system).
"""

def _run_rotation_averaging_base(
self,
num_images: int,
i2Ri1_dict: Dict[Tuple[int, int], Optional[Rot3]],
i1Ti2_priors: Dict[Tuple[int, int], PosePrior],
wTi_gt: List[Optional[Pose3]],
) -> Tuple[List[Optional[Rot3]], GtsfmMetricsGroup]:
"""Runs rotation averaging and computes metrics.
Args:
num_images: Number of poses.
i2Ri1_dict: Relative rotations as dictionary (i1, i2): i2Ri1.
i1Ti2_priors: Priors on relative poses as dictionary(i1, i2): PosePrior on i1Ti2.
wTi_gt: Ground truth global rotations to compare against.
Returns:
Global rotations for each camera pose, i.e. wRi, as a list. The number of entries in the list is
`num_images`. The list may contain `None` where the global rotation could not be computed (either
underconstrained system or ill-constrained system).
Metrics on global rotations.
"""
start_time = time.time()
wRis = self.run_rotation_averaging(num_images, i2Ri1_dict, i1Ti2_priors)
run_time = time.time() - start_time

metrics = self.evaluate(wRis, wTi_gt)
metrics.add_metric(GtsfmMetric("total_duration_sec", run_time))

return wRis, metrics

def evaluate(self, wRi_computed: List[Optional[Rot3]], wTi_gt: List[Optional[Pose3]]) -> GtsfmMetricsGroup:
"""Evaluate the global rotations computed by the rotation averaging implementation.
"""Evaluates the global rotations computed by the rotation averaging implementation.
Args:
wRi_computed: list of global rotations computed.
wTi_gt: ground truth global rotations to compare against.
wRi_computed: List of global rotations computed.
wTi_gt: Ground truth global rotations to compare against.
Raises:
ValueError: if the length of the computed and GT list differ.
ValueError: If the length of the computed and GT list differ.
Returns:
Metrics on global rotations.
Expand Down Expand Up @@ -97,7 +129,8 @@ def create_computation_graph(
global rotations wrapped using dask.delayed.
"""

wRis = dask.delayed(self.run_rotation_averaging)(num_images, i2Ri1_graph, i1Ti2_priors)
metrics = dask.delayed(self.evaluate)(wRis, gt_wTi_list)
wRis, metrics = dask.delayed(self._run_rotation_averaging_base, nout=2)(
num_images, i2Ri1_dict=i2Ri1_graph, i1Ti2_priors=i1Ti2_priors, wTi_gt=gt_wTi_list
)

return wRis, metrics
13 changes: 13 additions & 0 deletions gtsfm/averaging/translation/averaging_1dsfm.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@
Authors: Jing Wu, Ayush Baid, Akshay Krishnan
"""
import time
from collections import defaultdict
from enum import Enum
from typing import DefaultDict, Dict, List, Optional, Set, Tuple

import gtsam
import numpy as np
from gtsam import (
Expand Down Expand Up @@ -461,6 +463,7 @@ def run_translation_averaging(

w_i2Ui1_dict, valid_cameras = get_valid_measurements_in_world_frame(i2Ui1_dict, wRi_list)

start_time = time.time()
if self._use_tracks_for_averaging:
if tracks_2d is None:
logger.info("No tracks provided for translation averaging. Falling back to camera unit translations.")
Expand All @@ -473,10 +476,13 @@ def run_translation_averaging(
else:
w_i2Ui1_dict_tracks = {}

inlier_computation_start_time = time.time()
w_i2Ui1_dict_inliers, w_i2Ui1_dict_tracks_inliers, inlier_cameras = self.compute_inliers(
w_i2Ui1_dict, w_i2Ui1_dict_tracks
)
inlier_computation_time = time.time() - inlier_computation_start_time

averaging_start_time = time.time()
wti_list = self.__run_averaging(
num_images=num_images,
w_i2Ui1_dict=w_i2Ui1_dict_inliers,
Expand All @@ -486,6 +492,7 @@ def run_translation_averaging(
absolute_pose_priors=absolute_pose_priors,
scale_factor=scale_factor,
)
averaging_time = time.time() - averaging_start_time

# Compute the metrics.
ta_metrics = compute_metrics(set(w_i2Ui1_dict_inliers.keys()), i2Ui1_dict, wRi_list, wti_list, gt_wTi_list)
Expand All @@ -497,6 +504,12 @@ def run_translation_averaging(
wTi_list = [
Pose3(wRi, wti) if wRi is not None and wti is not None else None for wRi, wti in zip(wRi_list, wti_list)
]
total_time = time.time() - start_time
logger.info("Translation averaging took %.4f seconds.", total_time)
ta_metrics.add_metric(GtsfmMetric("total_duration_sec", total_time))
ta_metrics.add_metric(GtsfmMetric("outier_rejection_duration_sec", inlier_computation_time))
ta_metrics.add_metric(GtsfmMetric("optimization_duration_sec", averaging_time))

return wTi_list, ta_metrics


Expand Down
Loading

0 comments on commit 2e4eda5

Please sign in to comment.