Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #30 from mihaidusmanu/wheels
Browse files Browse the repository at this point in the history
[CI] Build wheels and publish to pypi
skydes authored Jan 2, 2022
2 parents bd528d7 + aad4be7 commit 5cfd165
Showing 9 changed files with 624 additions and 4 deletions.
76 changes: 76 additions & 0 deletions .github/workflows/build-new.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
name: Pybind11 CI

on:
push:
branches:
- master
pull_request:
types: [ assigned, opened, synchronize, reopened ]
release:
types: [published]
workflow_dispatch:

jobs:
linux-build:
name: Wrapper Linux Build
runs-on: ubuntu-latest
strategy:
matrix:
pyversion: ["cp37-cp37m","cp38-cp38"] # "cp36-cp36m", "cp39-cp39"
steps:
- name: Checkout
uses: actions/checkout@v2
with:
submodules: recursive
- name: Build the Linux wheels
run: |
# must be run in docker, cannot be run as freestanding script for toolchain issues
# run on old CentOS. but it's CentOS, so it's yum(RPM) not apt. very old glibc. glibc API is back-compatible but not forward. See https://github.com/pypa/manylinux
# see https://github.com/varunagrawal/docker-images/blob/master/gtsam-manylinux/Dockerfile for an example
# container, but it does not have some necesssary boost packages --> varunagrawal/gtsam-manylinux:latest
sudo docker run --rm -e PLAT=manylinux2014_x86_64 -e PYTHON_VERSION=${{ matrix.pyversion }} -v `pwd`:/io quay.io/pypa/manylinux2014_x86_64 /io/package/build-wheels-linux.sh ${{ matrix.pyversion }}
# cleanup for custom runner
sudo chown -R $(whoami):$(whoami) .
- name: Archive wheels
uses: actions/upload-artifact@v2
with:
# we strip the version number from the artifact name
name: pycolmap-${{ matrix.pyversion }}-manylinux2014_x86_64
path: wheelhouse/pycolmap-*-${{ matrix.pyversion }}-manylinux2014_x86_64.whl
- name: Publish package
# We publish the wheel to pypi when a new tag is pushed,
# either by creating a new GitHub release or explictly with `git tag`
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
packages_dir: wheelhouse/

mac-build:
name: Wrapper macOS Build
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [macos-11, macos-10.15]
pyversion: ["python@3.8", "python@3.9"] # "python@3.7" not supported in Github Actions
steps:
- name: Checkout
uses: actions/checkout@v2
with:
submodules: recursive
- name: Build the macOS wheels
run: |
./package/build-wheels-macos.sh ${{ matrix.pyversion }}
- name: Archive wheels
uses: actions/upload-artifact@v2
with:
name: pycolmap-${{ matrix.pyversion }}-${{ matrix.os }}
path: ./wheelhouse/pycolmap-*.whl
- name: Publish package
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags')
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
packages_dir: wheelhouse/
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
.vscode
*.so
*.egg-info/
build/
8 changes: 6 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
cmake_minimum_required(VERSION 3.6)
project(PyCOLMAP)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")

find_package(COLMAP REQUIRED)
include_directories(${COLMAP_INCLUDE_DIRS})
link_directories(${COLMAP_LINK_DIRS})

if (${CERES_VERSION} VERSION_LESS "2.0.0")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14")
endif()

add_subdirectory(pybind11)

pybind11_add_module(pycolmap main.cc)
88 changes: 88 additions & 0 deletions homography_estimation.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
#include <iostream>
#include <fstream>

#include "colmap/estimators/homography_matrix.h"
#include "colmap/optim/loransac.h"

using namespace colmap;

#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/eigen.h>

namespace py = pybind11;

