diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 52b3fb8a1..a0ba32393 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,9 @@ +Changelog +========= +------------------------ COLMAP 3.11 (11/28/2024) -======================== +------------------------ New Features ------------ @@ -30,6 +33,7 @@ Breaking Changes * Upgrade to C++17 standard in C++ and C++14 in CUDA source code. * New ``pose_priors`` table in database in support of pose prior based mapper. * PyCOLMAP API: + * ``align_reconstrution_to_locations`` is renamed to ``align_reconstruction_to_locations`` (typo). * ``pycomap.cost_functions`` becomes a module and should be explicitly imported as ``import pycolmap.cost_functions``. * Replaced ``Image.registered`` by ``Image.{has_pose,reset_pose}``. @@ -120,7 +124,7 @@ Full Change List (sorted temporally) * More informative exception if invalid access of image/camera/point3D by @sarlinpe in https://github.com/colmap/colmap/pull/2825 * Use minimal solvers from poselib by @ahojnnes in https://github.com/colmap/colmap/pull/2288 * Disable -march=native flags in poselib by @ahojnnes in https://github.com/colmap/colmap/pull/2828 -* Make Image::cam_from_world_ optional by @sarlinpe in https://github.com/colmap/colmap/pull/2824 +* Make ``Image::cam_from_world_`` optional by @sarlinpe in https://github.com/colmap/colmap/pull/2824 * Remove warning in configure step by @sarlinpe in https://github.com/colmap/colmap/pull/2830 * Fix coordinate notation in EstimateAbsolutePose by @ahojnnes in https://github.com/colmap/colmap/pull/2833 * Return success status in low-level triangulation functions by @ahojnnes in https://github.com/colmap/colmap/pull/2834 @@ -186,8 +190,9 @@ Full Change List (sorted temporally) * Update to latest pybind11 version by @ahojnnes in https://github.com/colmap/colmap/pull/2952 * Update install instructions for Mac using homebrew by @ahojnnes in https://github.com/colmap/colmap/pull/2953 +------------------------ COLMAP 3.10 (07/23/2024) -======================== +------------------------ * Add missing "include " needed for unique_ptr by @Tobias-Fischer in https://github.com/colmap/colmap/pull/2338 * Support decoding multi-byte characters in Python script by @jot-jt in https://github.com/colmap/colmap/pull/2344 * Split Dockerfile in two stages: builder and runtime. by @pablospe in https://github.com/colmap/colmap/pull/2347 @@ -276,13 +281,15 @@ COLMAP 3.10 (07/23/2024) * Add CI build for Windows CUDA by @ahojnnes in https://github.com/colmap/colmap/pull/2651 * Publish windows binaries from CI by @ahojnnes in https://github.com/colmap/colmap/pull/2663 +------------------------- COLMAP 3.9.1 (01/08/2024) -========================= +------------------------- * Version 3.9 changelog by @ahojnnes in https://github.com/colmap/colmap/pull/2325 * Fully encapsulate freeimage in bitmap library (#2332) by @ahojnnes in https://github.com/colmap/colmap/pull/2334 +----------------------- COLMAP 3.9 (01/06/2024) -======================= +----------------------- * clang format all code and require clang-format-14 by @ahojnnes in https://github.com/colmap/colmap/pull/1785 * Fix compilation for vcpkg windows build by @ahojnnes in https://github.com/colmap/colmap/pull/1791 * Increment version number to 3.9 by @ahojnnes in https://github.com/colmap/colmap/pull/1794 @@ -452,8 +459,9 @@ COLMAP 3.9 (01/06/2024) * Fix typo by @whuaegeanse in https://github.com/colmap/colmap/pull/2317 * Stable version 3.9 release by @ahojnnes in https://github.com/colmap/colmap/pull/2319 +----------------------- COLMAP 3.8 (01/31/2023) -======================= +----------------------- * Updating geo-registration doc. by @ferreram in https://github.com/colmap/colmap/pull/1410 * Adding user-specified option for reconstructing purely planar scene. … by @ferreram in https://github.com/colmap/colmap/pull/1408 * Only apply sqlite vacuum command when elements are deleted from the database. by @ferreram in https://github.com/colmap/colmap/pull/1414 @@ -518,8 +526,9 @@ COLMAP 3.8 (01/31/2023) * Option to store relative pose between two cameras in database by @yanxke in https://github.com/colmap/colmap/pull/1774 * Depend on system installed SQLite3 by @ahojnnes in https://github.com/colmap/colmap/pull/1783 +----------------------- COLMAP 3.7 (01/26/2022) -======================= +----------------------- * Allow to save fused point cloud in colmap format when using command line by @boitumeloruf in https://github.com/colmap/colmap/pull/799 * Fix typos in image.h by @Pascal-So in https://github.com/colmap/colmap/pull/936 * Fix for EPnP estimator by @vlarsson in https://github.com/colmap/colmap/pull/943 @@ -612,9 +621,9 @@ COLMAP 3.7 (01/26/2022) * Add ccache option by @ahojnnes in https://github.com/colmap/colmap/pull/1395 * Update ModelAligner to handle GPS and custom coords. and more by @ferreram in https://github.com/colmap/colmap/pull/1371 - +----------------------- COLMAP 3.6 (07/24/2020) -======================= +----------------------- * Improved robustness and faster incremental reconstruction process * Add ``image_deleter`` command to remove images from sparse model * Add ``image_filter`` command to filter bad registrations from sparse model @@ -636,9 +645,9 @@ COLMAP 3.6 (07/24/2020) * Scripts for building and running COLMAP in Docker * Many more bug fixes and improvements to code and documentation - +----------------------- COLMAP 3.5 (08/22/2018) -======================= +----------------------- * COLMAP is now released under the BSD license instead of the GPL * COLMAP is now installed as a library, whose headers can be included and libraries linked against from other C/C++ code @@ -656,9 +665,9 @@ COLMAP 3.5 (08/22/2018) * Add more extensive continuous integration across more compilation scenarios * Many more bug fixes and improvements to code and documentation - +----------------------- COLMAP 3.4 (01/29/2018) -======================= +----------------------- * Unified command-line interface: The functionality of previous executables have been merged into the ``src/exe/colmap.cc`` executable. The GUI can now be started using the command ``colmap gui`` and other commands are available @@ -679,9 +688,9 @@ COLMAP 3.4 (01/29/2018) * Faster covariant feature detection * Many more bug fixes and improvements - +----------------------- COLMAP 3.3 (11/21/2017) -======================= +----------------------- * Add DSP (Domain Size Pooling) SIFT implementation. DSP-SIFT outperforms standard SIFT in most cases, as shown in "Comparative Evaluation of Hand-Crafted and Learned Local Features", Schoenberger et al., CVPR 2017 @@ -694,9 +703,9 @@ COLMAP 3.3 (11/21/2017) * Support for older Python versions in automatic build script * Fix OpenCV Fisheye camera model to exactly match OpenCV specifications - +--------------------- COLMAP 3.2 (9/2/2017) -===================== +--------------------- * Fully automatic cross-platform build script (Windows, Mac, Linux) * Add multi-GPU feature extraction if multiple CUDA devices are available * Configurable dimension and data type for vocabulary tree implementation @@ -707,9 +716,9 @@ COLMAP 3.2 (9/2/2017) * Add continuous integration system under Windows, Mac, Linux through Github * Many more bug fixes and improvements - +---------------------- COLMAP 3.1 (6/15/2017) -====================== +---------------------- * Add fast spatial verification to image retrieval module * Add binary file format for sparse models by default. Old text format still fully compatible and possible conversion in GUI and CLI @@ -722,9 +731,9 @@ COLMAP 3.1 (6/15/2017) * Add medium quality option in automatic reconstructor * Many more bug fixes and improvements - +---------------------- COLMAP 3.0 (5/22/2017) -====================== +---------------------- * Add automatic end-to-end reconstruction tool that automatically performs sparse and dense reconstruction on a given set of images * Add multi-GPU dense stereo if multiple CUDA devices are available @@ -746,9 +755,9 @@ COLMAP 3.0 (5/22/2017) * More stable view selection for small baseline scenario in dense reconstruction * Many more bug fixes and improvements - +---------------------- COLMAP 2.1 (12/7/2016) -====================== +---------------------- * Support to only index and match specific images in vocabulary tree matching * Support to perform image retrieval using vocabulary tree * Several bug fixes and improvements for multi-view stereo module @@ -762,9 +771,9 @@ COLMAP 2.1 (12/7/2016) * Support to limit the number of features in image retrieval for improved speed * Miscellaneous bug fixes and improvements - +--------------------- COLMAP 2.0 (9/8/2016) -===================== +--------------------- * Implementation of dense reconstruction pipeline * Improved feature matching performance * New bundle adjuster for rigidly mounted multi-camera systems @@ -773,9 +782,9 @@ COLMAP 2.0 (9/8/2016) * Boost can now be linked in shared and static mode * Various bug fixes and performance improvements - +---------------------- COLMAP 1.1 (5/19/2016) -====================== +---------------------- * Implementation of state-of-the-art image retrieval system using Hamming embedding for vocabulary tree matching. This should lead to much improved matching results as compared to the previous implementation. @@ -791,7 +800,7 @@ COLMAP 1.1 (5/19/2016) * Extended documentation based on user feedback. * Fixed typo in documentation (Thomas Schoeps). - +--------------------- COLMAP 1.0 (4/4/2016) -===================== +--------------------- * Initial release of COLMAP. diff --git a/doc/changelog.rst b/doc/changelog.rst index f8338ad5a..76888fe1b 100644 --- a/doc/changelog.rst +++ b/doc/changelog.rst @@ -1,6 +1,3 @@ .. _changelog: -Changelog -========= - .. include:: ../CHANGELOG.rst diff --git a/doc/conf.py b/doc/conf.py index f51443bd0..5f0cd448a 100755 --- a/doc/conf.py +++ b/doc/conf.py @@ -10,6 +10,9 @@ # All configuration values have a default; values that are commented out # serve to show the default. +import re + +from sphinx.ext import autodoc # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the @@ -188,7 +191,7 @@ # The font size ('10pt', '11pt' or '12pt'). # 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. - #'preamble': '', + # 'preamble': '', } # Grouping the document tree into LaTeX files. List of tuples @@ -279,9 +282,40 @@ python_maximum_signature_line_length = 120 +class MyClassDocumenter(autodoc.ClassDocumenter): + def sort_members( + self, documenters: list[tuple[autodoc.Documenter, bool]], order: str + ) -> list[tuple[autodoc.Documenter, bool]]: + """Order the members by their definition order.""" + class_names = list(self.object.__dict__) + + def keyfunc(entry: tuple[autodoc.Documenter, bool]) -> int: + name = entry[0].name.split("::")[1].split(".")[1] + if name in class_names: + return class_names.index(name) + else: + return len(class_names) + + documenters.sort(key=keyfunc) + return documenters + + +# autodoc_member_order=bysource does not work for C++-defined classes since they +# cannot be introspected and do not have an __all__ list. Instead, +# we extract the definition order from object.__dict__. +autodoc.ClassDocumenter = MyClassDocumenter + + def process_doc(app, what, name, obj, options, lines): + if not lines: + return + has_overload = lines[0] == "Overloaded function." for i in range(len(lines)): lines[i] = lines[i].replace("pycolmap._core", "pycolmap") + if has_overload and re.search(r"^\d+\. ", lines[i]): + index, signature = lines[i].split(". ", 1) + signature = "``" + signature.replace("->", "→") + "``" + lines[i] = ". ".join([index, signature]) def process_sig(app, what, name, obj, options, signature, return_annotation): diff --git a/doc/index.rst b/doc/index.rst index 9a6e8317d..ff0e223c9 100755 --- a/doc/index.rst +++ b/doc/index.rst @@ -82,10 +82,10 @@ for bug reports, feature requests/additions, etc. Acknowledgments --------------- -COLMAP was originally written by `Johannes Schönberger `_ with +COLMAP was originally written by `Johannes Schönberger `__ with funding provided by his PhD advisors Jan-Michael Frahm and Marc Pollefeys. The team of core project maintainers currently includes -`Johannes Schönberger `_, +`Johannes Schönberger `__, `Paul-Edouard Sarlin `_, and `Shaohui Liu `_. diff --git a/doc/install.rst b/doc/install.rst index 5095dcd10..02b233b96 100755 --- a/doc/install.rst +++ b/doc/install.rst @@ -12,7 +12,7 @@ https://repology.org/metapackage/colmap/versions. Note that the COLMAP packages in the default repositories for Linux/Unix/BSD do not come with CUDA support, which requires a manual build from source, as explained further below. -For Mac users, [Homebrew](https://brew.sh) provides a formula for COLMAP with +For Mac users, `Homebrew `__ provides a formula for COLMAP with pre-compiled binaries or the option to build from source. After installing homebrew, installing COLMAP is as easy as running `brew install colmap`. @@ -131,7 +131,7 @@ CUDA package and GCC, and you must compile against GCC 10:: Mac --- -Dependencies from `Homebrew `_:: +Dependencies from `Homebrew `__:: brew install \ cmake \ diff --git a/src/pycolmap/geometry/bindings.cc b/src/pycolmap/geometry/bindings.cc index 7f3445dd2..5c7e2012c 100644 --- a/src/pycolmap/geometry/bindings.cc +++ b/src/pycolmap/geometry/bindings.cc @@ -28,7 +28,7 @@ void BindGeometry(py::module& m) { "xyzw"_a, "Quaternion in [x,y,z,w] format.") .def(py::init(), - "rotmat"_a, + "matrix"_a, "3x3 rotation matrix.") .def(py::init([](const Eigen::Vector3d& vec) { return Eigen::Quaterniond( @@ -75,10 +75,15 @@ void BindGeometry(py::module& m) { py::class_ext_ PyRigid3d(m, "Rigid3d"); PyRigid3d.def(py::init<>()) - .def(py::init()) + .def(py::init(), + "rotation"_a, + "translation"_a) .def(py::init([](const Eigen::Matrix3x4d& matrix) { - return Rigid3d(Eigen::Quaterniond(matrix.leftCols<3>()), matrix.col(3)); - })) + return Rigid3d(Eigen::Quaterniond(matrix.leftCols<3>()), + matrix.col(3)); + }), + "matrix"_a, + "3x4 transformation matrix.") .def_readwrite("rotation", &Rigid3d::rotation) .def_readwrite("translation", &Rigid3d::translation) .def("matrix", &Rigid3d::ToMatrix) @@ -110,8 +115,13 @@ void BindGeometry(py::module& m) { py::class_ext_ PySim3d(m, "Sim3d"); PySim3d.def(py::init<>()) .def( - py::init()) - .def(py::init(&Sim3d::FromMatrix)) + py::init(), + "scale"_a, + "rotation"_a, + "translation"_a) + .def(py::init(&Sim3d::FromMatrix), + "matrix"_a, + "3x4 transformation matrix.") .def_property( "scale", [](Sim3d& self) { @@ -147,12 +157,19 @@ void BindGeometry(py::module& m) { py::class_ext_ PyPosePrior(m, "PosePrior"); PyPosePrior.def(py::init<>()) - .def(py::init()) - .def(py::init()) - .def(py::init()) + .def(py::init(), "position"_a) + .def(py::init(), + "position"_a, + "coordinate_system"_a) + .def(py::init(), + "position"_a, + "position_covariance"_a) .def(py::init()) + const PPCoordinateSystem>(), + "position"_a, + "position_covariance"_a, + "coordinate_system"_a) .def_readwrite("position", &PosePrior::position) .def_readwrite("position_covariance", &PosePrior::position_covariance) .def_readwrite("coordinate_system", &PosePrior::coordinate_system) diff --git a/src/pycolmap/helpers.h b/src/pycolmap/helpers.h index c566cca4c..e9edb4dd7 100644 --- a/src/pycolmap/helpers.h +++ b/src/pycolmap/helpers.h @@ -42,8 +42,9 @@ T PyStringToEnum(const py::enum_& enm, const std::string& value) { template void AddStringToEnumConstructor(py::enum_& enm) { enm.def(py::init([enm](const std::string& value) { - return PyStringToEnum(enm, py::str(value)); // str constructor - })); + return PyStringToEnum(enm, py::str(value)); // str constructor + }), + "value"_a); py::implicitly_convertible(); } @@ -301,7 +302,7 @@ void MakeDataclass(py::class_ cls, if (!cls.attr("__dict__").contains("__repr__")) { cls.def("__repr__", &CreateRepresentation); } - cls.def("mergedict", &UpdateFromDict); + cls.def("mergedict", &UpdateFromDict, "kwargs"_a); cls.def( "todict", [attributes](const T& self, const bool recursive) { @@ -310,10 +311,11 @@ void MakeDataclass(py::class_ cls, "recursive"_a = true); cls.def(py::init([cls](const py::dict& dict) { - py::object self = cls(); - self.attr("mergedict").attr("__call__")(dict); - return self.cast(); - })); + py::object self = cls(); + self.attr("mergedict").attr("__call__")(dict); + return self.cast(); + }), + "kwargs"_a); cls.def(py::init([cls](const py::kwargs& kwargs) { py::dict dict = kwargs.cast(); return cls(dict).template cast(); @@ -419,7 +421,7 @@ inline void DefDeprecation( parent.def( old_name.c_str(), [parent, - old_name = std::move(old_name), + old_name, new_name = std::move(new_name), custom_warning = std::move(custom_warning)](const py::args& args, const py::kwargs& kwargs) { diff --git a/src/pycolmap/scene/camera.cc b/src/pycolmap/scene/camera.cc index 13ed16565..8e4e8be38 100644 --- a/src/pycolmap/scene/camera.cc +++ b/src/pycolmap/scene/camera.cc @@ -95,16 +95,21 @@ void BindCamera(py::module& m) { "Concatenate parameters as comma-separated list.") .def("set_params_from_string", &Camera::SetParamsFromString, + "params"_a, "Set camera parameters from comma-separated list.") .def("verify_params", &Camera::VerifyParams, "Check whether parameters are valid, i.e. the parameter vector has" - "\nthe correct dimensions that match the specified camera model.") + " the correct dimensions that match the specified camera model.") .def("has_bogus_params", &Camera::HasBogusParams, + "min_focal_length_ratio"_a, + "max_focal_length_ratio"_a, + "max_extra_param"_a, "Check whether camera has bogus parameters.") .def("cam_from_img", &Camera::CamFromImg, + "image_point"_a, "Project point in image plane to world / infinity.") .def( "cam_from_img", @@ -116,6 +121,7 @@ void BindCamera(py::module& m) { } return world_points; }, + "image_points"_a, "Project list of points in image plane to world / infinity.") .def( "cam_from_img", @@ -126,12 +132,15 @@ void BindCamera(py::module& m) { } return world_points; }, + "image_points"_a, "Project list of points in image plane to world / infinity.") .def("cam_from_img_threshold", &Camera::CamFromImgThreshold, + "threshold"_a, "Convert pixel threshold in image plane to world space.") .def("img_from_cam", &Camera::ImgFromCam, + "cam_point"_a, "Project point from world / infinity to image plane.") .def( "img_from_cam", @@ -143,6 +152,7 @@ void BindCamera(py::module& m) { } return image_points; }, + "cam_points"_a, "Project list of points from world / infinity to image plane.") .def( "img_from_cam", @@ -151,6 +161,7 @@ void BindCamera(py::module& m) { return py::cast(self).attr("img_from_cam")( world_points.rowwise().hnormalized()); }, + "cam_points"_a, "Project list of points from world / infinity to image plane.") .def( "img_from_cam", @@ -161,17 +172,19 @@ void BindCamera(py::module& m) { } return image_points; }, + "cam_points"_a, "Project list of points from world / infinity to image plane.") .def("rescale", py::overload_cast(&Camera::Rescale), - "Rescale camera dimensions to (width_height) and accordingly the " - "focal length and\n" - "and the principal point.") + "new_width"_a, + "new_height"_a, + "Rescale the camera dimensions and accordingly the " + "focal length and the principal point.") .def("rescale", py::overload_cast(&Camera::Rescale), - "Rescale camera dimensions by given factor and accordingly the " - "focal length and\n" - "and the principal point."); + "scale"_a, + "Rescale the camera dimensions and accordingly the " + "focal length and the principal point."); MakeDataclass(PyCamera, {"camera_id", "model", diff --git a/src/pycolmap/scene/image.cc b/src/pycolmap/scene/image.cc index 1ae027aec..ed3315721 100644 --- a/src/pycolmap/scene/image.cc +++ b/src/pycolmap/scene/image.cc @@ -129,7 +129,8 @@ void BindImage(py::module& m) { return py::none(); } }, - "Project 3D point onto the image") + "Project 3D point onto the image", + "point3D"_a) .def("has_camera_id", &Image::HasCameraId, "Check whether identifier of camera has been set.") diff --git a/src/pycolmap/scene/reconstruction.cc b/src/pycolmap/scene/reconstruction.cc index 5d84551f5..25a57e233 100644 --- a/src/pycolmap/scene/reconstruction.cc +++ b/src/pycolmap/scene/reconstruction.cc @@ -45,7 +45,7 @@ void BindReconstruction(py::module& m) { py::class_>(m, "Reconstruction") .def(py::init<>()) - .def(py::init()) + .def(py::init(), "reconstruction"_a) .def(py::init([](const std::string& path) { auto reconstruction = std::make_shared(); reconstruction->Read(path); diff --git a/src/pycolmap/scene/track.cc b/src/pycolmap/scene/track.cc index 0738fd2cf..fa80660ae 100644 --- a/src/pycolmap/scene/track.cc +++ b/src/pycolmap/scene/track.cc @@ -21,7 +21,7 @@ void BindTrack(py::module& m) { py::class_> PyTrackElement( m, "TrackElement"); PyTrackElement.def(py::init<>()) - .def(py::init()) + .def(py::init(), "image_id"_a, "point2D_idx"_a) .def_readwrite("image_id", &TrackElement::image_id) .def_readwrite("point2D_idx", &TrackElement::point2D_idx); MakeDataclass(PyTrackElement); @@ -29,10 +29,11 @@ void BindTrack(py::module& m) { py::class_> PyTrack(m, "Track"); PyTrack.def(py::init<>()) .def(py::init([](const std::vector& elements) { - auto track = std::make_shared(); - track->AddElements(elements); - return track; - })) + auto track = std::make_shared(); + track->AddElements(elements); + return track; + }), + "elements"_a) .def_property("elements", py::overload_cast<>(&Track::Elements), &Track::SetElements) diff --git a/src/pycolmap/sfm/incremental_mapper.cc b/src/pycolmap/sfm/incremental_mapper.cc index 30f5f467c..b8a52f250 100644 --- a/src/pycolmap/sfm/incremental_mapper.cc +++ b/src/pycolmap/sfm/incremental_mapper.cc @@ -340,7 +340,7 @@ void BindIncrementalMapperImpl(py::module& m) { // TODO: migrate comments. improve formatting py::class_>( m, "IncrementalMapper") - .def(py::init>()) + .def(py::init>(), "database_cache"_a) .def("begin_reconstruction", &IncrementalMapper::BeginReconstruction, "reconstruction"_a)