Skip to content

Commit

Permalink
Update to Colmap 3.9.1 and add Dockerfile (#26)
Browse files Browse the repository at this point in the history
  • Loading branch information
pablospe authored Jan 24, 2024
1 parent 7f66455 commit 533405d
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 26 deletions.
62 changes: 62 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
ARG UBUNTU_VERSION=22.04
ARG NVIDIA_CUDA_VERSION=12.3.1
FROM nvidia/cuda:${NVIDIA_CUDA_VERSION}-devel-ubuntu${UBUNTU_VERSION} as builder

ARG COLMAP_VERSION=3.9.1
ARG CUDA_ARCHITECTURES=70
ENV CUDA_ARCHITECTURES=${CUDA_ARCHITECTURES}
ENV QT_XCB_GL_INTEGRATION=xcb_egl

# Prevent stop building ubuntu at time zone selection.
ENV DEBIAN_FRONTEND=noninteractive

# Prepare and empty machine for building.
RUN apt-get update && \
apt-get install -y --no-install-recommends --no-install-suggests \
git \
cmake \
ninja-build \
build-essential \
libboost-program-options-dev \
libboost-filesystem-dev \
libboost-graph-dev \
libboost-system-dev \
libeigen3-dev \
libflann-dev \
libfreeimage-dev \
libmetis-dev \
libgoogle-glog-dev \
libgtest-dev \
libsqlite3-dev \
libglew-dev \
qtbase5-dev \
libqt5opengl5-dev \
libcgal-dev \
python-is-python3 \
python3-minimal \
python3-pip \
python3-dev \
python3-setuptools

# Install Ceres.
RUN apt-get install -y --no-install-recommends --no-install-suggests wget && \
wget "http://ceres-solver.org/ceres-solver-2.1.0.tar.gz" && \
tar zxf ceres-solver-2.1.0.tar.gz && \
mkdir ceres-build && \
cd ceres-build && \
cmake ../ceres-solver-2.1.0 -GNinja && \
ninja install

# Install Colmap.
RUN wget "https://github.com/colmap/colmap/archive/refs/tags/${COLMAP_VERSION}.tar.gz" -O colmap-${COLMAP_VERSION}.tar.gz && \
tar zxvf colmap-${COLMAP_VERSION}.tar.gz && \
mkdir colmap-build && \
cd colmap-build && \
cmake ../colmap-${COLMAP_VERSION} -GNinja -DCMAKE_CUDA_ARCHITECTURES=${CUDA_ARCHITECTURES} && \
ninja install


# Build pyceres.
COPY . /pyceres
WORKDIR /pyceres
RUN pip install . -vv
15 changes: 14 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,27 @@ git clone --recursive [email protected]:cvg/pyceres.git
cd pyceres
```

2. Install [COLMAP 3.8](https://colmap.github.io/) - _make sure to use tag 3.8_.
2. Install [COLMAP 3.9.1](https://colmap.github.io/)

3. Build the package:

```sh
pip install -e .
```

### Docker image

Alternatively, you can build the Docker image:

```sh
export COLMAP_VERSION=3.9.1
export CUDA_ARCHITECTURES=70
docker build -t pyceres \
--build-arg COLMAP_VERSION=${COLMAP_VERSION} \
--build-arg CUDA_ARCHITECTURES=${CUDA_ARCHITECTURES} \
-f Dockerfile .
```

## Factor graph optimization

For now we support the following cost functions, defined in `_pyceres/factors/`:
Expand Down
48 changes: 23 additions & 25 deletions _pyceres/factors/bundle.cc
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#include <colmap/camera/models.h>
#include <colmap/geometry/projection.h>
#include <colmap/scene/projection.h>
#include <colmap/sensor/models.h>
#include <colmap/util/types.h>

#include <ceres/ceres.h>
Expand All @@ -15,12 +15,9 @@ inline void WorldToPixel(const T* camera_params, const T* qvec, const T* tvec,
projection[1] += tvec[1];
projection[2] += tvec[2];

// Project to image plane.
projection[0] /= projection[2]; // u
projection[1] /= projection[2]; // v

// Distort and transform to pixel space.
CameraModel::WorldToImage(camera_params, projection[0], projection[1], &xy[0], &xy[1]);
CameraModel::ImgFromCam(camera_params, projection[0], projection[1], projection[2],
&xy[0], &xy[1]);
}

template <typename T>
Expand All @@ -43,7 +40,7 @@ class BundleAdjustmentCost {
static ceres::CostFunction* Create(const Eigen::Vector2d& point2D,
const double stddev) {
return (new ceres::AutoDiffCostFunction<BundleAdjustmentCost<CameraModel>, 2, 4, 3, 3,
CameraModel::kNumParams>(
CameraModel::num_params>(
new BundleAdjustmentCost(point2D, stddev)));
}

Expand Down Expand Up @@ -78,7 +75,7 @@ class BundleAdjustmentConstantPoseCost : public BundleAdjustmentCost<CameraModel
const Eigen::Vector4d qvec,
const Eigen::Vector3d tvec) {
return (new ceres::AutoDiffCostFunction<BundleAdjustmentConstantPoseCost<CameraModel>,
2, 3, CameraModel::kNumParams>(
2, 3, CameraModel::num_params>(
new BundleAdjustmentConstantPoseCost(point2D, stddev, qvec, tvec)));
}

Expand Down Expand Up @@ -111,7 +108,7 @@ class BundleAdjustmentConstantRigCost : public BundleAdjustmentCost<CameraModel>
const Eigen::Vector4d rel_qvec,
const Eigen::Vector3d rel_tvec) {
return (new ceres::AutoDiffCostFunction<BundleAdjustmentConstantRigCost<CameraModel>,
2, 4, 3, 3, CameraModel::kNumParams>(
2, 4, 3, 3, CameraModel::num_params>(
new BundleAdjustmentConstantRigCost(point2D, stddev, rel_qvec, rel_tvec)));
}

Expand Down Expand Up @@ -144,7 +141,7 @@ class BundleAdjustmentRigCost : public BundleAdjustmentCost<CameraModel> {
static ceres::CostFunction* Create(const Eigen::Vector2d& point2D,
const double stddev) {
return (new ceres::AutoDiffCostFunction<BundleAdjustmentRigCost<CameraModel>, 2, 4, 3,
4, 3, 3, CameraModel::kNumParams>(
4, 3, 3, CameraModel::num_params>(
new BundleAdjustmentRigCost(point2D, stddev)));
}

Expand All @@ -159,12 +156,12 @@ class BundleAdjustmentRigCost : public BundleAdjustmentCost<CameraModel> {
}
};

ceres::CostFunction* CreateBundleAdjustmentCost(int camera_model_id,
const Eigen::Vector2d& point2D,
const double stddev) {
ceres::CostFunction* CreateBundleAdjustmentCost(
const colmap::CameraModelId camera_model_id, const Eigen::Vector2d& point2D,
const double stddev) {
switch (camera_model_id) {
#define CAMERA_MODEL_CASE(CameraModel) \
case colmap::CameraModel::kModelId: \
case colmap::CameraModel::model_id: \
return BundleAdjustmentCost<colmap::CameraModel>::Create(point2D, stddev); \
break;
CAMERA_MODEL_SWITCH_CASES
Expand All @@ -173,11 +170,11 @@ ceres::CostFunction* CreateBundleAdjustmentCost(int camera_model_id,
}

ceres::CostFunction* CreateBundleAdjustmentConstantPoseCost(
int camera_model_id, const Eigen::Vector2d& point2D, const Eigen::Vector4d& qvec,
const Eigen::Vector3d& tvec, const double stddev) {
const colmap::CameraModelId camera_model_id, const Eigen::Vector2d& point2D,
const Eigen::Vector4d& qvec, const Eigen::Vector3d& tvec, const double stddev) {
switch (camera_model_id) {
#define CAMERA_MODEL_CASE(CameraModel) \
case colmap::CameraModel::kModelId: \
case colmap::CameraModel::model_id: \
return BundleAdjustmentConstantPoseCost<colmap::CameraModel>::Create( \
point2D, stddev, qvec, tvec); \
break;
Expand All @@ -187,11 +184,12 @@ ceres::CostFunction* CreateBundleAdjustmentConstantPoseCost(
}

ceres::CostFunction* CreateBundleAdjustmentConstantRigCost(
int camera_model_id, const Eigen::Vector2d& point2D, const Eigen::Vector4d& rel_qvec,
const Eigen::Vector3d& rel_tvec, const double stddev) {
const colmap::CameraModelId camera_model_id, const Eigen::Vector2d& point2D,
const Eigen::Vector4d& rel_qvec, const Eigen::Vector3d& rel_tvec,
const double stddev) {
switch (camera_model_id) {
#define CAMERA_MODEL_CASE(CameraModel) \
case colmap::CameraModel::kModelId: \
case colmap::CameraModel::model_id: \
return BundleAdjustmentConstantRigCost<colmap::CameraModel>::Create( \
point2D, stddev, rel_qvec, rel_tvec); \
break;
Expand All @@ -200,12 +198,12 @@ ceres::CostFunction* CreateBundleAdjustmentConstantRigCost(
}
}

ceres::CostFunction* CreateBundleAdjustmentRigCost(int camera_model_id,
const Eigen::Vector2d& point2D,
const double stddev) {
ceres::CostFunction* CreateBundleAdjustmentRigCost(
const colmap::CameraModelId camera_model_id, const Eigen::Vector2d& point2D,
const double stddev) {
switch (camera_model_id) {
#define CAMERA_MODEL_CASE(CameraModel) \
case colmap::CameraModel::kModelId: \
case colmap::CameraModel::model_id: \
return BundleAdjustmentRigCost<colmap::CameraModel>::Create(point2D, stddev); \
break;
CAMERA_MODEL_SWITCH_CASES
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def build_extension(self, ext):
'-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir,
'-DPYTHON_EXECUTABLE=' + sys.executable,
'-DVERSION_INFO={}'.format(self.distribution.get_version()),
'-DCMAKE_CUDA_ARCHITECTURES={}'.format(os.environ.get('CUDA_ARCHITECTURES', 'native')),
]
eigen_dir = os.environ.get('EIGEN3_INCLUDE_DIRS')
if eigen_dir is not None:
Expand Down

0 comments on commit 533405d

Please sign in to comment.