/**
* Recover the most probable pose from the inputted homography matrix.
*
* @param points2D1 First set of corresponding points.
* @param points2D2 Second set of corresponding points.
* @param max_error_px
* @param min_inlier_ratio
* @param min_num_trials
* @param max_num_trials
* @return The estimated homography matrix (3x3), ...
*/
py::dict homography_matrix_estimation(
const std::vector<Eigen::Vector2d> points2D1,
const std::vector<Eigen::Vector2d> points2D2,
const double max_error_px,
const double min_inlier_ratio,
const int min_num_trials,
const int max_num_trials,
const double confidence
) {
SetPRNGSeed(0);

// Check that both vectors have the same size.
assert(points2D1.size() == points2D2.size());

// Failure output dictionary.
py::dict failure_dict;
failure_dict["success"] = false;

// Fundamental matrix estimation parameters.
RANSACOptions ransac_options;
ransac_options.max_error = max_error_px;
ransac_options.min_inlier_ratio = min_inlier_ratio;
ransac_options.min_num_trials = min_num_trials;
ransac_options.max_num_trials = max_num_trials;
ransac_options.confidence = confidence;

// Estimate planar or panoramic model.
LORANSAC<
HomographyMatrixEstimator,
HomographyMatrixEstimator
> H_ransac(ransac_options);

// Homography matrix estimation.
const auto report = H_ransac.Estimate(points2D1, points2D2);

if (!report.success) {
return failure_dict;
}

// Recover data from report.
const Eigen::Matrix3d H = report.model;
const size_t num_inliers = report.support.num_inliers;
const auto inlier_mask = report.inlier_mask;

// Convert vector<char> to vector<int>.
std::vector<bool> inliers;
for (auto it : inlier_mask) {
if (it) {
inliers.push_back(true);
} else {
inliers.push_back(false);
}
}

// Success output dictionary.
py::dict success_dict;
success_dict["success"] = true;
success_dict["H"] = H;
success_dict["num_inliers"] = num_inliers;
success_dict["inliers"] = inliers;

return success_dict;
}
30 changes: 30 additions & 0 deletions main.cc
Original file line number Diff line number Diff line change
@@ -6,13 +6,20 @@ namespace py = pybind11;
#include "generalized_absolute_pose.cc"
#include "essential_matrix.cc"
#include "fundamental_matrix.cc"
#include "homography_estimation.cc"
#include "homography_decomposition.cc"
#include "transformations.cc"
#include "sift.cc"
#include "pose_refinement.cc"
#include "two_view_geometry_estimation.cc"

PYBIND11_MODULE(pycolmap, m) {
m.doc() = "COLMAP plugin";
#ifdef VERSION_INFO
m.attr("__version__") = py::str(VERSION_INFO);
#else
m.attr("__version__") = py::str("dev");
#endif

// Absolute pose.
m.def("absolute_pose_estimation", &absolute_pose_estimation,
@@ -57,6 +64,16 @@ PYBIND11_MODULE(pycolmap, m) {
py::arg("confidence") = 0.9999,
"LORANSAC + 7-point algorithm.");

// Homography matrix estimation.
m.def("homography_matrix_estimation", &homography_matrix_estimation,
py::arg("points2D1"), py::arg("points2D2"),
py::arg("max_error_px") = 4.0,
py::arg("min_inlier_ratio") = 0.01,
py::arg("min_num_trials") = 1000,
py::arg("max_num_trials") = 100000,
py::arg("confidence") = 0.9999,
"LORANSAC + 4-point DLT algorithm.");

// Homography Decomposition.
m.def("homography_decomposition", &homography_decomposition_estimation,
py::arg("H"),
@@ -84,4 +101,17 @@ PYBIND11_MODULE(pycolmap, m) {
py::arg("inlier_mask"),
py::arg("camera_dict"),
"Non-linear refinement.");

// Generic two view geometry estimation.
m.def("two_view_geometry_estimation", &two_view_geometry_estimation,
py::arg("points2D1"),
py::arg("points2D2"),
py::arg("camera_dict1"),
py::arg("camera_dict2"),
py::arg("max_error_px") = 4.0,
py::arg("min_inlier_ratio") = 0.01,
py::arg("min_num_trials") = 1000,
py::arg("max_num_trials") = 100000,
py::arg("confidence") = 0.9999,
"Generic two-view geometry estimation");
}
Loading

0 comments on commit 5cfd165

Please sign in to comment.