KISS-Matcher: point cloud registration from C++ to a Python wheel
KISS-Matcher: Fast, Robust, and Scalable Registration + ROS2 SLAM examples
At a glance
- What is it?
- KISS-Matcher is a C++ point cloud registration library with a Python package on PyPI and ROS2 example integrations, built around FPFH features, feature matching and graph pruning. It fits robotics teams that need to align lidar or depth scans fast, and its installation is where most of the friction lives.
- Who is it for?
- Adopt KISS-Matcher when your pipeline needs to align two point clouds quickly and you want the same implementation available as a C++ library and as a Python package, which is the case for teams doing offline experiments in Python and then shipping the matching code inside a ROS2 or lidar pipeline. Skip it if you only need a one off alignment in an existing toolchain, because the C++ path pulls in ROBIN and a CMake dependency tree that has to be built.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 24 days ago.
- What is it written in?
- Mainly C++, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What KISS-Matcher is actually for
The project describes itself as fast and scalable registration plus ROS2 SLAM examples, and the topic list is more informative than that slogan: 3d-mapping, faster-pfh, feature-extraction, feature-matching, fpfh, graph-pruning, lidar, lidar-slam, point-cloud-registration, pointcloud-registration, registration, rgb-d, ros2 and slam.
Read together, those topics describe a point cloud registration library with a ROS2 integration layer. Registration is the hard part of mapping: given two scans of the same scene taken from different positions, work out the rigid transform that maps one onto the other. Every SLAM front end, every loop closure check and every scan-to-map update needs that answer, and the cost of getting it wrong compounds across a trajectory.
Who should care? Robotics teams running lidar or depth cameras, groups building or evaluating SLAM stacks, and researchers who need a registration component they can call from C++ inside a live system or from Python in a notebook. The two language front ends exist because those are two very different workflows, and the project keeps them pointed at the same core rather than at two implementations.
The repository carries an `arxiv` link and a citation request for academic use, and it was published through MIT-SPARK, so the project also positions itself as research code that other groups build on. The stated design intent is compact enough to state plainly: keep it simple, make it scalable.
FPFH features and graph pruning as the pipeline
The mechanism follows the standard shape of a feature based registration pipeline, and the topic list names each stage. The project carries a `faster-pfh` tag alongside the plain `fpfh` one, which points to an interest in speeding up the feature histogram computation that dominates the front of the pipeline.
The stages are recognisable from the tags. Feature extraction turns a point cloud into local descriptors, FPFH being the fast point feature histogram family the project names directly. Feature matching pairs those descriptors between the source and target clouds, producing candidate correspondences that are numerous and mostly wrong. Graph pruning then removes the inconsistent ones, since a rigid transform cannot satisfy arbitrary pairs, and the surviving correspondence set is what gets used to estimate the final pose.
That pipeline shape explains the profile of the tool. Descriptor computation dominates when the clouds are large, correspondence filtering dominates when the scene is repetitive, and both scale with point count rather than with scene size. A library that reduces the per point cost and prunes aggressively buys speed on the inputs robotics actually produces, which are large and repetitive.
The repository layout supports the same reading. A `cpp/` directory holds the core and an `examples` tree described as providing plentiful scalable registration examples, `python/` holds the bindings and examples, `ros/` holds the ROS2 side, and `shellscripts/` holds helper scripts. The paper linked from the README is the place to read the derivation behind those choices.
Installing the C++ core with make cppinstall
The README states that all installations are set up automatically in an out-of-the-box manner, and the entry point is a clone plus a dependency step:
git clone https://github.com/MIT-SPARK/KISS-Matcher.git
cd KISS-Matcher
make deps`make deps` auto-detects the host OS. On Linux (Ubuntu/Debian) it installs the toolchain via `apt-get`. On macOS it installs via Homebrew, and the Makefile chooses between them with a `uname -s` check at build time, so the same command works on both.
The C++ install is then a single target:
git clone https://github.com/MIT-SPARK/KISS-Matcher.git
cd KISS-Matcher
make cppinstallThe `cppinstall` command is encapsulated in the Makefile, and `cppinstall` calls `deps` to install the dependencies automatically, so running it alone is enough. KISS-Matcher also requires ROBIN, and ROBIN is automatically linked via `robin.cmake`. After installation, `kiss_matcher` and `robin` are placed in the installation directory by `cmake --install` invocations for the KISS-Matcher build and the ROBIN build, and both use `$(SUDO)` so the artifacts land in system paths without an extra manual copy.
One detail in the Makefile is worth knowing before you install anything: SUDO is resolved by testing for a `/.dockerenv` file, and inside a container it is set empty. The same build therefore behaves differently on a workstation and in a container image, which is convenient but means a local success does not guarantee a container success.
A pre-existing ROBIN install changes the build path
The README documents one failure mode explicitly, and it is the kind that produces a confusing error rather than an obvious one. If ROBIN is already installed in your environment, the build fails with CMake errors about a missing `cmake_install.cmake` inside the ROBIN build directory, followed by a Makefile error on the `cppinstall` target.
The fix is a different target:
make cppinstall_matcher_onlyThis is worth flagging to anyone packaging the project, because the failure message mentions a path deep inside a dependency build tree rather than naming the conflict. A user who has used ROBIN before on the same machine hits a wall that looks like a corrupted checkout rather than a version mismatch.
The same conflict has a second dimension on macOS. When invoking `cmake` directly instead of going through `make cppinstall`, the README recommends passing `-DUSE_SYSTEM_ROBIN=OFF`, which forces a fresh ROBIN via `FetchContent` and avoids picking up an older or incompatible system install. On Linux that flag is not required, but it is described as harmless. So the portable, predictable configuration is the one that always fetches ROBIN itself, even where a system copy would have worked.
macOS builds need Homebrew LLVM because AppleClang has no OpenMP
The macOS story is the one place where the out-of-the-box claim needs a caveat, and the reason is specific rather than general. AppleClang does not ship with OpenMP, so the project pulls in `llvm` and `libomp` from Homebrew, and the Makefile automatically routes the C++ build through `$(brew --prefix llvm)/bin/clang++`.
If you invoke `cmake` directly on macOS instead of going through `make cppinstall`, point CMake at the Homebrew LLVM toolchain so OpenMP is available:
LLVM_PREFIX=$(brew --prefix llvm)
cmake -S cpp/kiss_matcher -B build \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_C_COMPILER="$LLVM_PREFIX/bin/clang" \
-DCMAKE_CXX_COMPILER="$LLVM_PREFIX/bin/clang++" \
-DUSE_SYSTEM_ROBIN=OFF
cmake --build build -j$(sysctl -n hw.ncpu)Homebrew itself is a prerequisite, and the Makefile fails with an explicit error message if `brew` is missing on a Darwin host. The dependency set installed by `make deps` on macOS is cmake, ninja, eigen, tbb, lz4, flann, llvm, libomp and ccache. The Linux set is comparable in spirit and includes gcc, g++, build-essential, libeigen3-dev, python3-pip, python3-dev, cmake, git, ninja-build and libflann-dev.
The parallel build flag differs by platform too, `sysctl -n hw.ncpu` on macOS and `nproc --all` on Linux, both with a fallback of 4.
The Python package, the viz extra, and a synthetic smoke test
Since May 19, 2026, the Python package is available on PyPI. Installation is a one-liner, with an optional extra for the visualisation demo:
pip install kiss-matcher # core only (numpy)
pip install kiss-matcher[viz] # adds viser for the visualization demoThe published wheels cover Linux x86_64 manylinux_2_28 and up, plus macOS 14 and above on arm64, with an sdist build elsewhere. That distribution matrix is the practical answer to whether you need a compiler: on the listed platforms you get a binary, and anywhere else you build from source.
For a source checkout, the editable route installs the build toolchain first:
pip install --upgrade pip setuptools wheel scikit-build-core ninja cmake build
pip install -e python/The first useful thing to run is the synthetic smoke test, which needs no external data and no viser:
python python/examples/quickstart.pyIt generates 5k random points, applies a known rigid transform, and prints the recovered rotation and translation errors. The README states the expected outcome: sub-degree rotation error and sub-centimetre translation error. Because the transform is known, this is a correctness check on the estimator rather than a quality check on real data, which is exactly why it is a good first run.
For real point clouds with 3D visualisation, which requires the `[viz]` extra:
python python/examples/run_kiss_matcher.py \
--src_path /path/to/src.pcd \
--tgt_path /path/to/tgt.pcd \
--resolution 0.3The resolution argument is the voxel size used for downsampling, and it is the knob you will be tuning first on real scans.
Release cadence, licence, and the gaps in the documentation
Three releases carry the project: KISS-Matcher v1.0.0 on 2026-05-09, v1.0.1 on 2026-05-10 and v1.0.2 on 2026-05-10. All three landed within about a day of each other, which tells you the library was stabilised and released in one pass rather than iterated on publicly over months. The repository is not archived and the last push was on 2026-09-29, so work continued after the release line.
The licence is MIT, with the licence file at the repository root, and the project asks that academic work cite the original paper, which is linked to arXiv.
The documentation gap is the more interesting part. The README covers installation, build flags, examples and the citation request, and it stops there. It does not publish a benchmark table, so claims about speed and scalability have to be read from the paper rather than taken from the repository. It does not state a minimum C++ standard, a list of supported ROS2 distributions beyond the ROS2 Humble badge, or the exact dependency versions that a successful build pins. It also does not document what the `faster-pfh` variant changes relative to standard FPFH, even though that tag is one of the project's headline features.
Two smaller gaps matter for integration. The Python examples are referenced by directory rather than described, and the C++ examples live under `cpp/examples` with their own `CMakeLists.txt` for use in other packages, so integrating KISS-Matcher into an existing C++ project means reading those files rather than following a documented snippet. A team standardising on the Python path avoids all of that, at the cost of losing the fine control the C++ targets expose.
Editorial conclusion
Adopt KISS-Matcher when your pipeline needs to align two point clouds quickly and you want the same implementation available as a C++ library and as a Python package, which is the case for teams doing offline experiments in Python and then shipping the matching code inside a ROS2 or lidar pipeline. Skip it if you only need a one off alignment in an existing toolchain, because the C++ path pulls in ROBIN and a CMake dependency tree that has to be built. Verify first that `make cppinstall` completes on your host, because a pre-existing ROBIN install changes the build path, and on macOS confirm that Homebrew LLVM is on the path since the default AppleClang has no OpenMP. If the Python route is enough, `pip install kiss-matcher` is the cheaper starting point.
Frequently asked questions
How do I install KISS-Matcher for C++?
Clone the repository, run make deps to install the toolchain for your host OS, and then run make cppinstall, which calls deps itself and installs both kiss_matcher and robin. If ROBIN is already present on the machine, the build fails and make cppinstall_matcher_only is the target to use instead.
Can I install KISS-Matcher from Python?
Yes, the Python package has been on PyPI since May 19, 2026. Use pip install kiss-matcher for the core package with numpy, or pip install kiss-matcher[viz] to add viser for the visualisation demo, and run python python/examples/quickstart.py as a smoke test.
Why does the KISS-Matcher build fail on macOS?
AppleClang does not ship with OpenMP, so the project pulls llvm and libomp from Homebrew and routes the build through $(brew --prefix llvm)/bin/clang++. If you call cmake directly, pass the Homebrew LLVM compiler paths and -DUSE_SYSTEM_ROBIN=OFF as shown in the README.
What does the KISS-Matcher quickstart test verify?
The quickstart generates 5k random points, applies a known rigid transform, and prints the recovered rotation and translation errors. The README states the expected outcome is sub-degree rotation error and sub-centimetre translation error, so it checks the estimator against a known answer rather than measuring performance.
Does KISS-Matcher work with ROS2?
The project ships ROS2 example integrations in a ros directory and carries ROS2 Humble among its badges, and the description calls it a registration plus ROS2 SLAM example project. The README itself links to the examples directories rather than documenting ROS2 setup steps.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/mit-spark-kiss-matcher)Was this useful?