Skip to content

Commit

Permalink
Merge pull request #2 from ThreeDify/setup-opensfm
Browse files Browse the repository at this point in the history
Setup OpenSfM
  • Loading branch information
silwalanish authored Nov 22, 2020
2 parents 6d87c6f + 375187f commit 728fc40
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 19 deletions.
13 changes: 13 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
.vscode/
.venv/

dist/
build/
*.egg*/
*.py[cod]

data/

.env
**/*.pyc
**/__pycache__
2 changes: 2 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
API_BASE_URL=http://localhost:3000

SFM_IMPLEMENTATION=OPENSFM|THREEDIFY
23 changes: 7 additions & 16 deletions .github/workflows/lint-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,11 @@ jobs:
# Checks-out repository under $GITHUB_WORKSPACE, so job can access it
- uses: actions/checkout@v2

# Setup python
- name: Setup Python
uses: actions/setup-python@v2
with:
python-version: 3.8.6
# Build Image
- name: Build Docker Image
run: docker build --target=lint -t threedify_sfm_lint .

# Run Lint Checks
- name: Run Lint Checks
run: docker run threedify_sfm_lint

# Setup environment
- name: Setup environment
run: pip install -e .[dev]

# Run linter
- name: Run lint
run: pylint src

# Run code formatter
- name: Run code format
run: black --check --diff src/.
15 changes: 15 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
FROM ghcr.io/threedify/opensfm:0.5.2 AS main

WORKDIR /source/ThreeDify-SfM

COPY . .

RUN python3 setup.py install

CMD python3 src/main.py

FROM main AS lint

RUN pip3 install -e .[dev]

CMD pylint src && black --check .
28 changes: 27 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ ThreeDify is a online platform where you can upload images and create a 3D recon

| Variable | Description |
| ----------------------------- | ------------------------------------------------ |
| BASE_URL | API base url e.g. http://localhost |
| API_BASE_URL | API base url e.g. http://localhost |
| SFM_IMPLEMENTATION | SfM implementation to use. (OPENSFM|THREEDIFY) |

# Setup
1. Install `python-3.8` and `pip`.
Expand All @@ -28,12 +29,30 @@ $ pip install -e .[dev]
$ cp .env.example .env
```

4. Setup OpenSfM. [Docs](https://www.opensfm.org/docs/building.html)

## Run

```bash
$ python src/main.py
```

## Run with Docker

1. Setup Docker.

2. Build image.

```
$ docker build --target=main -t threedify_sfm .
```

3. Run

```
$ docker run --env-file=.env threedify_sfm
```

## Lint

Check lint errors.
Expand All @@ -47,3 +66,10 @@ Fix format.
```bash
$ black src
```

Check lint and format errors with docker.

```bash
$ docker build --target=lint -t threedify_sfm_lint .
$ docker run threedify_sfm_lint
```
12 changes: 10 additions & 2 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

from threedify_sfm.SfM import SfM
from threedify_sfm.DataSet import DataSet
from threedify_sfm.utils.opensfm import OpenSfM
from threedify_sfm.constants import SFM_IMPLEMENTATION
from threedify_sfm.utils.reconstructions import fetch_reconstructions

logging.basicConfig()
Expand All @@ -22,8 +24,14 @@ def main():
logger.info("Creating dataset for reconstruction.")
dataset = DataSet(reconstruction)

logger.info("Running SfM with the dataset.")
sfm = SfM(dataset)
if SFM_IMPLEMENTATION == "OPENSFM":
logger.info("Using OpenSfM implementation.")
sfm = OpenSfM(dataset)
else:
logger.info("Using ThreeDify SfM implementation.")
sfm = SfM(dataset)

logger.info("Running SfM pipeline.")
sfm.run()


Expand Down
9 changes: 9 additions & 0 deletions src/threedify_sfm/DataSet.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,15 @@ def images(self) -> List[str]:
"""
return self.image_paths

def data_path(self) -> str:
"""
Get the path to directory of the dataset.
"""
return os.path.join(
DOWNLOAD_PATH,
"{}_{}".format(self.reconstruction.name, self.reconstruction.id),
)

def image_path(self) -> str:
"""
Get the path to directory of the images.
Expand Down
2 changes: 2 additions & 0 deletions src/threedify_sfm/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@
DOWNLOAD_PATH = os.path.join(
os.path.abspath(os.path.dirname(__file__)), "../../", "data"
)

SFM_IMPLEMENTATION = os.getenv("SFM_IMPLEMENTATION", "THREEDIFY").upper()
59 changes: 59 additions & 0 deletions src/threedify_sfm/utils/opensfm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import logging

from opensfm import dataset
from opensfm.actions import (
extract_metadata,
detect_features,
match_features,
create_tracks,
reconstruct,
mesh,
undistort,
compute_depthmaps,
)

from threedify_sfm.DataSet import DataSet

logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)


class OpenSfM:
"""
Run structure from motion pipeline on given dataset.
"""

dataset: dataset.DataSet

def __init__(self, data: DataSet):
self.dataset = dataset.DataSet(data.data_path())

def run(self):
"""
Run the SFM pipeline
"""
logger.info("Running SFM pipeline.")

logger.info("Extracting camera data from dataset.")
extract_metadata.run_dataset(self.dataset)

logger.info("Extracting features from dataset.")
detect_features.run_dataset(self.dataset)

logger.info("Matching features from the images in the dataset.")
match_features.run_dataset(self.dataset)

logger.info("Creating tracks from the matches.")
create_tracks.run_dataset(self.dataset)

logger.info("Running reconstruction.")
reconstruct.run_dataset(self.dataset)

logger.info("Generating mesh.")
mesh.run_dataset(self.dataset)

logger.info("Undistoring images.")
undistort.run_dataset(self.dataset, None, 0, None, "undistored")

logger.info("Computing depthmaps.")
compute_depthmaps.run_dataset(self.dataset, "undistored", False)

0 comments on commit 728fc40

Please sign in to comment.