diff --git a/.github/workflows/format-ubuntu.yml b/.github/workflows/format-ubuntu.yml index 1410019b..767948e4 100644 --- a/.github/workflows/format-ubuntu.yml +++ b/.github/workflows/format-ubuntu.yml @@ -37,8 +37,7 @@ jobs: exit 0 fi set +x -euo pipefail - sudo apt-get update && sudo apt-get install -y clang-format-14 - python -m pip install ruff==0.6.7 + python -m pip install ruff==0.6.7 clang-format==19.1.0 ./scripts/format/clang_format.sh ./scripts/format/python.sh git diff --name-only diff --git a/.gitmodules b/.gitmodules index d7ad5e3e..a3d91e06 100644 --- a/.gitmodules +++ b/.gitmodules @@ -7,9 +7,6 @@ [submodule "third-party/JLinkage"] path = third-party/JLinkage url = https://github.com/B1ueber2y/JLinkage -[submodule "third-party/libigl"] - path = third-party/libigl - url = https://github.com/B1ueber2y/libigl.git [submodule "third-party/RansacLib"] path = third-party/RansacLib url = https://github.com/B1ueber2y/RansacLib.git @@ -36,3 +33,6 @@ [submodule "third-party/GlueStick"] path = third-party/GlueStick url = https://github.com/cvg/GlueStick.git +[submodule "third-party/libigl"] + path = third-party/libigl + url = https://github.com/libigl/libigl.git diff --git a/CMakeLists.txt b/CMakeLists.txt index 9b3340ef..740c1f8e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,12 +8,11 @@ project(LIMAP) # Include CMake dependencies ################################################################################ set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED TRUE) +set(CMAKE_CXX_STANDARD_REQUIRED ON) if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.1) message(FATAL_ERROR "GCC version needs to be at least 9.1") endif() set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake) -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -w -std=c++17 -std=gnu++17") # brute-force approach to make sure we are using C++17 # Include helper macros and commands, and allow the included file to override # the CMake policies in this file @@ -24,89 +23,34 @@ include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/CMakeHelper.cmake NO_POLICY_SCOPE) ################################################################################ option(OPENMP_ENABLED "Whether to enable OpenMP parallelization" ON) option(INTERPOLATION_ENABLED "Whether to enable interpolation-based pixel-perfect optimization" OFF) +option(FETCH_POSELIB "Whether to use PoseLib with FetchContent or with self-installed software" ON) +option(FETCH_COLMAP "Whether to use COLMAP with FetchContent or with self-installed software" ON) +option(CUDA_ENABLED "Whether to use CUDA (only for the third-party COLMAP)" OFF) -################################################################################ -# Compiler specific configuration -################################################################################ - -if(OPENMP_ENABLED) - find_package(OpenMP) - if(OPENMP_FOUND) - message(STATUS "Enabling OpenMP support") - add_definitions("-DOPENMP_ENABLED") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") - endif() -endif() - -if(INTERPOLATION_ENABLED) - message(STATUS "Enabling pixelwise optimization with ceres interpolation. This should be disabled for clang.") - add_definitions("-DINTERPOLATION_ENABLED") -else() - message(STATUS "Disabling pixelwise optimization with ceres interpolation.") -endif() - -################################################################################ -# Find packages -################################################################################ -find_package(Eigen3 3.3 REQUIRED) -find_package(COLMAP REQUIRED) -if(${CERES_VERSION} VERSION_LESS "2.2.0") - # ceres 2.2.0 changes the interface of local parameterization - add_definitions("-DCERES_PARAMETERIZATION_ENABLED") -endif() -find_package(PoseLib REQUIRED) - -################################################################################ -# Add sources -################################################################################ - -set(LIMAP_INCLUDE_DIRS - ${HDF5_INCLUDE_DIRS} - ${EIGEN3_INCLUDE_DIR} - ${PROJECT_SOURCE_DIR} - ${FREEIMAGE_INCLUDE_DIRS} - ${COLMAP_INCLUDE_DIRS} -) - -set(LIMAP_LINK_DIRS - ${COLMAP_LINK_DIRS} -) - -set(LIMAP_EXTERNAL_LIBRARIES - ${CERES_LIBRARIES} - ${FREEIMAGE_LIBRARIES} - ${COLMAP_LIBRARIES} - ${HDF5_C_LIBRARIES} - ${Boost_LIBRARIES} - PoseLib::PoseLib -) - -if(OPENMP_FOUND) - list(APPEND LIMAP_EXTERNAL_LIBRARIES ${OpenMP_libomp_LIBRARY}) -endif() - -set(LIMAP_INTERNAL_LIBRARIES - HighFive - pybind11::module - JLinkage - igl::core -) +include(cmake/FindDependencies.cmake) +include(cmake/InitVariables.cmake) +# include directories include_directories( third-party limap + ${PROJECT_SOURCE_DIR} ${LIMAP_INCLUDE_DIRS} ) - link_directories(${LIMAP_LINK_DIRS}) +# Add sources add_subdirectory(third-party) include_directories(${JLINKAGE_INCLUDE_DIRS}) -include_directories(${POSELIB_INCLUDE_DIRS}) include_directories(${RANSACLIB_INCLUDE_DIRS}) add_subdirectory(limap) +# Install find_package scripts for dependencies. +install( + DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/cmake + DESTINATION share/colmap + FILES_MATCHING PATTERN "Find*.cmake") + ################################################################################ # Generate source groups for Visual Studio, XCode, etc. ################################################################################ diff --git a/README.md b/README.md index 81e57874..06a0bbb9 100644 --- a/README.md +++ b/README.md @@ -18,17 +18,38 @@ In this project, we provide interfaces for various geometric operations on 2D/3D ## Installation -**Note**: COLMAP has been under active development since summer 2023, so we currently only support COLMAP 3.8. - **Install the dependencies as follows:** * CMake >= 3.17 -* COLMAP 3.8 [[the official guide](https://colmap.github.io/install.html)] _make sure to use the tag 3.8_ -* PoseLib [[Guide](misc/install/poselib.md)] +* All dependencies for third-party: COLMAP (will be installed with FetchContent). From [[official guide](https://colmap.github.io/install.html)] +```bash +sudo apt-get install \ + 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 \ + libgmock-dev \ + libsqlite3-dev \ + libglew-dev \ + qtbase5-dev \ + libqt5opengl5-dev \ + libcgal-dev \ + libceres-dev +``` * HDF5 ```bash sudo apt-get install libhdf5-dev ``` -* Python 3.9 + required packages +* Python >= 3.9 + required packages ```bash git submodule update --init --recursive diff --git a/cfgs/fitnmerge/default.yaml b/cfgs/fitnmerge/default.yaml index 3867c3db..c7c7a7e3 100644 --- a/cfgs/fitnmerge/default.yaml +++ b/cfgs/fitnmerge/default.yaml @@ -55,7 +55,7 @@ fitting: var2d: -1.0 # depends on the detector ransac_th: 0.75 min_percentage_inliers: 0.9 - n_jobs: 4 + n_jobs: 1 ############################## # merging config diff --git a/cmake/FindDependencies.cmake b/cmake/FindDependencies.cmake new file mode 100644 index 00000000..17cef13c --- /dev/null +++ b/cmake/FindDependencies.cmake @@ -0,0 +1,69 @@ +################################################################################ +# Find packages +################################################################################ +find_package(Eigen3 3.4 REQUIRED) +find_package(FreeImage REQUIRED) +find_package(Glog REQUIRED) +if(DEFINED glog_VERSION_MAJOR) + # Older versions of glog don't export version variables. + add_definitions("-DGLOG_VERSION_MAJOR=${glog_VERSION_MAJOR}") + add_definitions("-DGLOG_VERSION_MINOR=${glog_VERSION_MINOR}") +endif() +find_package(Boost REQUIRED COMPONENTS + graph + program_options + system) + +# Ceres +find_package(Ceres REQUIRED COMPONENTS SuiteSparse) +if(${CERES_VERSION} VERSION_LESS "2.2.0") + # ceres 2.2.0 changes the interface of local parameterization + add_definitions("-DCERES_PARAMETERIZATION_ENABLED") +endif() +if(INTERPOLATION_ENABLED) + message(STATUS "Enabling pixelwise optimization with ceres interpolation. This should be disabled for clang.") + add_definitions("-DINTERPOLATION_ENABLED") +else() + message(STATUS "Disabling pixelwise optimization with ceres interpolation.") +endif() + +# OpenMP +if(OPENMP_ENABLED) + find_package(OpenMP) + if(OPENMP_FOUND) + message(STATUS "Enabling OpenMP support") + add_definitions("-DOPENMP_ENABLED") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") + endif() +endif() + +# PoseLib +include(FetchContent) +FetchContent_Declare(PoseLib + GIT_REPOSITORY https://github.com/PoseLib/PoseLib.git + GIT_TAG a84c545a9895e46d12a3f5ccde2581c25e6a6953 + EXCLUDE_FROM_ALL +) +message(STATUS "Configuring PoseLib...") +if (FETCH_POSELIB) + FetchContent_MakeAvailable(PoseLib) +else() + find_package(PoseLib REQUIRED) +endif() +message(STATUS "Configuring PoseLib... done") + +# COLMAP +FetchContent_Declare(COLMAP + GIT_REPOSITORY https://github.com/colmap/colmap.git + GIT_TAG 63b2cc000de32dc697f45ef1576dec7e67abddbc + EXCLUDE_FROM_ALL +) +message(STATUS "Configuring COLMAP...") +if (FETCH_COLMAP) + FetchContent_MakeAvailable(COLMAP) +else() + find_package(COLMAP REQUIRED) +endif() +message(STATUS "Configuring COLMAP... done") + diff --git a/cmake/FindFreeImage.cmake b/cmake/FindFreeImage.cmake new file mode 100644 index 00000000..43e6dd52 --- /dev/null +++ b/cmake/FindFreeImage.cmake @@ -0,0 +1,104 @@ +# Copyright (c) 2023, ETH Zurich and UNC Chapel Hill. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# * Neither the name of ETH Zurich and UNC Chapel Hill nor the names of +# its contributors may be used to endorse or promote products derived +# from this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + + +# Find package module for FreeImage library. +# +# The following variables are set by this module: +# +# FREEIMAGE_FOUND: TRUE if FreeImage is found. +# freeimage::FreeImage_limap: Imported target to link against. +# +# The following variables control the behavior of this module: +# +# FREEIMAGE_INCLUDE_DIR_HINTS: List of additional directories in which to +# search for FreeImage includes. +# FREEIMAGE_LIBRARY_DIR_HINTS: List of additional directories in which to +# search for FreeImage libraries. + +set(FREEIMAGE_INCLUDE_DIR_HINTS "" CACHE PATH "FreeImage include directory") +set(FREEIMAGE_LIBRARY_DIR_HINTS "" CACHE PATH "FreeImage library directory") + +unset(FREEIMAGE_FOUND) + +find_package(FreeImage CONFIG QUIET) +if(FreeImage_FOUND) + if(TARGET freeimage::FreeImage_limap) + set(FREEIMAGE_FOUND TRUE) + message(STATUS "Found FreeImage") + message(STATUS " Target : freeimage::FreeImage_limap") + endif() +else() + list(APPEND FREEIMAGE_CHECK_INCLUDE_DIRS + ${FREEIMAGE_INCLUDE_DIR_HINTS} + /usr/include + /usr/local/include + /opt/include + /opt/local/include + ) + + list(APPEND FREEIMAGE_CHECK_LIBRARY_DIRS + ${FREEIMAGE_LIBRARY_DIR_HINTS} + /usr/lib + /usr/local/lib + /opt/lib + /opt/local/lib + ) + + find_path(FREEIMAGE_INCLUDE_DIRS + NAMES + FreeImage.h + PATHS + ${FREEIMAGE_CHECK_INCLUDE_DIRS}) + find_library(FREEIMAGE_LIBRARIES + NAMES + freeimage + PATHS + ${FREEIMAGE_CHECK_LIBRARY_DIRS}) + + if(FREEIMAGE_INCLUDE_DIRS AND FREEIMAGE_LIBRARIES) + set(FREEIMAGE_FOUND TRUE) + endif() + + if(FREEIMAGE_FOUND) + message(STATUS "Found FreeImage") + message(STATUS " Includes : ${FREEIMAGE_INCLUDE_DIRS}") + message(STATUS " Libraries : ${FREEIMAGE_LIBRARIES}") + endif() + + add_library(freeimage::FreeImage_limap INTERFACE IMPORTED) + target_include_directories( + freeimage::FreeImage_limap INTERFACE ${FREEIMAGE_INCLUDE_DIRS}) + target_link_libraries( + freeimage::FreeImage_limap INTERFACE ${FREEIMAGE_LIBRARIES}) +endif() + +if(NOT FREEIMAGE_FOUND AND FREEIMAGE_FIND_REQUIRED) + message(FATAL_ERROR "Could not find FreeImage") +endif() diff --git a/cmake/InitVariables.cmake b/cmake/InitVariables.cmake new file mode 100644 index 00000000..262830fd --- /dev/null +++ b/cmake/InitVariables.cmake @@ -0,0 +1,46 @@ +# External libraries +set(LIMAP_EXTERNAL_LIBRARIES + ${CERES_LIBRARIES} + ${FREEIMAGE_LIBRARIES} + ${HDF5_C_LIBRARIES} + ${Boost_LIBRARIES} +) + +# OpenMP +if(OPENMP_FOUND) + list(APPEND LIMAP_EXTERNAL_LIBRARIES ${OpenMP_libomp_LIBRARY}) +endif() + +# colmap +if(NOT FETCH_COLMAP) + list(APPEND LIMAP_EXTERNAL_LIBRARIES colmap::colmap) +else() + list(APPEND LIMAP_EXTERNAL_LIBRARIES colmap) +endif() + +# PoseLib +if(NOT FETCH_POSELIB) + list(APPEND LIMAP_EXTERNAL_LIBRARIES PoseLib::PoseLib) +else() + list(APPEND LIMAP_EXTERNAL_LIBRARIES PoseLib) +endif() + +# Internal libraries +set(LIMAP_INTERNAL_LIBRARIES + HighFive + pybind11::module + JLinkage + igl::core +) + +# Init variables for directories +set(LIMAP_INCLUDE_DIRS + ${HDF5_INCLUDE_DIRS} + ${EIGEN3_INCLUDE_DIR} + ${FREEIMAGE_INCLUDE_DIRS} + ${COLMAP_INCLUDE_DIRS} +) + +set(LIMAP_LINK_DIRS + ${Boost_LIBRARY_DIRS} +) diff --git a/limap/base/CMakeLists.txt b/limap/base/CMakeLists.txt index dbb19864..afac5f8a 100644 --- a/limap/base/CMakeLists.txt +++ b/limap/base/CMakeLists.txt @@ -7,6 +7,7 @@ LIMAP_ADD_SOURCES( transforms.h transforms.cc camera_view.h camera_view.cc image_collection.h image_collection.cc + pose.h pose.cc pointtrack.h pointtrack.cc linebase.h linebase.cc diff --git a/limap/base/bindings.cc b/limap/base/bindings.cc index 43247095..55a1b0e8 100644 --- a/limap/base/bindings.cc +++ b/limap/base/bindings.cc @@ -686,6 +686,13 @@ void bind_line_linker(py::module &m) { } void bind_camera(py::module &m) { + // TODO: use pycolmap + py::enum_ PyCameraModelId(m, "CameraModelId"); + PyCameraModelId.value("INVALID", colmap::CameraModelId::kInvalid); + PyCameraModelId.value("SIMPLE_PINHOLE", + colmap::CameraModelId::kSimplePinhole); + PyCameraModelId.value("PINHOLE", colmap::CameraModelId::kPinhole); + py::class_(m, "Camera", R"( | Camera model, inherits `COLMAP's camera model `_. | COLMAP camera models: @@ -727,6 +734,9 @@ void bind_camera(py::module &m) { .def(py::init>(), py::arg("model_name"), py::arg("cam_id") = -1, py::arg("hw") = std::make_pair(-1, -1)) // empty camera + .def("__copy__", [](const Camera &self) { return Camera(self); }) + .def("__deepcopy__", + [](const Camera &self, const py::dict &) { return Camera(self); }) .def(py::pickle( [](const Camera &input) { // dump return input.as_dict(); @@ -734,6 +744,12 @@ void bind_camera(py::module &m) { [](const py::dict &dict) { // load return Camera(dict); })) + .def_readwrite("camera_id", &Camera::camera_id, + "Unique identifier of the camera.") + .def_readwrite("model", &Camera::model_id, "Camera model.") + .def_readwrite("width", &Camera::width, "Width of camera sensor.") + .def_readwrite("height", &Camera::height, "Height of camera sensor.") + .def_readwrite("params", &Camera::params, "Camera parameters.") .def("as_dict", &Camera::as_dict, R"( Returns: dict: Python dict representation of this :class:`~limap.base.Camera` @@ -754,22 +770,6 @@ void bind_camera(py::module &m) { Returns: :class:`np.array` of shape (3, 3): Inverse of the intrinsic matrix )") - .def("cam_id", &Camera::CameraId, R"( - Returns: - int: Camera ID - )") - .def("model_id", &Camera::ModelId, R"( - Returns: - int: COLMAP camera model ID - )") - .def("params", &Camera::params, R"( - Returns: - list (float): Minimal representation of intrinsic paramters, length varies according to camera model - )") - .def("num_params", &Camera::NumParams, R"( - Returns: - int: Number of the paramters for minimal representation of intrinsic - )") .def("resize", &Camera::resize, R"( Resize camera's width and height. @@ -785,10 +785,6 @@ void bind_camera(py::module &m) { val (int) )", py::arg("val")) - .def("set_cam_id", &Camera::SetCameraId, R"( - Set the camera ID. - )", - py::arg("camera_id")) .def("InitializeParams", &Camera::InitializeParams, R"( Initialize the intrinsics using focal length, width, and height @@ -798,8 +794,8 @@ void bind_camera(py::module &m) { height (int) )", py::arg("focal_length"), py::arg("width"), py::arg("height")) - .def("ImageToWorld", &Camera::ImageToWorld) - .def("WorldToImage", &Camera::WorldToImage) + .def("CamFromImg", &Camera::CamFromImg) + .def("ImgFromCam", &Camera::ImgFromCam) .def("IsInitialized", &Camera::IsInitialized, R"( Returns: bool: True if the camera parameters are initialized @@ -833,6 +829,9 @@ void bind_camera(py::module &m) { Constructor from a Python dict )", py::arg("dict")) + .def("__copy__", [](const CameraPose &self) { return CameraPose(self); }) + .def("__deepcopy__", [](const CameraPose &self, + const py::dict &) { return CameraPose(self); }) .def(py::pickle( [](const CameraPose &input) { // dump return input.as_dict(); @@ -888,6 +887,10 @@ void bind_camera(py::module &m) { py::arg("camera"), py::arg("pose"), py::arg("image_name") = "none") .def(py::init(), py::arg("dict")) .def(py::init(), py::arg("camimage")) + .def("__copy__", + [](const CameraImage &self) { return CameraImage(self); }) + .def("__deepcopy__", [](const CameraImage &self, + const py::dict &) { return CameraImage(self); }) .def(py::pickle( [](const CameraImage &input) { // dump return input.as_dict(); @@ -942,6 +945,9 @@ void bind_camera(py::module &m) { py::arg("camera"), py::arg("pose"), py::arg("image_name") = "none") .def(py::init(), py::arg("dict")) .def(py::init(), py::arg("camview")) + .def("__copy__", [](const CameraView &self) { return CameraView(self); }) + .def("__deepcopy__", [](const CameraView &self, + const py::dict &) { return CameraView(self); }) .def(py::pickle( [](const CameraView &input) { // dump return input.as_dict(); @@ -1060,6 +1066,12 @@ void bind_camera(py::module &m) { .def(py::init &>(), py::arg("camviews")) .def(py::init(), py::arg("dict")) .def(py::init(), py::arg("imagecols")) + .def("__copy__", + [](const ImageCollection &self) { return ImageCollection(self); }) + .def("__deepcopy__", + [](const ImageCollection &self, const py::dict &) { + return ImageCollection(self); + }) .def(py::pickle( [](const ImageCollection &input) { // dump return input.as_dict(); diff --git a/limap/base/camera.cc b/limap/base/camera.cc index 793548cf..de73f6d3 100644 --- a/limap/base/camera.cc +++ b/limap/base/camera.cc @@ -1,28 +1,31 @@ #include "base/camera.h" +#include namespace limap { -void Camera::SetModelId(const int model_id) { - colmap::Camera::SetModelId(model_id); - initialized.resize(NumParams()); +void Camera::SetModelId(int model) { + model_id = static_cast(model); + initialized.resize(params.size()); std::fill(initialized.begin(), initialized.end(), false); } void Camera::SetModelIdFromName(const std::string &model_name) { - colmap::Camera::SetModelIdFromName(model_name); - initialized.resize(NumParams()); + model_id = colmap::CameraModelNameToId(model_name); + initialized.resize(params.size()); std::fill(initialized.begin(), initialized.end(), false); } -void Camera::SetParams(const std::vector ¶ms) { - THROW_CHECK_EQ(params.size(), NumParams()); - colmap::Camera::SetParams(params); +void Camera::SetParams(const std::vector ¶ms_input) { + THROW_CHECK_EQ(params.size(), params_input.size()); + params = params_input; std::fill(initialized.begin(), initialized.end(), true); } -void Camera::InitializeParams(const double focal_length, const int width, - const int height) { - InitializeWithId(ModelId(), focal_length, width, height); +void Camera::InitializeParams(double focal_length, int width, int height) { + width = width; + height = height; + params = colmap::CameraModelInitializeParams(model_id, focal_length, width, + height); std::fill(initialized.begin(), initialized.end(), true); } @@ -35,51 +38,52 @@ bool Camera::IsInitialized() const { } Camera::Camera(const colmap::Camera &cam) { - SetCameraId(cam.CameraId()); - SetModelId(cam.ModelId()); - SetParams(cam.Params()); - SetHeight(cam.Height()); - SetWidth(cam.Width()); + camera_id = cam.camera_id; + model_id = cam.model_id; + params = cam.params; + height = cam.height; + width = cam.width; } // empty camera -Camera::Camera(int model_id, int cam_id, std::pair hw) { - SetModelId(model_id); - SetCameraId(cam_id); - SetHeight(hw.first); - SetWidth(hw.second); +Camera::Camera(int model, int cam_id, std::pair hw) { + model_id = static_cast(model); + camera_id = cam_id; + height = hw.first; + width = hw.second; } // empty camera Camera::Camera(const std::string &model_name, int cam_id, std::pair hw) { - SetModelIdFromName(model_name); - SetCameraId(cam_id); - SetHeight(hw.first); - SetWidth(hw.second); + model_id = colmap::CameraModelNameToId(model_name); + camera_id = cam_id; + height = hw.first; + width = hw.second; } -Camera::Camera(int model_id, const std::vector ¶ms, int cam_id, +Camera::Camera(int model, const std::vector ¶ms_input, int cam_id, std::pair hw) { - SetModelId(model_id); - SetParams(params); + model_id = static_cast(model); + params = params_input; if (cam_id != -1) - SetCameraId(cam_id); + camera_id = cam_id; if (hw.first != -1 && hw.second != -1) { - SetHeight(hw.first); - SetWidth(hw.second); + height = hw.first; + width = hw.second; } } -Camera::Camera(const std::string &model_name, const std::vector ¶ms, - int cam_id, std::pair hw) { - SetModelIdFromName(model_name); - SetParams(params); +Camera::Camera(const std::string &model_name, + const std::vector ¶ms_input, int cam_id, + std::pair hw) { + model_id = colmap::CameraModelNameToId(model_name); + params = params_input; if (cam_id != -1) - SetCameraId(cam_id); + camera_id = cam_id; if (hw.first != -1 && hw.second != -1) { - SetHeight(hw.first); - SetWidth(hw.second); + height = hw.first; + width = hw.second; } } @@ -88,44 +92,43 @@ Camera::Camera(M3D K, int cam_id, std::pair hw) { THROW_CHECK_EQ(K(1, 0), 0); THROW_CHECK_EQ(K(2, 0), 0); THROW_CHECK_EQ(K(2, 1), 0); - std::vector params; + params.clear(); if (K(0, 0) == K(1, 1)) { - SetModelIdFromName("SIMPLE_PINHOLE"); + model_id = colmap::CameraModelNameToId("SIMPLE_PINHOLE"); params.push_back(K(0, 0)); params.push_back(K(0, 2)); params.push_back(K(1, 2)); } else { - SetModelIdFromName("PINHOLE"); + model_id = colmap::CameraModelNameToId("PINHOLE"); params.push_back(K(0, 0)); params.push_back(K(1, 1)); params.push_back(K(0, 2)); params.push_back(K(1, 2)); } - SetParams(params); if (cam_id != -1) - SetCameraId(cam_id); + camera_id = cam_id; if (hw.first != -1 && hw.second != -1) { - SetHeight(hw.first); - SetWidth(hw.second); + height = hw.first; + width = hw.second; } } -Camera::Camera(int model_id, M3D K, int cam_id, std::pair hw) { +Camera::Camera(int model, M3D K, int cam_id, std::pair hw) { THROW_CHECK_EQ(K(0, 1), 0); THROW_CHECK_EQ(K(1, 0), 0); THROW_CHECK_EQ(K(2, 0), 0); THROW_CHECK_EQ(K(2, 1), 0); - std::vector params; - if (model_id == 0) { + params.clear(); + if (model == 0) { // SIMPLE_PINHOLE THROW_CHECK_EQ(K(0, 0), K(1, 1)); - SetModelIdFromName("SIMPLE_PINHOLE"); + model_id = colmap::CameraModelNameToId("SIMPLE_PINHOLE"); params.push_back(K(0, 0)); params.push_back(K(0, 2)); params.push_back(K(1, 2)); - } else if (model_id == 1) { + } else if (model == 1) { // PINHOLE - SetModelIdFromName("PINHOLE"); + model_id = colmap::CameraModelNameToId("PINHOLE"); params.push_back(K(0, 0)); params.push_back(K(1, 1)); params.push_back(K(0, 2)); @@ -133,12 +136,11 @@ Camera::Camera(int model_id, M3D K, int cam_id, std::pair hw) { } else throw std::runtime_error( "model initialized with K should be either SIMPLE_PINHOLE or PINHOLE"); - SetParams(params); if (cam_id != -1) - SetCameraId(cam_id); + camera_id = cam_id; if (hw.first != -1 && hw.second != -1) { - SetHeight(hw.first); - SetWidth(hw.second); + height = hw.first; + width = hw.second; } } @@ -148,17 +150,17 @@ Camera::Camera(const std::string &model_name, M3D K, int cam_id, THROW_CHECK_EQ(K(1, 0), 0); THROW_CHECK_EQ(K(2, 0), 0); THROW_CHECK_EQ(K(2, 1), 0); - std::vector params; + params.clear(); if (model_name == "SIMPLE_PINHOLE") { // SIMPLE_PINHOLE THROW_CHECK_EQ(K(0, 0), K(1, 1)); - SetModelIdFromName("SIMPLE_PINHOLE"); + model_id = colmap::CameraModelNameToId("SIMPLE_PINHOLE"); params.push_back(K(0, 0)); params.push_back(K(0, 2)); params.push_back(K(1, 2)); } else if (model_name == "PINHOLE") { // PINHOLE - SetModelIdFromName("PINHOLE"); + model_id = colmap::CameraModelNameToId("PINHOLE"); params.push_back(K(0, 0)); params.push_back(K(1, 1)); params.push_back(K(0, 2)); @@ -166,37 +168,46 @@ Camera::Camera(const std::string &model_name, M3D K, int cam_id, } else throw std::runtime_error("Error! The model initialized with K should be " "either SIMPLE_PINHOLE (id=0) or PINHOLE (id=1)."); - SetParams(params); if (cam_id != -1) - SetCameraId(cam_id); + camera_id = cam_id; if (hw.first != -1 && hw.second != -1) { - SetHeight(hw.first); - SetWidth(hw.second); + height = hw.first; + width = hw.second; } } Camera::Camera(const Camera &cam) { - SetCameraId(cam.CameraId()); - SetModelId(cam.ModelId()); - SetParams(cam.Params()); - SetHeight(cam.Height()); - SetWidth(cam.Width()); + camera_id = cam.camera_id; + model_id = cam.model_id; + params = cam.params; + height = cam.height; + width = cam.width; initialized = cam.initialized; } +Camera &Camera::operator=(const Camera &cam) { + if (this != &cam) { + camera_id = cam.camera_id; + model_id = cam.model_id; + params = cam.params; + height = cam.height; + width = cam.width; + initialized = cam.initialized; + } + return *this; +} + bool Camera::operator==(const Camera &cam) { - if (CameraId() != cam.CameraId()) + if (camera_id != cam.camera_id) return false; - if (ModelId() != cam.ModelId()) + if (model_id != cam.model_id) return false; if (h() != cam.h()) return false; if (w() != cam.w()) return false; - std::vector params = Params(); - std::vector params_cam = cam.Params(); for (int i = 0; i < params.size(); ++i) { - if (params[i] != params_cam[i]) + if (params[i] != cam.params[i]) return false; } return true; @@ -204,10 +215,8 @@ bool Camera::operator==(const Camera &cam) { void Camera::set_max_image_dim(const int &val) { THROW_CHECK_EQ(IsUndistorted(), true); - THROW_CHECK_GT(val, 0) + THROW_CHECK_GT(val, 0); - double height = Height(); - double width = Width(); double ratio = double(val) / double(std::max(height, width)); if (ratio < 1.0) { int new_width = int(round(ratio * width)); @@ -218,7 +227,7 @@ void Camera::set_max_image_dim(const int &val) { double Camera::uncertainty(double depth, double var2d) const { double f = -1.0; - const std::vector &idxs = FocalLengthIdxs(); + auto idxs = FocalLengthIdxs(); if (idxs.size() == 1) f = FocalLength(); else if (idxs.size() == 2) { @@ -233,34 +242,29 @@ double Camera::uncertainty(double depth, double var2d) const { } Camera::Camera(py::dict dict) { - // load data - int model_id; - ASSIGN_PYDICT_ITEM(dict, model_id, int); - std::vector params; - ASSIGN_PYDICT_ITEM(dict, params, std::vector); - int cam_id; - ASSIGN_PYDICT_ITEM(dict, cam_id, int); - int height, width; - ASSIGN_PYDICT_ITEM(dict, height, int); - ASSIGN_PYDICT_ITEM(dict, width, int); + // model id + int model_id_loaded; + ASSIGN_PYDICT_ITEM(dict, model_id_loaded, int); + model_id = static_cast(model_id_loaded); - // set camera - SetModelId(model_id); - THROW_CHECK_EQ(params.size(), NumParams()); - SetParams(params); - SetCameraId(cam_id); - SetHeight(height); - SetWidth(width); + // params + std::vector params_loaded; + ASSIGN_PYDICT_ITEM(dict, params_loaded, std::vector); + THROW_CHECK_EQ(params_loaded.size(), params.size()); + params = params_loaded; - // set initialized + // other fields + ASSIGN_PYDICT_ITEM(dict, camera_id, int); + ASSIGN_PYDICT_ITEM(dict, height, int); + ASSIGN_PYDICT_ITEM(dict, width, int); ASSIGN_PYDICT_ITEM(dict, initialized, std::vector); } py::dict Camera::as_dict() const { py::dict output; - output["model_id"] = ModelId(); - output["params"] = params(); - output["cam_id"] = int(CameraId()); + output["model_id"] = int(model_id); + output["params"] = params; + output["cam_id"] = int(camera_id); output["height"] = h(); output["width"] = w(); output["initialized"] = initialized; diff --git a/limap/base/camera.h b/limap/base/camera.h index b0b4bd70..1cc80260 100644 --- a/limap/base/camera.h +++ b/limap/base/camera.h @@ -11,11 +11,11 @@ namespace py = pybind11; #include "_limap/helpers.h" +#include "base/pose.h" #include "util/types.h" -#include -#include -#include +#include +#include namespace limap { @@ -35,13 +35,14 @@ namespace limap { class Camera : public colmap::Camera { public: Camera() { - SetCameraId(-1); - SetModelId(0); - SetHeight(-1); - SetWidth(-1); + camera_id = -1; + model_id = colmap::CameraModelId::kPinhole; + height = -1; + width = -1; } // default + Camera(const colmap::Camera &cam); - Camera(int model_id, const std::vector ¶ms, int cam_id = -1, + Camera(int model, const std::vector ¶ms, int cam_id = -1, std::pair hw = std::make_pair(-1, -1)); Camera(const std::string &model_name, const std::vector ¶ms, int cam_id = -1, @@ -49,13 +50,14 @@ class Camera : public colmap::Camera { // initialize with intrinsics Camera(M3D K, int cam_id = -1, std::pair hw = std::make_pair(-1, -1)); - Camera(int model_id, M3D K, int cam_id = -1, + Camera(int model, M3D K, int cam_id = -1, std::pair hw = std::make_pair(-1, -1)); Camera(const std::string &model_name, M3D K, int cam_id = -1, std::pair hw = std::make_pair(-1, -1)); Camera(py::dict dict); Camera(const Camera &cam); - Camera(int model_id, int cam_id = -1, + Camera &operator=(const Camera &cam); + Camera(int model, int cam_id = -1, std::pair hw = std::make_pair(-1, -1)); // empty camera Camera(const std::string &model_name, int cam_id = -1, @@ -70,18 +72,16 @@ class Camera : public colmap::Camera { void set_max_image_dim(const int &val); M3D K() const { return CalibrationMatrix(); } M3D K_inv() const { return K().inverse(); } - int h() const { return Height(); } - int w() const { return Width(); } - std::vector params() const { return Params(); } + int h() const { return height; } + int w() const { return width; } double uncertainty(double depth, double var2d = 5.0) const; // initialized - void SetModelId(const int model_id); // override - void SetModelIdFromName(const std::string &model_name); // override - void SetParams(const std::vector ¶ms); // override - void InitializeParams(const double focal_length, const int width, - const int height); + void SetModelId(int model); + void SetModelIdFromName(const std::string &model_name); + void SetParams(const std::vector ¶ms); + void InitializeParams(double focal_length, int width, int height); std::vector initialized; bool IsInitialized() const; }; @@ -93,7 +93,7 @@ class CameraPose { : qvec(qvec.normalized()), tvec(tvec), initialized(initialized) {} CameraPose(M3D R, V3D T, bool initiallized = true) : tvec(T), initialized(initialized) { - qvec = colmap::RotationMatrixToQuaternion(R); + qvec = RotationMatrixToQuaternion(R); } CameraPose(py::dict dict); CameraPose(const CameraPose &campose) @@ -105,7 +105,7 @@ class CameraPose { bool initialized = false; py::dict as_dict() const; - M3D R() const { return colmap::QuaternionToRotationMatrix(qvec); } + M3D R() const { return QuaternionToRotationMatrix(qvec); } V3D T() const { return tvec; } V3D center() const { return -R().transpose() * T(); } diff --git a/limap/base/camera_models.h b/limap/base/camera_models.h index f50c9ab3..4c460226 100644 --- a/limap/base/camera_models.h +++ b/limap/base/camera_models.h @@ -1,7 +1,7 @@ #ifndef LIMAP_BASE_CAMERA_MODELS_H_ #define LIMAP_BASE_CAMERA_MODELS_H_ -#include +#include namespace limap { @@ -27,13 +27,14 @@ namespace limap { // Get the 4-dimensional kvec [fx, fy, cx, cy] from the following colmap camera // model colmap camera models: (0, SIMPLE_PINHOLE) (1, PINHOLE) template -void ParamsToKvec(const int model_id, const T *params, T *kvec) { - if (model_id == 0) { // SIMPLE_PINHOLE +void ParamsToKvec(const colmap::CameraModelId model_id, const T *params, + T *kvec) { + if (model_id == colmap::CameraModelId::kSimplePinhole) { // SIMPLE_PINHOLE kvec[0] = params[0]; kvec[1] = params[0]; kvec[2] = params[1]; kvec[3] = params[2]; - } else if (model_id == 1) { // PINHOLE + } else if (model_id == colmap::CameraModelId::kPinhole) { // PINHOLE kvec[0] = params[0]; kvec[1] = params[1]; kvec[2] = params[2]; diff --git a/limap/base/camera_view.cc b/limap/base/camera_view.cc index 4d4c9443..8597bc88 100644 --- a/limap/base/camera_view.cc +++ b/limap/base/camera_view.cc @@ -1,5 +1,5 @@ #include "base/camera_view.h" -#include +#include namespace limap { diff --git a/limap/base/camera_view.h b/limap/base/camera_view.h index 43cd654f..c1dbff37 100644 --- a/limap/base/camera_view.h +++ b/limap/base/camera_view.h @@ -24,15 +24,15 @@ class CameraImage { : cam_id(input_cam_id), pose(CameraPose(false)), image_name_(image_name) { } // empty image CameraImage(const Camera &input_cam, const std::string &image_name = "none") - : cam_id(input_cam.CameraId()), pose(CameraPose(false)), + : cam_id(input_cam.camera_id), pose(CameraPose(false)), image_name_(image_name) {} // empty image CameraImage(const int &input_cam_id, const CameraPose &input_pose, const std::string &image_name = "none") : cam_id(input_cam_id), pose(input_pose), image_name_(image_name) {} CameraImage(const Camera &input_cam, const CameraPose &input_pose, const std::string &image_name = "none") - : cam_id(input_cam.CameraId()), pose(input_pose), - image_name_(image_name) {} + : cam_id(input_cam.camera_id), pose(input_pose), image_name_(image_name) { + } CameraImage(py::dict dict); CameraImage(const CameraImage &camimage) : cam_id(camimage.cam_id), pose(camimage.pose) { diff --git a/limap/base/graph.h b/limap/base/graph.h index 9f9c0e86..b73eae2a 100644 --- a/limap/base/graph.h +++ b/limap/base/graph.h @@ -13,8 +13,8 @@ #include #include -#include "util/log_exceptions.h" #include "util/simple_logger.h" +#include // Copyright (c) 2020, ETH Zurich, CVG, Mihai Dusmanu // (mihai.dusmanu@inf.ethz.ch) Adapted by Philipp Lindenberger for the diff --git a/limap/base/image_collection.cc b/limap/base/image_collection.cc index 53ed25ad..fabdbb08 100644 --- a/limap/base/image_collection.cc +++ b/limap/base/image_collection.cc @@ -1,4 +1,5 @@ #include "base/image_collection.h" +#include namespace limap { @@ -44,11 +45,11 @@ ImageCollection::ImageCollection(const std::vector &camviews) { for (size_t img_id = 0; img_id < n_images; ++img_id) { auto camview = camviews[img_id]; images.insert(std::make_pair(img_id, CameraImage(camview))); - int cam_id = camview.cam.CameraId(); + int cam_id = camview.cam.camera_id; if (exist_cam(cam_id)) { CHECK_EQ(cameras.at(cam_id) == camview.cam, true); } else { - cameras.insert(std::make_pair(camview.cam.CameraId(), camview.cam)); + cameras.insert(std::make_pair(camview.cam.camera_id, camview.cam)); } } } @@ -63,7 +64,7 @@ ImageCollection::ImageCollection(py::dict dict) { for (auto it = dictvec_cameras.begin(); it != dictvec_cameras.end(); ++it) { int cam_id = it->first; Camera cam = Camera(it->second); - assert(cam_id == cam.CameraId()); + assert(cam_id == cam.camera_id); cameras.insert(std::make_pair(cam_id, cam)); } // load images @@ -446,7 +447,7 @@ bool ImageCollection::IsUndistorted() const { double *ImageCollection::params_data(const int img_id) { THROW_CHECK_EQ(exist_image(img_id), true); int cam_id = camimage(img_id).cam_id; - return cameras.at(cam_id).Params().data(); + return cameras.at(cam_id).params.data(); } double *ImageCollection::qvec_data(const int img_id) { @@ -485,10 +486,7 @@ void ImageCollection::init_uninitialized_cameras() { CameraView view = camview(img_id); auto res = view.get_initial_focal_length(); it->second.InitializeParams(res.first, view.w(), view.h()); - if (res.second) - it->second.SetPriorFocalLength(true); - else - it->second.SetPriorFocalLength(false); + it->second.has_prior_focal_length = res.second; } } @@ -498,10 +496,7 @@ void ImageCollection::uninitialize_intrinsics() { CameraView view = camview(img_id); auto res = view.get_initial_focal_length(); it->second.InitializeParams(res.first, view.w(), view.h()); - if (res.second) - it->second.SetPriorFocalLength(true); - else - it->second.SetPriorFocalLength(false); + it->second.has_prior_focal_length = res.second; } } @@ -514,7 +509,8 @@ void ImageCollection::uninitialize_poses() { bool ImageCollection::IsUndistortedCameraModel() const { for (auto it = cameras.begin(); it != cameras.end(); ++it) { - if (it->second.ModelId() != 0 and it->second.ModelId() != 1) + if (it->second.model_id != colmap::CameraModelId::kSimplePinhole and + it->second.model_id != colmap::CameraModelId::kPinhole) return false; } return true; diff --git a/limap/base/infinite_line.cc b/limap/base/infinite_line.cc index 986b6ccf..258c3d13 100644 --- a/limap/base/infinite_line.cc +++ b/limap/base/infinite_line.cc @@ -1,7 +1,8 @@ #include "base/infinite_line.h" +#include "base/pose.h" #include -#include +#include namespace limap { @@ -218,12 +219,12 @@ MinimalInfiniteLine3d::MinimalInfiniteLine3d(const InfiniteLine3d &inf_line) { V3D axb = a.cross(bprime); Q.col(2) = axb / axb.norm(); } - uvec = colmap::RotationMatrixToQuaternion(Q); + uvec = RotationMatrixToQuaternion(Q); } InfiniteLine3d MinimalInfiniteLine3d::GetInfiniteLine() const { // get plucker coordinate - M3D Q = colmap::QuaternionToRotationMatrix(uvec); + M3D Q = QuaternionToRotationMatrix(uvec); V3D d = Q.col(0); V3D m = std::abs(wvec(1)) / std::abs(wvec(0)) * Q.col(1); return InfiniteLine3d(d, m, false); diff --git a/limap/base/infinite_line.h b/limap/base/infinite_line.h index a98af4d7..e5eaba0e 100644 --- a/limap/base/infinite_line.h +++ b/limap/base/infinite_line.h @@ -68,7 +68,7 @@ class MinimalInfiniteLine3d { public: MinimalInfiniteLine3d() {} MinimalInfiniteLine3d(const Line3d &line) - : MinimalInfiniteLine3d(InfiniteLine3d(line)){}; + : MinimalInfiniteLine3d(InfiniteLine3d(line)) {}; MinimalInfiniteLine3d(const InfiniteLine3d &inf_line); MinimalInfiniteLine3d(const std::vector &values); InfiniteLine3d GetInfiniteLine() const; diff --git a/limap/base/line_dists.cc b/limap/base/line_dists.cc index 737f405a..0d1a3583 100644 --- a/limap/base/line_dists.cc +++ b/limap/base/line_dists.cc @@ -90,6 +90,7 @@ double infinite_dist_perpendicular(const Line3d &l1, const Line3d &l2) { q = (A11 * B2 - A21 * B1) / det; } double dist = (C0 + Cp * p + Cq * q).norm(); + return dist; } double infinite_perpendicular_scaleinv_line3dpp(const Line3d &l1, @@ -119,6 +120,7 @@ double infinite_perpendicular_scaleinv_line3dpp(const Line3d &l1, double distsquared = (Ck * k + Cz).squaredNorm() - pow((Ck * k + Cz).dot(v), 2); double dist = sqrt(distsquared); + return dist; } double infinite_dist_perpendicular_scaleinv_line3dpp(const Line3d &l1, @@ -217,6 +219,7 @@ double compute_distance(const Line2d &l1, const Line2d &l2, throw std::runtime_error( "Type error. Scale invariance distance is not supported for Line2d."); } + return -1.0; } template <> @@ -258,6 +261,7 @@ double compute_distance(const Line3d &l1, const Line3d &l2, case LineDistType::ENDPOINTS_SCALEINV: return dist_endpoints_scaleinv(l1, l2); } + return -1.0; } } // namespace limap diff --git a/limap/base/linebase.cc b/limap/base/linebase.cc index 6602727a..697f6d0c 100644 --- a/limap/base/linebase.cc +++ b/limap/base/linebase.cc @@ -1,5 +1,6 @@ #include "base/linebase.h" #include +#include namespace limap { diff --git a/limap/base/linetrack.cc b/limap/base/linetrack.cc index 6473fba8..d00e2b77 100644 --- a/limap/base/linetrack.cc +++ b/limap/base/linetrack.cc @@ -1,6 +1,7 @@ #include "base/linetrack.h" #include "base/line_dists.h" +#include #include #include #include diff --git a/limap/base/pose.cc b/limap/base/pose.cc new file mode 100644 index 00000000..f6fb7b88 --- /dev/null +++ b/limap/base/pose.cc @@ -0,0 +1,30 @@ +#include "base/pose.h" + +#include + +namespace limap { + +Eigen::Vector4d RotationMatrixToQuaternion(const Eigen::Matrix3d &rot_mat) { + const Eigen::Quaterniond quat(rot_mat); + return Eigen::Vector4d(quat.w(), quat.x(), quat.y(), quat.z()); +} + +Eigen::Matrix3d QuaternionToRotationMatrix(const Eigen::Vector4d &qvec) { + const Eigen::Vector4d normalized_qvec = NormalizeQuaternion(qvec); + const Eigen::Quaterniond quat(normalized_qvec(0), normalized_qvec(1), + normalized_qvec(2), normalized_qvec(3)); + return quat.toRotationMatrix(); +} + +Eigen::Vector4d NormalizeQuaternion(const Eigen::Vector4d &qvec) { + const double norm = qvec.norm(); + if (norm == 0) { + // We do not just use (1, 0, 0, 0) because that is a constant and when used + // for automatic differentiation that would lead to a zero derivative. + return Eigen::Vector4d(1.0, qvec(1), qvec(2), qvec(3)); + } else { + return qvec / norm; + } +} + +} // namespace limap diff --git a/limap/base/pose.h b/limap/base/pose.h new file mode 100644 index 00000000..56deb01f --- /dev/null +++ b/limap/base/pose.h @@ -0,0 +1,34 @@ +#ifndef LIMAP_BASE_POSE_H_ +#define LIMAP_BASE_POSE_H_ + +#include + +// Functions copied from COLMAP 3.8 +// TODO: Update all the qvec to Eigen Quaternion as in the new COLMAP + +namespace limap { + +// Convert 3D rotation matrix to Quaternion representation. +// +// @param rot_mat 3x3 rotation matrix. +// +// @return Unit Quaternion rotation coefficients (w, x, y, z). +Eigen::Vector4d RotationMatrixToQuaternion(const Eigen::Matrix3d &rot_mat); + +// Convert Quaternion representation to 3D rotation matrix. +// +// @param qvec Unit Quaternion rotation coefficients (w, x, y, z). +// +// @return 3x3 rotation matrix. +Eigen::Matrix3d QuaternionToRotationMatrix(const Eigen::Vector4d &qvec); + +// Normalize Quaternion vector. +// +// @param qvec Quaternion rotation coefficients (w, x, y, z). +// +// @return Unit Quaternion rotation coefficients (w, x, y, z). +Eigen::Vector4d NormalizeQuaternion(const Eigen::Vector4d &qvec); + +} // namespace limap + +#endif diff --git a/limap/base/transforms.h b/limap/base/transforms.h index bf0f6d7a..6ee4ea7d 100644 --- a/limap/base/transforms.h +++ b/limap/base/transforms.h @@ -1,9 +1,8 @@ #ifndef LIMAP_BASE_TRANSFORMS_H_ #define LIMAP_BASE_TRANSFORMS_H_ -#include - #include "base/camera.h" +#include "base/pose.h" namespace limap { @@ -16,13 +15,13 @@ class SimilarityTransform3 { SimilarityTransform3(V4D qqvec, V3D ttvec, double s = 1.0) : qvec(qqvec), tvec(ttvec), scale(s) {} SimilarityTransform3(M3D R, V3D T, double s = 1.0) : tvec(T), scale(s) { - qvec = colmap::RotationMatrixToQuaternion(R); + qvec = RotationMatrixToQuaternion(R); } V4D qvec = V4D(1., 0., 0., 0.); V3D tvec = V3D::Zero(); double scale = 1.0; - M3D R() const { return colmap::QuaternionToRotationMatrix(qvec); } + M3D R() const { return QuaternionToRotationMatrix(qvec); } V3D T() const { return tvec; } double s() const { return scale; } }; diff --git a/limap/base/unit_test.py b/limap/base/unit_test.py index 84a9c57c..c93b1716 100644 --- a/limap/base/unit_test.py +++ b/limap/base/unit_test.py @@ -1,7 +1,6 @@ -import logging - import _limap._base as _base import numpy as np +from pycolmap import logging def unit_test_add_noise(imagecols): @@ -23,8 +22,8 @@ def report_error(imagecols_pred, imagecols): # cameras camera_errors = [] for cam_id in imagecols.get_cam_ids(): - error = np.array(imagecols_pred.cam(cam_id).params()) - np.array( - imagecols.cam(cam_id).params() + error = np.array(imagecols_pred.cam(cam_id).params) - np.array( + imagecols.cam(cam_id).params ) error = np.abs(error) camera_errors.append(error) diff --git a/limap/ceresbase/interpolation.h b/limap/ceresbase/interpolation.h index 2169f0b9..8a9992e3 100644 --- a/limap/ceresbase/interpolation.h +++ b/limap/ceresbase/interpolation.h @@ -23,8 +23,8 @@ namespace py = pybind11; #include #include -#include "util/log_exceptions.h" #include "util/types.h" +#include namespace limap { diff --git a/limap/ceresbase/line_projection.h b/limap/ceresbase/line_projection.h index c5da39d4..563a02c6 100644 --- a/limap/ceresbase/line_projection.h +++ b/limap/ceresbase/line_projection.h @@ -13,7 +13,7 @@ namespace limap { // line projection (camera frame) in plucker coordinate template -void Line_WorldToImage(const T *kvec, const T *mvec, T *coor) { +void Line_ImgFromCam(const T *kvec, const T *mvec, T *coor) { // K * [m]x * K.transpose() Eigen::Matrix mskew; mskew(0, 0) = T(0.0); @@ -77,22 +77,22 @@ void Line_WorldToPixel(const T *kvec, const T *qvec, const T *tvec, mvec_transformed[0] = mskew_transformed(2, 1); mvec_transformed[1] = mskew_transformed(0, 2); mvec_transformed[2] = mskew_transformed(1, 0); - Line_WorldToImage(kvec, mvec_transformed, coor); + Line_ImgFromCam(kvec, mvec_transformed, coor); } // line projection (camera frame) in normal coordinate template -void Line_WorldToImage_Regular(const T *kvec, const T *p3d, const T *dir3d, - T *p2d, T *dir2d) { +void Line_ImgFromCam_Regular(const T *kvec, const T *p3d, const T *dir3d, + T *p2d, T *dir2d) { T u = p3d[0] / p3d[2]; T v = p3d[1] / p3d[2]; - WorldToImage(kvec, u, v, &p2d[0], &p2d[1]); + ImgFromCam(kvec, u, v, &p2d[0], &p2d[1]); // compute vanishing point T u_vp = dir3d[0] / dir3d[2]; T v_vp = dir3d[1] / dir3d[2]; T xy_vp[2]; - WorldToImage(kvec, u_vp, v_vp, &xy_vp[0], &xy_vp[1]); + ImgFromCam(kvec, u_vp, v_vp, &xy_vp[0], &xy_vp[1]); // compute 2d direction dir2d[0] = xy_vp[0] - p2d[0]; @@ -118,7 +118,7 @@ void Line_WorldToPixel_Regular(const T *kvec, const T *qvec, const T *tvec, ceres::QuaternionRotatePoint(qvec, dir3d, dir_projection); // world to image - Line_WorldToImage_Regular(kvec, p_projection, dir_projection, p2d, dir2d); + Line_ImgFromCam_Regular(kvec, p_projection, dir_projection, p2d, dir2d); } // get direction from vp diff --git a/limap/ceresbase/point_projection.h b/limap/ceresbase/point_projection.h index f5893529..908f7e13 100644 --- a/limap/ceresbase/point_projection.h +++ b/limap/ceresbase/point_projection.h @@ -5,14 +5,11 @@ #include #include -#include -#include -#include namespace limap { template -void ImageToWorld(const T *kvec, const T x, const T y, T *u, T *v) { +void CamFromImg(const T *kvec, const T x, const T y, T *u, T *v) { const T f1 = kvec[0]; const T f2 = kvec[1]; const T c1 = kvec[2]; @@ -23,7 +20,7 @@ void ImageToWorld(const T *kvec, const T x, const T y, T *u, T *v) { } template -void WorldToImage(const T *kvec, const T u, const T v, T *x, T *y) { +void ImgFromCam(const T *kvec, const T u, const T v, T *x, T *y) { const T f1 = kvec[0]; const T f2 = kvec[1]; const T c1 = kvec[2]; @@ -37,7 +34,7 @@ template void PixelToWorld(const T *kvec, const T *qvec, const T *tvec, const T x, const T y, const T *depth, T *xyz) { T local_xyz[3]; - ImageToWorld(kvec, x, y, &local_xyz[0], &local_xyz[1]); + CamFromImg(kvec, x, y, &local_xyz[0], &local_xyz[1]); local_xyz[2] = T(1.0); for (int i = 0; i < 3; i++) { local_xyz[i] = local_xyz[i] * depth[0] - tvec[i]; @@ -59,7 +56,7 @@ inline void WorldToPixel(const T *kvec, const T *qvec, const T *tvec, projection[0] /= projection[2]; // u projection[1] /= projection[2]; // v - WorldToImage(kvec, projection[0], projection[1], &xy[0], &xy[1]); + ImgFromCam(kvec, projection[0], projection[1], &xy[0], &xy[1]); } template inline bool IsInsideZeroL(const T &value, double L) { diff --git a/limap/estimators/absolute_pose/hybrid_pose_estimator.cc b/limap/estimators/absolute_pose/hybrid_pose_estimator.cc index bd2010af..c423c846 100644 --- a/limap/estimators/absolute_pose/hybrid_pose_estimator.cc +++ b/limap/estimators/absolute_pose/hybrid_pose_estimator.cc @@ -81,6 +81,8 @@ double HybridPoseEstimator::EvaluateModelOnPoint(const CameraPose &pose, int t, else if (t == 1) return JointPoseEstimator::EvaluateModelOnPoint(pose, i + num_data_points()); + else + throw std::runtime_error("Error! Not supported!"); } } // namespace absolute_pose diff --git a/limap/estimators/absolute_pose/joint_pose_estimator.cc b/limap/estimators/absolute_pose/joint_pose_estimator.cc index 16d4ab2b..544ce1b2 100644 --- a/limap/estimators/absolute_pose/joint_pose_estimator.cc +++ b/limap/estimators/absolute_pose/joint_pose_estimator.cc @@ -69,7 +69,7 @@ JointPoseEstimator::JointPoseEstimator( l2ds_ = &l2ds; p3ds_ = &p3ds; p2ds_ = &p2ds; - cam_ = Camera(colmap::PinholeCameraModel::model_id, cam.K()); + cam_ = Camera(cam.K()); num_data_ = p3ds.size() + l3d_ids.size(); if (loc_config_.cost_function == E3DLineLineDist2 || @@ -161,7 +161,7 @@ int JointPoseEstimator::NonMinimalSolver(const std::vector &sample, config.weight_line = config.weight_point = 1.0; config.loss_function.reset(new ceres::TrivialLoss()); JointLocEngine loc_engine(config); - V4D kvec = V4D(cam_.Params().data()); + V4D kvec = V4D(cam_.params.data()); loc_engine.Initialize(opt_l3ds, opt_l2ds, opt_p3ds, opt_p2ds, kvec, pose->qvec, pose->tvec); loc_engine.SetUp(); @@ -184,7 +184,7 @@ double JointPoseEstimator::EvaluateModelOnPoint(const CameraPose &pose, return std::numeric_limits::max(); hybridloc::ReprojectionPointFunctor(p3ds_->at(i), p2ds_->at(i), loc_config_.points_3d_dist)( - cam_.Params().data(), pose.qvec.data(), pose.tvec.data(), res); + cam_.params.data(), pose.qvec.data(), pose.tvec.data(), res); return V2D(res[0], res[1]).squaredNorm(); } else { // we sampled a line correspondence @@ -195,11 +195,13 @@ double JointPoseEstimator::EvaluateModelOnPoint(const CameraPose &pose, return std::numeric_limits::max(); hybridloc::ReprojectionLineFunctor(loc_config_.cost_function, ENoneWeight, l3d, l2ds_->at(i))( - cam_.Params().data(), pose.qvec.data(), pose.tvec.data(), res); + cam_.params.data(), pose.qvec.data(), pose.tvec.data(), res); if (getResidualNum(loc_config_.cost_function) == 2) { return V2D(res[0], res[1]).squaredNorm(); } else if (getResidualNum(loc_config_.cost_function) == 4) return V4D(res[0], res[1], res[2], res[3]).squaredNorm(); + else + throw std::runtime_error("Error! Not supported!"); } } @@ -277,7 +279,7 @@ void JointPoseEstimator::LeastSquares(const std::vector &sample, // Here the passed in config is used for LSQ JointLocEngine loc_engine(loc_config_); - V4D kvec = V4D(cam_.Params().data()); + V4D kvec = V4D(cam_.params.data()); loc_engine.Initialize(opt_l3ds, opt_l2ds, opt_p3ds, opt_p2ds, kvec, pose->qvec, pose->tvec); loc_engine.SetUp(); diff --git a/limap/evaluation/refline_evaluator.h b/limap/evaluation/refline_evaluator.h index 3737f4b0..1fca0978 100644 --- a/limap/evaluation/refline_evaluator.h +++ b/limap/evaluation/refline_evaluator.h @@ -14,7 +14,7 @@ class RefLineEvaluator { public: RefLineEvaluator() {} RefLineEvaluator(const std::vector &ref_lines) - : ref_lines_(ref_lines){}; + : ref_lines_(ref_lines) {}; double SumLength() const; double ComputeRecallRef(const std::vector &lines, diff --git a/limap/features/dense_sift.h b/limap/features/dense_sift.h index 1296f1c0..4c2f27e9 100644 --- a/limap/features/dense_sift.h +++ b/limap/features/dense_sift.h @@ -18,8 +18,8 @@ namespace py = pybind11; #include -#include "util/log_exceptions.h" #include "util/simple_logger.h" +#include namespace limap { diff --git a/limap/features/extractors.py b/limap/features/extractors.py index 6989f07e..7d307911 100644 --- a/limap/features/extractors.py +++ b/limap/features/extractors.py @@ -1,6 +1,5 @@ # [NOTE] modified from the pixel-perfect-sfm project -import logging import sys import time @@ -9,6 +8,7 @@ import torch import torchvision.transforms.functional as tvf from _limap import _features +from pycolmap import logging from torchvision import transforms from .models.s2dnet import S2DNet diff --git a/limap/features/featuremap.h b/limap/features/featuremap.h index db25815c..3d047cb6 100644 --- a/limap/features/featuremap.h +++ b/limap/features/featuremap.h @@ -10,8 +10,8 @@ #include #include -#include "util/log_exceptions.h" #include "util/types.h" +#include namespace py = pybind11; diff --git a/limap/features/featurepatch.h b/limap/features/featurepatch.h index 7c9a9bd1..dd7122c5 100644 --- a/limap/features/featurepatch.h +++ b/limap/features/featurepatch.h @@ -6,9 +6,10 @@ #include #include "features/featuremap.h" -#include "util/log_exceptions.h" #include "util/types.h" +#include + namespace py = pybind11; namespace limap { diff --git a/limap/features/models/s2dnet.py b/limap/features/models/s2dnet.py index b712a838..2788234b 100644 --- a/limap/features/models/s2dnet.py +++ b/limap/features/models/s2dnet.py @@ -1,4 +1,3 @@ -import logging import os from pathlib import Path from typing import List @@ -6,6 +5,7 @@ import numpy as np import torch import torch.nn as nn +from pycolmap import logging from torchvision import models from .base_model import BaseModel diff --git a/limap/line2d/DeepLSD/deeplsd.py b/limap/line2d/DeepLSD/deeplsd.py index 5bd09638..2d111eb0 100644 --- a/limap/line2d/DeepLSD/deeplsd.py +++ b/limap/line2d/DeepLSD/deeplsd.py @@ -1,9 +1,9 @@ -import logging import os import numpy as np import torch from deeplsd.models.deeplsd_inference import DeepLSD +from pycolmap import logging from ..base_detector import ( BaseDetector, diff --git a/limap/line2d/GlueStick/matcher.py b/limap/line2d/GlueStick/matcher.py index eac0e9cf..9492f419 100644 --- a/limap/line2d/GlueStick/matcher.py +++ b/limap/line2d/GlueStick/matcher.py @@ -1,9 +1,9 @@ -import logging import os import numpy as np import torch from gluestick.models.gluestick import GlueStick +from pycolmap import logging from ..base_matcher import ( BaseMatcher, diff --git a/limap/line2d/HAWPv3/hawp.py b/limap/line2d/HAWPv3/hawp.py index ea9aefa5..f5765d80 100644 --- a/limap/line2d/HAWPv3/hawp.py +++ b/limap/line2d/HAWPv3/hawp.py @@ -1,4 +1,3 @@ -import logging import os import cv2 @@ -6,6 +5,7 @@ import torch from hawp.fsl.config import cfg as model_config from hawp.ssl.models import MODELS +from pycolmap import logging from ..base_detector import ( BaseDetector, diff --git a/limap/line2d/L2D2/extractor.py b/limap/line2d/L2D2/extractor.py index 8d122351..fceac1bb 100644 --- a/limap/line2d/L2D2/extractor.py +++ b/limap/line2d/L2D2/extractor.py @@ -1,9 +1,9 @@ -import logging import os import cv2 import numpy as np import torch +from pycolmap import logging import limap.util.io as limapio diff --git a/limap/line2d/LineTR/line_transformer.py b/limap/line2d/LineTR/line_transformer.py index e733b247..0d4dd240 100755 --- a/limap/line2d/LineTR/line_transformer.py +++ b/limap/line2d/LineTR/line_transformer.py @@ -1,9 +1,9 @@ -import logging from copy import deepcopy from pathlib import Path import torch from einops import repeat +from pycolmap import logging from torch import nn from .line_attention import FeedForward, MultiHeadAttention diff --git a/limap/line2d/SOLD2/misc/train_utils.py b/limap/line2d/SOLD2/misc/train_utils.py index 470f0a8e..1a763dac 100644 --- a/limap/line2d/SOLD2/misc/train_utils.py +++ b/limap/line2d/SOLD2/misc/train_utils.py @@ -2,11 +2,11 @@ This file contains some useful functions for train / val. """ -import logging import os import numpy as np import torch +from pycolmap import logging ################# diff --git a/limap/line2d/SOLD2/model/model_util.py b/limap/line2d/SOLD2/model/model_util.py index b638219a..55fd6420 100644 --- a/limap/line2d/SOLD2/model/model_util.py +++ b/limap/line2d/SOLD2/model/model_util.py @@ -1,7 +1,6 @@ -import logging - import torch.nn as nn import torch.nn.init as init +from pycolmap import logging from .nets.backbone import HourglassBackbone, SuperpointBackbone from .nets.descriptor_decoder import SuperpointDescriptor diff --git a/limap/line2d/SOLD2/sold2_wrapper.py b/limap/line2d/SOLD2/sold2_wrapper.py index 648a6733..6088eb35 100644 --- a/limap/line2d/SOLD2/sold2_wrapper.py +++ b/limap/line2d/SOLD2/sold2_wrapper.py @@ -1,10 +1,10 @@ -import logging import os import subprocess import cv2 import numpy as np import torch +from pycolmap import logging from skimage.draw import line from .experiment import load_config diff --git a/limap/line2d/SOLD2/train.py b/limap/line2d/SOLD2/train.py index 522868ef..7585bc8c 100644 --- a/limap/line2d/SOLD2/train.py +++ b/limap/line2d/SOLD2/train.py @@ -2,12 +2,11 @@ This file implements the training process and all the summaries """ -import logging - import cv2 import numpy as np import torch import torch.utils.data.dataloader as torch_loader +from pycolmap import logging from torch.nn.functional import pixel_shuffle, softmax # from model.lr_scheduler import get_lr_scheduler diff --git a/limap/line2d/TP_LSD/tp_lsd.py b/limap/line2d/TP_LSD/tp_lsd.py index 73114199..796810f7 100644 --- a/limap/line2d/TP_LSD/tp_lsd.py +++ b/limap/line2d/TP_LSD/tp_lsd.py @@ -1,9 +1,9 @@ -import logging import os import cv2 import numpy as np import torch +from pycolmap import logging from tp_lsd.modeling.TP_Net import Res320 from tp_lsd.utils.reconstruct import TPS_line from tp_lsd.utils.utils import load_model diff --git a/limap/merging/aggregator.cc b/limap/merging/aggregator.cc index 0857b13f..dca40db9 100644 --- a/limap/merging/aggregator.cc +++ b/limap/merging/aggregator.cc @@ -1,4 +1,5 @@ #include "merging/aggregator.h" +#include namespace limap { diff --git a/limap/merging/merging.cc b/limap/merging/merging.cc index ef4d7540..df8d2fa0 100644 --- a/limap/merging/merging.cc +++ b/limap/merging/merging.cc @@ -7,6 +7,7 @@ #include "util/types.h" #include +#include #include #include diff --git a/limap/merging/merging.py b/limap/merging/merging.py index a22fbc24..65286d8d 100644 --- a/limap/merging/merging.py +++ b/limap/merging/merging.py @@ -1,7 +1,6 @@ -import logging - from _limap import _base from _limap import _merging as _mrg +from pycolmap import logging def merging(linker, all_2d_segs, imagecols, seg3d_list, neighbors, var2d=5.0): @@ -37,8 +36,8 @@ def remerge(linker3d, linetracks, num_outliers=2): break num_tracks = num_tracks_new logging.info( - f"[LOG] tracks after iterative remerging: \ - {len(new_linetracks)} / {len(linetracks)}" + f"[LOG] tracks after iterative remerging:" + f" {len(new_linetracks)} / {len(linetracks)}" ) return new_linetracks diff --git a/limap/optimize/global_pl_association/cost_functions.h b/limap/optimize/global_pl_association/cost_functions.h index 0b0281fb..79817188 100644 --- a/limap/optimize/global_pl_association/cost_functions.h +++ b/limap/optimize/global_pl_association/cost_functions.h @@ -39,7 +39,7 @@ template struct PointGeometricRefinementFunctor { const double *tvec = NULL) { if (!params && !qvec && !tvec) return new ceres::AutoDiffCostFunction( + 3, CameraModel::num_params, 4, 3>( new PointGeometricRefinementFunctor(p2d, NULL, NULL, NULL)); else return new ceres::AutoDiffCostFunction struct PointGeometricRefinementFunctor { CHECK_NOTNULL(qvec_); CHECK_NOTNULL(tvec_); - const int num_params = CameraModel::kNumParams; + const int num_params = CameraModel::num_params; T params[num_params]; for (size_t i = 0; i < num_params; ++i) { params[i] = T(params_[i]); diff --git a/limap/optimize/global_pl_association/global_associator.cc b/limap/optimize/global_pl_association/global_associator.cc index 573ff36d..e965ee28 100644 --- a/limap/optimize/global_pl_association/global_associator.cc +++ b/limap/optimize/global_pl_association/global_associator.cc @@ -7,7 +7,7 @@ #include "optimize/line_refinement/cost_functions.h" #include -#include +#include #include #include #include @@ -539,9 +539,7 @@ bool GlobalAssociator::Solve() { } if (config_.print_summary) { - colmap::PrintHeading2("Optimization report"); - colmap::PrintSolverSummary( - summary_); // We need to replace this with our own Printer!!! + colmap::PrintSolverSummary(summary_, "Optimization report"); } return true; } diff --git a/limap/optimize/hybrid_bundle_adjustment/cost_functions.h b/limap/optimize/hybrid_bundle_adjustment/cost_functions.h index 5aaa6650..13183119 100644 --- a/limap/optimize/hybrid_bundle_adjustment/cost_functions.h +++ b/limap/optimize/hybrid_bundle_adjustment/cost_functions.h @@ -39,7 +39,7 @@ template struct PointGeometricRefinementFunctor { const double *tvec = NULL) { if (!params && !qvec && !tvec) return new ceres::AutoDiffCostFunction( + 3, CameraModel::num_params, 4, 3>( new PointGeometricRefinementFunctor(p2d, NULL, NULL, NULL)); else return new ceres::AutoDiffCostFunction struct PointGeometricRefinementFunctor { CHECK_NOTNULL(qvec_); CHECK_NOTNULL(tvec_); - const int num_params = CameraModel::kNumParams; + const int num_params = CameraModel::num_params; T params[num_params]; for (size_t i = 0; i < num_params; ++i) { params[i] = T(params_[i]); diff --git a/limap/optimize/hybrid_bundle_adjustment/hybrid_bundle_adjustment.cc b/limap/optimize/hybrid_bundle_adjustment/hybrid_bundle_adjustment.cc index 3b78b85f..627acaba 100644 --- a/limap/optimize/hybrid_bundle_adjustment/hybrid_bundle_adjustment.cc +++ b/limap/optimize/hybrid_bundle_adjustment/hybrid_bundle_adjustment.cc @@ -4,8 +4,7 @@ #include "optimize/hybrid_bundle_adjustment/cost_functions.h" #include "optimize/line_refinement/cost_functions.h" -#include -#include +#include #include #include #include @@ -72,11 +71,10 @@ void HybridBAEngine::ParameterizeCameras() { } else if (config_.constant_principal_point) { int cam_id = imagecols_.camimage(img_id).cam_id; std::vector const_idxs; - const std::vector &principal_point_idxs = - imagecols_.cam(cam_id).PrincipalPointIdxs(); + auto principal_point_idxs = imagecols_.cam(cam_id).PrincipalPointIdxs(); const_idxs.insert(const_idxs.end(), principal_point_idxs.begin(), principal_point_idxs.end()); - SetSubsetManifold(imagecols_.cam(cam_id).params().size(), const_idxs, + SetSubsetManifold(imagecols_.cam(cam_id).params.size(), const_idxs, problem_.get(), params_data); } @@ -132,13 +130,13 @@ void HybridBAEngine::AddPointGeometricResiduals(const int track_id) { config_.point_geometric_loss_function.get(); for (size_t i = 0; i < track.count_images(); ++i) { int img_id = track.image_id_list[i]; - int model_id = imagecols_.camview(img_id).cam.ModelId(); + auto model_id = imagecols_.camview(img_id).cam.model_id; V2D p2d = track.p2d_list[i]; ceres::CostFunction *cost_function = nullptr; switch (model_id) { #define CAMERA_MODEL_CASE(CameraModel) \ - case CameraModel::kModelId: \ + case CameraModel::model_id: \ cost_function = PointGeometricRefinementFunctor::Create( \ p2d, NULL, NULL, NULL); \ break; @@ -170,7 +168,7 @@ void HybridBAEngine::AddLineGeometricResiduals(const int track_id) { std::vector image_ids = track.GetSortedImageIds(); for (auto it1 = image_ids.begin(); it1 != image_ids.end(); ++it1) { int img_id = *it1; - int model_id = imagecols_.camview(img_id).cam.ModelId(); + auto model_id = imagecols_.camview(img_id).cam.model_id; const auto &ids = idmap.at(img_id); for (auto it2 = ids.begin(); it2 != ids.end(); ++it2) { const Line2d &line = track.line2d_list[*it2]; @@ -179,7 +177,7 @@ void HybridBAEngine::AddLineGeometricResiduals(const int track_id) { switch (model_id) { #define CAMERA_MODEL_CASE(CameraModel) \ - case CameraModel::kModelId: \ + case CameraModel::model_id: \ cost_function = \ line_refinement::GeometricRefinementFunctor::Create( \ line, NULL, NULL, NULL, config_.geometric_alpha); \ @@ -260,9 +258,7 @@ bool HybridBAEngine::Solve() { } if (config_.print_summary) { - colmap::PrintHeading2("Optimization report"); - colmap::PrintSolverSummary( - summary_); // We need to replace this with our own Printer!!! + colmap::PrintSolverSummary(summary_, "Optimization report"); } return true; } diff --git a/limap/optimize/hybrid_localization/hybrid_localization.cc b/limap/optimize/hybrid_localization/hybrid_localization.cc index ac209018..cd3b3350 100644 --- a/limap/optimize/hybrid_localization/hybrid_localization.cc +++ b/limap/optimize/hybrid_localization/hybrid_localization.cc @@ -2,7 +2,7 @@ #include "ceresbase/parameterization.h" #include "optimize/hybrid_localization/cost_functions.h" -#include +#include #include #include #include @@ -14,7 +14,7 @@ namespace optimize { namespace hybrid_localization { void LineLocEngine::ParameterizeCamera() { - double *kvec_data = cam.Params().data(); + double *kvec_data = cam.params.data(); double *qvec_data = campose.qvec.data(); double *tvec_data = campose.tvec.data(); @@ -45,7 +45,7 @@ void LineLocEngine::AddResiduals() { ceres::LossFunction *scaled_loss_function = new ceres::ScaledLoss( loss_function, weight, ceres::DO_NOT_TAKE_OWNERSHIP); ceres::ResidualBlockId block_id = problem_->AddResidualBlock( - cost_function, scaled_loss_function, cam.Params().data(), + cost_function, scaled_loss_function, cam.params.data(), campose.qvec.data(), campose.tvec.data()); } } @@ -83,15 +83,14 @@ bool LineLocEngine::Solve() { } if (config_.print_summary) { - colmap::PrintHeading2("Optimization report"); - colmap::PrintSolverSummary( - summary_); // We need to replace this with our own Printer!!! + colmap::PrintSolverSummary(summary_, "Optimization report"); } return true; } void JointLocEngine::AddResiduals() { - CHECK_EQ(this->cam.ModelId(), colmap::PinholeCameraModel::model_id); + CHECK_EQ(static_cast(this->cam.model_id), + static_cast(colmap::PinholeCameraModel::model_id)); // ceres::LossFunction* loss_function = new ceres::CauchyLoss(0.1); ceres::LossFunction *loss_function = this->config_.loss_function.get(); @@ -118,7 +117,7 @@ void JointLocEngine::AddResiduals() { ceres::LossFunction *scaled_loss_function = new ceres::ScaledLoss( loss_function, weight, ceres::DO_NOT_TAKE_OWNERSHIP); ceres::ResidualBlockId block_id = this->problem_->AddResidualBlock( - cost_function, scaled_loss_function, this->cam.Params().data(), + cost_function, scaled_loss_function, this->cam.params.data(), this->campose.qvec.data(), this->campose.tvec.data()); } } @@ -129,7 +128,7 @@ void JointLocEngine::AddResiduals() { ceres::CostFunction *cost_function = ReprojectionPointFunctor::Create( this->p3ds[i], this->p2ds[i], this->config_.points_3d_dist); ceres::ResidualBlockId block_id = this->problem_->AddResidualBlock( - cost_function, weighted_loss_function, this->cam.Params().data(), + cost_function, weighted_loss_function, this->cam.params.data(), this->campose.qvec.data(), this->campose.tvec.data()); } } diff --git a/limap/optimize/hybrid_localization/hybrid_localization.h b/limap/optimize/hybrid_localization/hybrid_localization.h index ff5fcfec..af8e7ba1 100644 --- a/limap/optimize/hybrid_localization/hybrid_localization.h +++ b/limap/optimize/hybrid_localization/hybrid_localization.h @@ -46,7 +46,7 @@ class LineLocEngine { CHECK_EQ(l3ds.size(), l2ds.size()); this->l3ds = l3ds; this->l2ds = l2ds; - this->cam = Camera(colmap::PinholeCameraModel::model_id, K); + this->cam = Camera(K); this->campose = CameraPose(R, T); } void Initialize(const std::vector &l3ds, @@ -60,7 +60,7 @@ class LineLocEngine { K(1, 1) = kvec(1); K(0, 2) = kvec(2); K(1, 2) = kvec(3); - this->cam = Camera(colmap::PinholeCameraModel::model_id, K); + this->cam = Camera(K); this->campose = CameraPose(qvec, tvec); } void SetUp(); @@ -103,7 +103,7 @@ class JointLocEngine : public LineLocEngine { this->p2ds = p2ds; this->l3ds = l3ds; this->l2ds = l2ds; - this->cam = Camera(colmap::PinholeCameraModel::model_id, K); + this->cam = Camera(K); this->campose = CameraPose(R, T); } void Initialize(const std::vector &l3ds, @@ -121,7 +121,7 @@ class JointLocEngine : public LineLocEngine { K(1, 1) = kvec(1); K(0, 2) = kvec(2); K(1, 2) = kvec(3); - this->cam = Camera(colmap::PinholeCameraModel::model_id, K); + this->cam = Camera(K); this->campose = CameraPose(qvec, tvec); } }; diff --git a/limap/optimize/line_refinement/cost_functions.h b/limap/optimize/line_refinement/cost_functions.h index 33b4d349..3d053915 100644 --- a/limap/optimize/line_refinement/cost_functions.h +++ b/limap/optimize/line_refinement/cost_functions.h @@ -6,7 +6,7 @@ #include #include -#include +#include #include "base/camera_models.h" #include "base/infinite_line.h" @@ -43,7 +43,7 @@ template struct VPConstraintsFunctor { const double *qvec = NULL) { if (!params && !qvec) return new ceres::AutoDiffCostFunction( + CameraModel::num_params, 4>( new VPConstraintsFunctor(VP, NULL, NULL)); else return new ceres::AutoDiffCostFunction( @@ -56,7 +56,7 @@ template struct VPConstraintsFunctor { CHECK_NOTNULL(params_); CHECK_NOTNULL(qvec_); - const int num_params = CameraModel::kNumParams; + const int num_params = CameraModel::num_params; T params[num_params]; for (size_t i = 0; i < num_params; ++i) { params[i] = T(params_[i]); @@ -143,7 +143,7 @@ template struct GeometricRefinementFunctor { const double alpha = 10.0) { if (!params && !qvec && !tvec) return new ceres::AutoDiffCostFunction( + 2, CameraModel::num_params, 4, 3>( new GeometricRefinementFunctor(line2d, NULL, NULL, NULL, alpha)); else return new ceres::AutoDiffCostFunction struct GeometricRefinementFunctor { CHECK_NOTNULL(qvec_); CHECK_NOTNULL(tvec_); - const int num_params = CameraModel::kNumParams; + const int num_params = CameraModel::num_params; T params[num_params]; for (size_t i = 0; i < num_params; ++i) { params[i] = T(params_[i]); diff --git a/limap/optimize/line_refinement/line_refinement.py b/limap/optimize/line_refinement/line_refinement.py index 9b546741..9c7a854b 100644 --- a/limap/optimize/line_refinement/line_refinement.py +++ b/limap/optimize/line_refinement/line_refinement.py @@ -1,7 +1,7 @@ -import logging import os import numpy as np +from pycolmap import logging from tqdm import tqdm import limap.base as base diff --git a/limap/optimize/line_refinement/pixel_cost_functions.h b/limap/optimize/line_refinement/pixel_cost_functions.h index 75a5ae89..bb927f61 100644 --- a/limap/optimize/line_refinement/pixel_cost_functions.h +++ b/limap/optimize/line_refinement/pixel_cost_functions.h @@ -6,7 +6,7 @@ #include #include -#include +#include #include "base/camera_models.h" #include "base/infinite_line.h" @@ -48,7 +48,7 @@ template struct MaxHeatmapFunctor { const double *tvec = NULL) { if (!params && !qvec && !tvec) return new ceres::AutoDiffCostFunction( new MaxHeatmapFunctor(interpolator, samples, NULL, NULL, NULL), samples.size()); @@ -66,7 +66,7 @@ template struct MaxHeatmapFunctor { CHECK_NOTNULL(qvec_); CHECK_NOTNULL(tvec_); - const int num_params = CameraModel::kNumParams; + const int num_params = CameraModel::num_params; T params[num_params]; for (size_t i = 0; i < num_params; ++i) { params[i] = T(params_[i]); @@ -130,7 +130,7 @@ struct FeatureConsisSrcFunctor { if (!params && !qvec && !tvec) return new ceres::AutoDiffCostFunction( + CameraModel::num_params, 4, 3>( new FeatureConsisSrcFunctor(interpolator, sample, ref_descriptor, NULL, NULL, NULL), CHANNELS); @@ -149,7 +149,7 @@ struct FeatureConsisSrcFunctor { CHECK_NOTNULL(qvec_); CHECK_NOTNULL(tvec_); - const int num_params = CameraModel::kNumParams; + const int num_params = CameraModel::num_params; T params[num_params]; for (size_t i = 0; i < num_params; ++i) { params[i] = T(params_[i]); @@ -223,7 +223,7 @@ struct FeatureConsisTgtFunctor { !tvec_tgt) return new ceres::AutoDiffCostFunction< FeatureConsisTgtFunctor, ceres::DYNAMIC, 4, 2, - CameraModelRef::kNumParams, 4, 3, CameraModelTgt::kNumParams, 4, 3>( + CameraModelRef::num_params, 4, 3, CameraModelTgt::num_params, 4, 3>( new FeatureConsisTgtFunctor(interpolator_ref, interpolator_tgt, sample, ref_descriptor, NULL, NULL, NULL, NULL, NULL, NULL), @@ -242,7 +242,7 @@ struct FeatureConsisTgtFunctor { bool intersect(const T *const uvec, const T *const wvec, T *intersection) const { // get kvec_ref - const int num_params_ref = CameraModelRef::kNumParams; + const int num_params_ref = CameraModelRef::num_params; T params_ref[num_params_ref]; for (size_t i = 0; i < num_params_ref; ++i) { params_ref[i] = T(params_ref_[i]); @@ -274,14 +274,14 @@ struct FeatureConsisTgtFunctor { CHECK_NOTNULL(tvec_tgt_); // get kvec_ref and kvec_tgt - const int num_params_ref = CameraModelRef::kNumParams; + const int num_params_ref = CameraModelRef::num_params; T params_ref[num_params_ref]; for (size_t i = 0; i < num_params_ref; ++i) { params_ref[i] = T(params_ref_[i]); } T kvec_ref[4]; ParamsToKvec(CameraModelRef::model_id, params_ref, kvec_ref); - const int num_params_tgt = CameraModelTgt::kNumParams; + const int num_params_tgt = CameraModelTgt::num_params; T params_tgt[num_params_tgt]; for (size_t i = 0; i < num_params_tgt; ++i) { params_tgt[i] = T(params_tgt_[i]); @@ -315,14 +315,14 @@ struct FeatureConsisTgtFunctor { CHECK_NOTNULL(tvec_tgt_); // get kvec_ref and kvec_tgt - const int num_params_ref = CameraModelRef::kNumParams; + const int num_params_ref = CameraModelRef::num_params; T params_ref[num_params_ref]; for (size_t i = 0; i < num_params_ref; ++i) { params_ref[i] = T(params_ref_[i]); } T kvec_ref[4]; ParamsToKvec(CameraModelRef::model_id, params_ref, kvec_ref); - const int num_params_tgt = CameraModelTgt::kNumParams; + const int num_params_tgt = CameraModelTgt::num_params; T params_tgt[num_params_tgt]; for (size_t i = 0; i < num_params_tgt; ++i) { params_tgt[i] = T(params_tgt_[i]); diff --git a/limap/optimize/line_refinement/refine.cc b/limap/optimize/line_refinement/refine.cc index adf2e44c..9125c6cf 100644 --- a/limap/optimize/line_refinement/refine.cc +++ b/limap/optimize/line_refinement/refine.cc @@ -4,7 +4,7 @@ #include "ceresbase/parameterization.h" #include "optimize/line_refinement/cost_functions.h" -#include +#include #include #include #include @@ -63,11 +63,11 @@ void RefinementEngine::AddGeometricResiduals() { double weight = weights[*it]; ceres::CostFunction *cost_function = nullptr; - switch (view.cam.ModelId()) { + switch (view.cam.model_id) { #define CAMERA_MODEL_CASE(CameraModel) \ - case CameraModel::kModelId: \ + case CameraModel::model_id: \ cost_function = GeometricRefinementFunctor::Create( \ - line, view.cam.Params().data(), view.pose.qvec.data(), \ + line, view.cam.params.data(), view.pose.qvec.data(), \ view.pose.tvec.data(), config_.geometric_alpha); \ break; LIMAP_UNDISTORTED_CAMERA_MODEL_SWITCH_CASES @@ -105,11 +105,11 @@ void RefinementEngine::AddVPResiduals() { double weight = weights[*it] * config_.vp_multiplier; ceres::CostFunction *cost_function = nullptr; - switch (view.cam.ModelId()) { + switch (view.cam.model_id) { #define CAMERA_MODEL_CASE(CameraModel) \ - case CameraModel::kModelId: \ + case CameraModel::model_id: \ cost_function = VPConstraintsFunctor::Create( \ - vp, view.cam.Params().data(), view.pose.qvec.data()); \ + vp, view.cam.params.data(), view.pose.qvec.data()); \ break; LIMAP_UNDISTORTED_CAMERA_MODEL_SWITCH_CASES #undef CAMERA_MODEL_CASE @@ -171,9 +171,7 @@ bool RefinementEngine::Solve() { ceres::Solve(solver_options, problem_.get(), &summary_); if (config_.print_summary) { - colmap::PrintHeading2("Optimization report"); - colmap::PrintSolverSummary( - summary_); // We need to replace this with our own Printer!!! + colmap::PrintSolverSummary(summary_, "Optimization report"); } return true; } @@ -341,11 +339,11 @@ void RefinementEngine::AddHeatmapResiduals() { double(config_.n_samples_heatmap / 10.0); ceres::CostFunction *cost_function = nullptr; - switch (view.cam.ModelId()) { + switch (view.cam.model_id) { #define CAMERA_MODEL_CASE(CameraModel) \ - case CameraModel::kModelId: \ + case CameraModel::model_id: \ cost_function = MaxHeatmapFunctor::Create( \ - p_heatmaps_itp_[i], samples, view.cam.Params().data(), \ + p_heatmaps_itp_[i], samples, view.cam.params.data(), \ view.pose.qvec.data(), view.pose.tvec.data()); \ break; LIMAP_UNDISTORTED_CAMERA_MODEL_SWITCH_CASES @@ -403,7 +401,7 @@ void RefinementEngine::AddFeatureConsistencyResiduals() { ref_descriptor = new double[CHANNELS]; V2D ref_intersection; double kvec_ref[4]; - ParamsToKvec(view_ref.cam.ModelId(), view_ref.cam.Params().data(), + ParamsToKvec(view_ref.cam.model_id, view_ref.cam.params.data(), kvec_ref); Ceres_GetIntersection2dFromInfiniteLine3d( inf_line_.uvec.data(), inf_line_.wvec.data(), kvec_ref, @@ -420,21 +418,21 @@ void RefinementEngine::AddFeatureConsistencyResiduals() { // source residuals ceres::CostFunction *cost_function = nullptr; - switch (view_ref.cam.ModelId()) { + switch (view_ref.cam.model_id) { #define CAMERA_MODEL_CASE(CameraModel) \ - case CameraModel::kModelId: \ + case CameraModel::model_id: \ if (use_patches) { \ cost_function = FeatureConsisSrcFunctor< \ CameraModel, features::PatchInterpolator, \ CHANNELS>::Create(p_patches_itp_[ref_index], sample, ref_descriptor, \ - view_ref.cam.Params().data(), \ + view_ref.cam.params.data(), \ view_ref.pose.qvec.data(), \ view_ref.pose.tvec.data()); \ } else { \ cost_function = FeatureConsisSrcFunctor< \ CameraModel, features::FeatureInterpolator, \ CHANNELS>::Create(p_features_itp_[ref_index], sample, \ - ref_descriptor, view_ref.cam.Params().data(), \ + ref_descriptor, view_ref.cam.params.data(), \ view_ref.pose.qvec.data(), \ view_ref.pose.tvec.data()); \ } \ @@ -459,23 +457,23 @@ void RefinementEngine::AddFeatureConsistencyResiduals() { ceres::CostFunction *cost_function = nullptr; // switch 2x2 = 4 camera model configurations - switch (view_ref.cam.ModelId()) { + switch (view_ref.cam.model_id) { // reference camera model == colmap::SimplePinholeCameraModel - case colmap::SimplePinholeCameraModel::kModelId: - switch (view_tgt.cam.ModelId()) { + case colmap::SimplePinholeCameraModel::model_id: + switch (view_tgt.cam.model_id) { #define CAMERA_MODEL_CASE(CameraModel) \ - case CameraModel::kModelId: \ + case CameraModel::model_id: \ if (use_patches) { \ cost_function = FeatureConsisTgtFunctor< \ colmap::SimplePinholeCameraModel, CameraModel, \ features::PatchInterpolator, \ CHANNELS>::Create(p_patches_itp_[ref_index], \ p_patches_itp_[tgt_index], sample, ref_descriptor, \ - view_ref.cam.Params().data(), \ + view_ref.cam.params.data(), \ view_ref.pose.qvec.data(), \ view_ref.pose.tvec.data(), \ - view_tgt.cam.Params().data(), \ + view_tgt.cam.params.data(), \ view_tgt.pose.qvec.data(), \ view_tgt.pose.tvec.data()); \ } else { \ @@ -484,10 +482,10 @@ void RefinementEngine::AddFeatureConsistencyResiduals() { features::FeatureInterpolator, \ CHANNELS>::Create(p_features_itp_[ref_index], \ p_features_itp_[tgt_index], sample, \ - ref_descriptor, view_ref.cam.Params().data(), \ + ref_descriptor, view_ref.cam.params.data(), \ view_ref.pose.qvec.data(), \ view_ref.pose.tvec.data(), \ - view_tgt.cam.Params().data(), \ + view_tgt.cam.params.data(), \ view_tgt.pose.qvec.data(), \ view_tgt.pose.tvec.data()); \ } \ @@ -496,21 +494,21 @@ void RefinementEngine::AddFeatureConsistencyResiduals() { #undef CAMERA_MODEL_CASE } // reference camera model == colmap::PinholeCameraModel - case colmap::PinholeCameraModel::kModelId: - switch (view_tgt.cam.ModelId()) { + case colmap::PinholeCameraModel::model_id: + switch (view_tgt.cam.model_id) { #define CAMERA_MODEL_CASE(CameraModel) \ - case CameraModel::kModelId: \ + case CameraModel::model_id: \ if (use_patches) { \ cost_function = FeatureConsisTgtFunctor< \ colmap::PinholeCameraModel, CameraModel, \ features::PatchInterpolator, \ CHANNELS>::Create(p_patches_itp_[ref_index], \ p_patches_itp_[tgt_index], sample, ref_descriptor, \ - view_ref.cam.Params().data(), \ + view_ref.cam.params.data(), \ view_ref.pose.qvec.data(), \ view_ref.pose.tvec.data(), \ - view_tgt.cam.Params().data(), \ + view_tgt.cam.params.data(), \ view_tgt.pose.qvec.data(), \ view_tgt.pose.tvec.data()); \ } else { \ @@ -519,10 +517,10 @@ void RefinementEngine::AddFeatureConsistencyResiduals() { features::FeatureInterpolator, \ CHANNELS>::Create(p_features_itp_[ref_index], \ p_features_itp_[tgt_index], sample, \ - ref_descriptor, view_ref.cam.Params().data(), \ + ref_descriptor, view_ref.cam.params.data(), \ view_ref.pose.qvec.data(), \ view_ref.pose.tvec.data(), \ - view_tgt.cam.Params().data(), \ + view_tgt.cam.params.data(), \ view_tgt.pose.qvec.data(), \ view_tgt.pose.tvec.data()); \ } \ @@ -573,8 +571,7 @@ RefinementEngine::GetHeatmapIntersections( for (auto it2 = samples.begin(); it2 != samples.end(); ++it2) { V2D intersection; double kvec[4]; - ParamsToKvec(view.cam.ModelId(), view.cam.Params().data(), - kvec); + ParamsToKvec(view.cam.model_id, view.cam.params.data(), kvec); Ceres_GetIntersection2dFromInfiniteLine3d( inf_line.uvec.data(), inf_line.wvec.data(), kvec, view.pose.qvec.data(), view.pose.tvec.data(), it2->coords.data(), @@ -623,7 +620,7 @@ RefinementEngine::GetFConsistencyIntersections( std::vector> out_samples_idx; V2D ref_intersection; double kvec_ref[4]; - ParamsToKvec(view_ref.cam.ModelId(), view_ref.cam.Params().data(), + ParamsToKvec(view_ref.cam.model_id, view_ref.cam.params.data(), kvec_ref); Ceres_GetIntersection2dFromInfiniteLine3d( inf_line.uvec.data(), inf_line.wvec.data(), kvec_ref, @@ -638,9 +635,9 @@ RefinementEngine::GetFConsistencyIntersections( V3D epiline_coord; V2D tgt_intersection; double kvec_ref[4], kvec_tgt[4]; - ParamsToKvec(view_ref.cam.ModelId(), view_ref.cam.Params().data(), + ParamsToKvec(view_ref.cam.model_id, view_ref.cam.params.data(), kvec_ref); - ParamsToKvec(view_tgt.cam.ModelId(), view_tgt.cam.Params().data(), + ParamsToKvec(view_tgt.cam.model_id, view_tgt.cam.params.data(), kvec_tgt); GetEpipolarLineCoordinate( kvec_ref, view_ref.pose.qvec.data(), view_ref.pose.tvec.data(), diff --git a/limap/point2d/superglue/superglue.py b/limap/point2d/superglue/superglue.py index 4457bdb4..f4e5942f 100644 --- a/limap/point2d/superglue/superglue.py +++ b/limap/point2d/superglue/superglue.py @@ -40,13 +40,13 @@ # --------------------------------------------------------------------*/ # %BANNER_END% -import logging import os from copy import deepcopy from pathlib import Path from typing import List, Tuple import torch +from pycolmap import logging from torch import nn diff --git a/limap/point2d/superpoint/main.py b/limap/point2d/superpoint/main.py index e4e6fcb5..8735f992 100644 --- a/limap/point2d/superpoint/main.py +++ b/limap/point2d/superpoint/main.py @@ -1,5 +1,4 @@ import collections.abc as collections -import logging import pprint from pathlib import Path from typing import Dict, List, Optional, Union @@ -9,6 +8,7 @@ import torch from hloc import extract_features from hloc.utils.io import list_h5_names +from pycolmap import logging from tqdm import tqdm from .superpoint import SuperPoint diff --git a/limap/point2d/superpoint/superpoint.py b/limap/point2d/superpoint/superpoint.py index c164ec0f..833a60e0 100644 --- a/limap/point2d/superpoint/superpoint.py +++ b/limap/point2d/superpoint/superpoint.py @@ -40,11 +40,11 @@ # --------------------------------------------------------------------*/ # %BANNER_END% -import logging import os from pathlib import Path import torch +from pycolmap import logging from torch import nn diff --git a/limap/pointsfm/bundler_reader.py b/limap/pointsfm/bundler_reader.py index 9e91676d..f1253268 100644 --- a/limap/pointsfm/bundler_reader.py +++ b/limap/pointsfm/bundler_reader.py @@ -1,9 +1,9 @@ -import logging import os import imagesize import numpy as np from _limap import _base, _pointsfm +from pycolmap import logging from tqdm import tqdm diff --git a/limap/pointsfm/colmap_reader.py b/limap/pointsfm/colmap_reader.py index 60aa3355..9f896c4d 100644 --- a/limap/pointsfm/colmap_reader.py +++ b/limap/pointsfm/colmap_reader.py @@ -1,8 +1,8 @@ -import logging import os import sys from _limap import _base +from pycolmap import logging sys.path.append(os.path.dirname(os.path.abspath(__file__))) from hloc.utils.read_write_model import ( diff --git a/limap/pointsfm/colmap_sfm.py b/limap/pointsfm/colmap_sfm.py index b1dac793..01be7922 100644 --- a/limap/pointsfm/colmap_sfm.py +++ b/limap/pointsfm/colmap_sfm.py @@ -1,5 +1,4 @@ import copy -import logging import os import shutil import subprocess @@ -7,6 +6,7 @@ from pathlib import Path import cv2 +from pycolmap import logging sys.path.append(os.path.dirname(os.path.abspath(__file__))) import hloc.utils.database as database @@ -26,7 +26,7 @@ def import_images_with_known_cameras(image_dir, database_path, imagecols): for cam_id in imagecols.get_cam_ids(): cam = imagecols.cam(cam_id) db.add_camera( - cam.model_id(), cam.w(), cam.h(), cam.params(), camera_id=cam_id + int(cam.model), cam.w(), cam.h(), cam.params, camera_id=cam_id ) # add image for img_name, img_id in zip(image_name_list, image_ids): diff --git a/limap/pointsfm/functions.py b/limap/pointsfm/functions.py index d504888e..0561c305 100644 --- a/limap/pointsfm/functions.py +++ b/limap/pointsfm/functions.py @@ -1,6 +1,5 @@ -import logging - from _limap import _pointsfm +from pycolmap import logging def filter_by_cam_id(cam_id, prev_imagecols, prev_neighbors): diff --git a/limap/pointsfm/model_converter.py b/limap/pointsfm/model_converter.py index 4da7fade..e13524ad 100644 --- a/limap/pointsfm/model_converter.py +++ b/limap/pointsfm/model_converter.py @@ -82,7 +82,7 @@ def convert_imagecols_to_colmap(imagecols, colmap_output_path): colmap_cameras = {} for cam_id in imagecols.get_cam_ids(): cam = imagecols.cam(cam_id) - model_id = cam.model_id() + model_id = int(cam.model) model_name = None if model_id == 0: model_name = "SIMPLE_PINHOLE" @@ -105,7 +105,7 @@ def convert_imagecols_to_colmap(imagecols, colmap_output_path): model=model_name, width=cam.w(), height=cam.h(), - params=cam.params(), + params=cam.params, ) fname = os.path.join(colmap_output_path, "cameras.txt") colmap_utils.write_cameras_text(colmap_cameras, fname) diff --git a/limap/pointsfm/sfm_model.cc b/limap/pointsfm/sfm_model.cc index 87cb593a..3c95c7d9 100644 --- a/limap/pointsfm/sfm_model.cc +++ b/limap/pointsfm/sfm_model.cc @@ -1,8 +1,9 @@ #include "pointsfm/sfm_model.h" -#include "util/log_exceptions.h" -#include -#include +#include +#include +#include +#include #include namespace limap { @@ -39,8 +40,8 @@ void SfmModel::ReadFromCOLMAP(const std::string &path, // store image ids colmap::Reconstruction reconstruction; reconstruction.Read(colmap::JoinPaths(path, sparse_path)); - for (size_t i = 0; i < reconstruction.NumRegImages(); ++i) { - reg_image_ids.push_back(reconstruction.RegImageIds()[i]); + for (auto &image_id : reconstruction.RegImageIds()) { + reg_image_ids.push_back(static_cast(image_id)); } } diff --git a/limap/runners/functions.py b/limap/runners/functions.py index 340c8f4a..d5795ab0 100644 --- a/limap/runners/functions.py +++ b/limap/runners/functions.py @@ -1,6 +1,6 @@ -import logging import os +from pycolmap import logging from tqdm import tqdm import limap.line2d @@ -60,8 +60,8 @@ def undistort_images( unload_ids = imagecols.get_img_ids() if skip_exists: logging.info( - f"[LOG] Loading undistorted images \ - (n_images = {imagecols.NumImages()})..." + f"[LOG] Loading undistorted images " + f"(n_images = {imagecols.NumImages()})..." ) fname_in = os.path.join(output_dir, fname) if os.path.isfile(fname_in): @@ -107,7 +107,7 @@ def process(imagecols, img_id): cam_undistorted = undistortion.undistort_image_camera( cam, imname_in, imname_out ) - cam_undistorted.set_cam_id(cam_id) + cam_undistorted.camera_id = cam_id return cam_undistorted outputs = joblib.Parallel(n_jobs=n_jobs)( @@ -121,7 +121,7 @@ def process(imagecols, img_id): for idx, img_id in enumerate(unload_ids): imname_out = os.path.join(output_dir, f"image{img_id:08d}.png") cam_undistorted = outputs[idx] - cam_id = cam_undistorted.cam_id() + cam_id = cam_undistorted.camera_id if cam_id not in cam_dict: cam_dict[cam_id] = cam_undistorted imagecols_undistorted.change_camera(cam_id, cam_undistorted) @@ -213,8 +213,8 @@ def compute_2d_segs(cfg, imagecols, compute_descinfo=True): weight_path = cfg.get("weight_path", None) if "extractor" in cfg["line2d"]: logging.info( - "[LOG] Start 2D line detection and description \ - (detector = {}, extractor = {}, n_images = {})...".format( + "[LOG] Start 2D line detection and description " + "(detector = {}, extractor = {}, n_images = {})...".format( cfg["line2d"]["detector"]["method"], cfg["line2d"]["extractor"]["method"], imagecols.NumImages(), @@ -222,8 +222,8 @@ def compute_2d_segs(cfg, imagecols, compute_descinfo=True): ) else: logging.info( - "[LOG] Start 2D line detection and description \ - (detector = {}, n_images = {})...".format( + "[LOG] Start 2D line detection and description " + "(detector = {}, n_images = {})...".format( cfg["line2d"]["detector"]["method"], imagecols.NumImages() ) ) @@ -306,8 +306,8 @@ def compute_matches(cfg, descinfo_folder, image_ids, neighbors): """ weight_path = cfg.get("weight_path", None) logging.info( - "[LOG] Start matching 2D lines... (extractor = {}, matcher = {}, \ - n_images = {}, n_neighbors = {})".format( + "[LOG] Start matching 2D lines... (extractor = {}, matcher = {}," + "n_images = {}, n_neighbors = {})".format( cfg["line2d"]["extractor"]["method"], cfg["line2d"]["matcher"]["method"], len(image_ids), @@ -359,8 +359,8 @@ def compute_exhaustive_matches(cfg, descinfo_folder, image_ids): matches_folder (str): path to store the computed matches """ logging.info( - "[LOG] Start exhausive matching 2D lines... \ - (extractor = {}, matcher = {}, n_images = {})".format( + "[LOG] Start exhausive matching 2D lines..." + "(extractor = {}, matcher = {}, n_images = {})".format( cfg["line2d"]["extractor"]["method"], cfg["line2d"]["matcher"]["method"], len(image_ids), diff --git a/limap/runners/functions_structures.py b/limap/runners/functions_structures.py index a046e417..669dbeb8 100644 --- a/limap/runners/functions_structures.py +++ b/limap/runners/functions_structures.py @@ -1,7 +1,7 @@ -import logging import os import numpy as np +from pycolmap import logging from tqdm import tqdm import limap.pointsfm as pointsfm diff --git a/limap/runners/hybrid_localization.py b/limap/runners/hybrid_localization.py index 02c0baec..3fd617b5 100644 --- a/limap/runners/hybrid_localization.py +++ b/limap/runners/hybrid_localization.py @@ -1,9 +1,9 @@ -import logging import os from collections import defaultdict import numpy as np from hloc.utils.io import get_keypoints, get_matches +from pycolmap import logging from tqdm import tqdm import limap.base as base diff --git a/limap/runners/line_fitnmerge.py b/limap/runners/line_fitnmerge.py index df0b6b3d..1905f6e4 100644 --- a/limap/runners/line_fitnmerge.py +++ b/limap/runners/line_fitnmerge.py @@ -1,8 +1,8 @@ -import logging import os import joblib import numpy as np +from pycolmap import logging from tqdm import tqdm import limap.base as base diff --git a/limap/runners/line_triangulation.py b/limap/runners/line_triangulation.py index d865120a..e1a0349d 100644 --- a/limap/runners/line_triangulation.py +++ b/limap/runners/line_triangulation.py @@ -1,6 +1,6 @@ -import logging import os +from pycolmap import logging from tqdm import tqdm import limap.base as base diff --git a/limap/triangulation/base_line_triangulator.cc b/limap/triangulation/base_line_triangulator.cc index 30996cc3..8b4a4964 100644 --- a/limap/triangulation/base_line_triangulator.cc +++ b/limap/triangulation/base_line_triangulator.cc @@ -2,6 +2,7 @@ #include "triangulation/functions.h" #include +#include #include #include diff --git a/limap/undistortion/bindings.cc b/limap/undistortion/bindings.cc index d5d97b54..19c9fb4a 100644 --- a/limap/undistortion/bindings.cc +++ b/limap/undistortion/bindings.cc @@ -8,7 +8,7 @@ #include #include "undistortion/undistort.h" -#include +#include namespace py = pybind11; @@ -21,7 +21,8 @@ void bind_undistortion(py::module &m) { .def(py::init<>()) .def("Read", &colmap::Bitmap::Read, py::arg("imname"), py::arg("as_rgb") = true) - .def("Write", &colmap::Bitmap::Write) + .def("Write", &colmap::Bitmap::Write, py::arg("path"), + py::arg("flag") = 0) .def("Width", &colmap::Bitmap::Width) .def("Height", &colmap::Bitmap::Height) .def("Channels", &colmap::Bitmap::Channels); diff --git a/limap/undistortion/undistort.cc b/limap/undistortion/undistort.cc index 97f0c364..1efeb1ae 100644 --- a/limap/undistortion/undistort.cc +++ b/limap/undistortion/undistort.cc @@ -1,8 +1,8 @@ #include "undistortion/undistort.h" -#include -#include -#include +#include +#include +#include #include namespace limap { @@ -16,8 +16,8 @@ Camera UndistortCamera(const std::string &imname_in, const Camera &camera, colmap::Camera cam = camera; bool exif_autorotate = false; - if (cam.Height() != img.Height() || cam.Width() != img.Width()) { - if (cam.Width() != img.Height() || cam.Height() != img.Width()) + if (cam.height != img.Height() || cam.width != img.Width()) { + if (cam.width != img.Height() || cam.height != img.Width()) throw std::runtime_error("Error! The height and width of the given " "camera do not match the input image."); // std::cout<<"[WARNING] Auto rotating image (EXIF): @@ -47,7 +47,7 @@ CameraView UndistortCameraView(const std::string &imname_in, V2D UndistortPoint(const V2D &point, const Camera &distorted_camera, const Camera &undistorted_camera) { - return undistorted_camera.WorldToImage(distorted_camera.ImageToWorld(point)); + return undistorted_camera.ImgFromCam(distorted_camera.CamFromImg(point)); } std::vector UndistortPoints(const std::vector &points, diff --git a/limap/undistortion/undistort.py b/limap/undistortion/undistort.py index 084f1356..0a82bcc4 100644 --- a/limap/undistortion/undistort.py +++ b/limap/undistortion/undistort.py @@ -20,14 +20,14 @@ def undistort_image_camera(camera, imname_in, imname_out): if camera.IsUndistorted(): # no distortion img = cv2.imread(imname_in) cv2.imwrite(imname_out, img) - if camera.model_id() == 0 or camera.model_id() == 1: + if int(camera.model) == 0 or int(camera.model) == 1: return camera # if "SIMPLE_RADIAL", update to "SIMPLE_PINHOLE" - if camera.model_id() == 2: + if int(camera.model) == 2: new_camera = _base.Camera( "SIMPLE_PINHOLE", camera.K(), - cam_id=camera.cam_id(), + cam_id=camera.camera_id, hw=[camera.h(), camera.w()], ) else: @@ -35,7 +35,7 @@ def undistort_image_camera(camera, imname_in, imname_out): new_camera = _base.Camera( "PINHOLE", camera.K(), - cam_id=camera.cam_id(), + cam_id=camera.camera_id, hw=[camera.h(), camera.w()], ) return new_camera diff --git a/limap/util/CMakeLists.txt b/limap/util/CMakeLists.txt index bd598c84..66e52096 100644 --- a/limap/util/CMakeLists.txt +++ b/limap/util/CMakeLists.txt @@ -3,7 +3,6 @@ set(FOLDER_NAME "util") LIMAP_ADD_SOURCES( types.h simple_logger.h simple_logger.cc - log_exceptions.h nanoflann.hpp kd_tree.h kd_tree.cpp diff --git a/limap/util/evaluation.py b/limap/util/evaluation.py index 9bbe22e0..5687a136 100644 --- a/limap/util/evaluation.py +++ b/limap/util/evaluation.py @@ -1,7 +1,6 @@ -import logging - import cv2 import numpy as np +from pycolmap import logging import limap.base as base diff --git a/limap/util/io.py b/limap/util/io.py index 75fad647..1dad7d50 100644 --- a/limap/util/io.py +++ b/limap/util/io.py @@ -1,8 +1,8 @@ -import logging import os import shutil import numpy as np +from pycolmap import logging from tqdm import tqdm import limap.base as base diff --git a/limap/util/log_exceptions.h b/limap/util/log_exceptions.h deleted file mode 100644 index e15d79e1..00000000 --- a/limap/util/log_exceptions.h +++ /dev/null @@ -1,94 +0,0 @@ -#pragma once - -// Copied from the pixel-perfect-sfm project - -#include -#include -#include - -#include - -namespace py = pybind11; - -#define THROW_EXCEPTION(exception, msg) \ - throw TemplateException(__FILE__, __LINE__, msg); - -#define THROW_CUSTOM_CHECK_MSG(condition, exception, msg) \ - if (!condition) \ - throw TemplateException( \ - __FILE__, __LINE__, \ - __MergeTwoConstChar(__GetCheckString(#condition).c_str(), msg) \ - .c_str()); - -#define THROW_CUSTOM_CHECK(condition, exception) \ - if (!condition) \ - throw TemplateException(__FILE__, __LINE__, \ - __GetCheckString(#condition).c_str()); - -inline const char *__ColmapGetConstFileBaseName(const char *file) { - const char *base = strrchr(file, '/'); - if (!base) { - base = strrchr(file, '\\'); - } - return base ? (base + 1) : file; -} - -template -inline T TemplateException(const char *file, const int line, const char *txt) { - std::stringstream ss; - ss << "[" << __ColmapGetConstFileBaseName(file) << ":" << line << "] " << txt; - return T(ss.str()); -} - -inline std::string __GetConditionString(const char *cond_str) { - std::stringstream ss; - ss << "Condition Failed: " << cond_str; - return ss.str(); -} - -inline std::string __GetCheckString(const char *cond_str) { - std::stringstream ss; - ss << "Check Failed: " << cond_str; - return ss.str(); -} - -inline std::string __MergeTwoConstChar(const char *expr1, const char *expr2) { - return (std::string(expr1) + std::string(" ") + expr2); -} - -inline void __ThrowCheckImpl(const char *file, const int line, - const bool result, const char *expr_str) { - if (!result) { - throw TemplateException( - file, line, __GetCheckString(expr_str).c_str()); - } -} - -template -void __ThrowCheckOpImpl(const char *file, const int line, const bool result, - const T1 &val1, const T2 &val2, const char *val1_str, - const char *val2_str, const char *op_str) { - if (!result) { - std::stringstream ss; - ss << val1_str << " " << op_str << " " << val2_str << " (" << val1 - << " vs. " << val2 << ")"; - std::string msg = ss.str(); - throw TemplateException( - file, line, __GetCheckString(msg.c_str()).c_str()); - } -} - -// Option checker macros. In contrast to glog, this function does not abort the -// program, but simply returns false on failure. -#define THROW_CHECK(expr) __ThrowCheckImpl(__FILE__, __LINE__, (expr), #expr); - -#define THROW_CHECK_OP(name, op, val1, val2) \ - __ThrowCheckOpImpl(__FILE__, __LINE__, (val1 op val2), val1, val2, #val1, \ - #val2, #op); - -#define THROW_CHECK_EQ(val1, val2) THROW_CHECK_OP(_EQ, ==, val1, val2) -#define THROW_CHECK_NE(val1, val2) THROW_CHECK_OP(_NE, !=, val1, val2) -#define THROW_CHECK_LE(val1, val2) THROW_CHECK_OP(_LE, <=, val1, val2) -#define THROW_CHECK_LT(val1, val2) THROW_CHECK_OP(_LT, <, val1, val2) -#define THROW_CHECK_GE(val1, val2) THROW_CHECK_OP(_GE, >=, val1, val2) -#define THROW_CHECK_GT(val1, val2) THROW_CHECK_OP(_GT, >, val1, val2) diff --git a/limap/util/types.h b/limap/util/types.h index ddba98b1..b979249d 100644 --- a/limap/util/types.h +++ b/limap/util/types.h @@ -7,7 +7,7 @@ #include #include -#include "util/log_exceptions.h" +#include namespace py = pybind11; diff --git a/limap/visualize/trackvis/base.py b/limap/visualize/trackvis/base.py index 7999c75b..e7fd644f 100644 --- a/limap/visualize/trackvis/base.py +++ b/limap/visualize/trackvis/base.py @@ -1,6 +1,5 @@ -import logging - import numpy as np +from pycolmap import logging from ..vis_utils import test_line_inside_ranges @@ -26,14 +25,14 @@ def report(self): def report_stats(self): counts = np.array(self.counts) logging.info( - f"[Track Report] (N2, N4, N6, N8, N10, N20, N50) = \ - ({counts[counts >= 2].shape[0]}, \ - {counts[counts >= 4].shape[0]}, \ - {counts[counts >= 6].shape[0]}, \ - {counts[counts >= 8].shape[0]}, \ - {counts[counts >= 10].shape[0]}, \ - {counts[counts >= 20].shape[0]}, \ - {counts[counts >= 50].shape[0]})" + f"[Track Report] (N2, N4, N6, N8, N10, N20, N50) =" + f" ({counts[counts >= 2].shape[0]}," + f" {counts[counts >= 4].shape[0]}," + f" {counts[counts >= 6].shape[0]}," + f" {counts[counts >= 8].shape[0]}," + f" {counts[counts >= 10].shape[0]}," + f" {counts[counts >= 20].shape[0]}," + f" {counts[counts >= 50].shape[0]})" ) def report_avg_supports(self, n_visible_views=4): @@ -42,12 +41,12 @@ def report_avg_supports(self, n_visible_views=4): arr = counts[counts >= n_visible_views] arr_lines = counts_lines[counts >= n_visible_views] logging.info( - f"average supporting images (>= {n_visible_views}): \ - {arr.sum()} / {arr.shape[0]} = {arr.mean():.2f}" + f"average supporting images (>= {n_visible_views}):" + f" {arr.sum()} / {arr.shape[0]} = {arr.mean():.2f}" ) logging.info( - f"average supporting lines (>= {n_visible_views}): \ - {arr_lines.sum()} / {arr_lines.shape[0]} = {arr_lines.mean():.2f}" + f"average supporting lines (>= {n_visible_views}): " + f"{arr_lines.sum()} / {arr_lines.shape[0]} = {arr_lines.mean():.2f}" ) def get_counts_np(self): diff --git a/limap/visualize/vis_utils.py b/limap/visualize/vis_utils.py index c07e5a63..142a495a 100644 --- a/limap/visualize/vis_utils.py +++ b/limap/visualize/vis_utils.py @@ -1,11 +1,11 @@ import copy -import logging import os import cv2 import matplotlib.pyplot as plt import numpy as np import seaborn as sns +from pycolmap import logging def random_color(): diff --git a/misc/install/poselib.md b/misc/install/poselib.md deleted file mode 100644 index 98fb8d7c..00000000 --- a/misc/install/poselib.md +++ /dev/null @@ -1,12 +0,0 @@ -## Install PoseLib as Dependency -Clone the repository -```bash -git clone --recursive https://github.com/vlarsson/PoseLib.git -cd PoseLib -``` -Build and install: -```bash -mkdir build && cd build -cmake .. -sudo make install -j8 -``` diff --git a/requirements.txt b/requirements.txt index c776ad85..ebd63c7a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -26,8 +26,9 @@ imagesize einops ninja yacs -python-json-logger +pycolmap ruff==0.6.7 +clang-format==19.1.0 ./third-party/pytlsd ./third-party/hawp diff --git a/runners/cambridge/utils.py b/runners/cambridge/utils.py index 830ef1a4..5996dadf 100644 --- a/runners/cambridge/utils.py +++ b/runners/cambridge/utils.py @@ -142,7 +142,7 @@ def create_query_list(imagecols, out): for img_id in imagecols.get_img_ids(): cam_id = imagecols.camimage(img_id).cam_id camera = imagecols.cam(cam_id) - w, h, params = camera.w(), camera.h(), camera.params() + w, h, params = camera.w(), camera.h(), camera.params name = imagecols.camimage(img_id).image_name().split("/")[-1] p = [name, model_dict[camera.as_dict()["model_id"]], w, h] + params data.append(" ".join(map(str, p))) diff --git a/scripts/eval_hypersim.py b/scripts/eval_hypersim.py index b584e753..d91c0ae5 100644 --- a/scripts/eval_hypersim.py +++ b/scripts/eval_hypersim.py @@ -4,6 +4,7 @@ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import matplotlib.pyplot as plt import numpy as np +from pycolmap import logging from tqdm import tqdm import limap.evaluation as limap_eval @@ -58,11 +59,11 @@ def report_error_to_GT(evaluator, lines, vis_err_th=None): list_recall.append(length_recall) precision = 100 * (ratios > 0).astype(int).sum() / ratios.shape[0] list_precision.append(precision) - print("R: recall, P: precision") + logging.info("R: recall, P: precision") for idx, threshold in enumerate(thresholds): - print( - f"R / P at {int(threshold * 1000)}mm: \ - {list_recall[idx]:.2f} / {list_precision[idx]:.2f}" + logging.info( + f"R / P at {int(threshold * 1000)}mm: " + f"{list_recall[idx]:.2f} / {list_precision[idx]:.2f}" ) return evaluator @@ -75,7 +76,7 @@ def read_ply(fname): y = np.asarray(plydata.elements[0].data["y"]) z = np.asarray(plydata.elements[0].data["z"]) points = np.stack([x, y, z], axis=1) - print(f"number of points: {points.shape[0]}") + logging.info(f"number of points: {points.shape[0]}") return points @@ -282,9 +283,9 @@ def main(): sup_line_counts = np.array( [track.count_lines() for track in linetracks] ) - print( - f"supporting images / lines: ({sup_image_counts.mean():.2f} \ - / {sup_line_counts.mean():.2f})" + logging.info( + f"supporting images / lines: ({sup_image_counts.mean():.2f} " + f"/ {sup_line_counts.mean():.2f})" ) diff --git a/scripts/eval_tnt.py b/scripts/eval_tnt.py index b7297a1f..5cb7678f 100644 --- a/scripts/eval_tnt.py +++ b/scripts/eval_tnt.py @@ -4,6 +4,7 @@ sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) import matplotlib.pyplot as plt import numpy as np +from pycolmap import logging from tqdm import tqdm import limap.base as base @@ -31,9 +32,9 @@ def report_error_to_GT(evaluator, lines): precision = 100 * (ratios > 0).astype(int).sum() / ratios.shape[0] list_precision.append(precision) for idx, threshold in enumerate(thresholds): - print( - f"R / P at {int(threshold * 1000)}mm: \ - {list_recall[idx]:.2f} / {list_precision[idx]:.2f}" + logging.info( + f"R / P at {int(threshold * 1000)}mm: " + f"{list_recall[idx]:.2f} / {list_precision[idx]:.2f}" ) return evaluator @@ -47,13 +48,13 @@ def report_pc_recall_for_GT(evaluator, lines): # point_dists = evaluator.ComputeDistsforEachPoint_KDTree(lines) point_dists = np.array(point_dists) n_points = point_dists.shape[0] - print("Compute point recall metrics.") + logging.info("Compute point recall metrics.") for threshold in thresholds.tolist(): num_inliers = (point_dists < threshold).sum() point_recall = 100 * num_inliers / n_points - print( - f"{int(threshold * 1000):.0f}mm, inliers = {num_inliers}, \ - point recall = {point_recall:.2f}" + logging.info( + f"{int(threshold * 1000):.0f}mm, inliers = {num_inliers}, " + f"point recall = {point_recall:.2f}" ) return evaluator @@ -66,7 +67,7 @@ def read_ply(fname): y = np.asarray(plydata.elements[0].data["y"]) z = np.asarray(plydata.elements[0].data["z"]) points = np.stack([x, y, z], axis=1) - print(f"number of points: {points.shape[0]}") + logging.info(f"number of points: {points.shape[0]}") return points @@ -118,7 +119,7 @@ def eval_tnt(cfg, lines, ref_lines=None): for line in lines if limapvis.test_line_inside_ranges(line, ranges) ] - print(f"Filtering by range: {len(lines)} / {n_lines}") + logging.info(f"Filtering by range: {len(lines)} / {n_lines}") evaluator = report_error_to_point_cloud( points, lines, kdtree_dir=cfg["kdtree_dir"] ) @@ -215,7 +216,6 @@ def parse_config(): cfg["noeval"] = args.noeval cfg["transform_txt"] = args.transform_txt cfg["use_ranges"] = args.use_ranges - # print(cfg) return cfg @@ -278,9 +278,9 @@ def main(): sup_line_counts = np.array( [track.count_lines() for track in linetracks] ) - print( - f"supporting images / lines: ({sup_image_counts.mean():.2f} \ - / {sup_line_counts.mean():.2f})" + logging.info( + f"supporting images / lines: ({sup_image_counts.mean():.2f} " + f"/ {sup_line_counts.mean():.2f})" ) diff --git a/scripts/format/clang_format.sh b/scripts/format/clang_format.sh index a70a0c8a..d978b650 100755 --- a/scripts/format/clang_format.sh +++ b/scripts/format/clang_format.sh @@ -24,7 +24,7 @@ echo "Found clang-format: $(which ${clang_format})" # Check version version_string=$($clang_format --version | sed -E 's/^.*(\d+\.\d+\.\d+-.*).*$/\1/') -expected_version_string='14.0.0' +expected_version_string='19.1.0' if [[ "$version_string" =~ "$expected_version_string" ]]; then echo "clang-format version '$version_string' matches '$expected_version_string'" else diff --git a/third-party/DeepLSD b/third-party/DeepLSD index 59006b26..88c589df 160000 --- a/third-party/DeepLSD +++ b/third-party/DeepLSD @@ -1 +1 @@ -Subproject commit 59006b264d05e97856556d3f16ded45bd4dbc286 +Subproject commit 88c589dfdd824a94051131cd5bce88588009bebb diff --git a/third-party/libigl b/third-party/libigl index e19a68cf..c2f96e8e 160000 --- a/third-party/libigl +++ b/third-party/libigl @@ -1 +1 @@ -Subproject commit e19a68cfa6141c72a7acb8021e85da1f919fffca +Subproject commit c2f96e8e1853a3630f4c410767dada94d61e4f94