diff --git a/README.md b/README.md index 40c5140..ce69be7 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ - C++ source code of Patchwork++ ([patchworkpp][sourcecodelink]) - Python binding of Patchwork++ using pybind11 ([python_wrapper][wraplink]) - Examples codes of [C++][cppexamplelink], [Python][pyexamplelink], and [ROS2][rosexamplelink] :thumbsup: +- Full suppor of a reproducible **SemanticKITTI evaluation harness** for both Patchwork and Patchwork++ ([`python/examples/evaluate_semantickitti.py`][evallink]). In the papers of Patchwork and Patchwork++, we use **different evaluation protocols** — see [`USAGE.md`][usagelink] §1 for why and §4 for per-sequence numbers. > If you are familiar with ROS1, you can also visit [here][roslink] and try executing ROS1-based Patchwork++! @@ -68,23 +69,23 @@ Eigen is fetched automatically by CMake, so no extra system package is required ### Python -**Pure installation** +The released library is on PyPI: ```commandline -make pyinstall +pip install pypatchworkpp # core library +pip install 'pypatchworkpp[demo]' # + Open3D for the visual demos ``` -Then, you can use Patchwork++ by `import pypatchworkpp`, which is super simple! - -**Installation to run demo** +Then `import pypatchworkpp` in your script — see the [Python examples][pyexamplelink]. -Only Open3D (> 0.17.0) is additionally installed for visualization purposes. +
Build from source (contributors / unreleased main) ```commandline -make pyinstall_with_demo +make pyinstall # equivalent to `pip install ./python/` +make pyinstall_with_demo # also installs Open3D >= 0.17.0 ``` -How to run Python demos is explained [here][pyexamplelink]. +
### C++ @@ -135,9 +136,13 @@ pp_default = p.patchworkpp(p.Parameters()) # Patchwork++ pp_classic = p.patchwork(p.PatchworkParams()) # Patchwork (classic) ``` -**ROS2:** +**ROS2:** Patchwork++ is the default; pass `algorithm:=patchwork` to switch to the classic Patchwork. ```bash +# Default — runs Patchwork++ +ros2 launch patchworkpp patchworkpp.launch.py + +# Override to the classic Patchwork ros2 launch patchworkpp patchworkpp.launch.py algorithm:=patchwork ``` @@ -193,6 +198,7 @@ ______________________________________________________________________ [arxivlink]: https://arxiv.org/abs/2207.11919 [cppexamplelink]: https://github.com/url-kaist/patchwork-plusplus/tree/master/cpp +[evallink]: python/examples/evaluate_semantickitti.py [htlink]: https://github.com/LimHyungTae [patchworkarxivlink]: https://arxiv.org/abs/2108.05560 [patchworkieeelink]: https://ieeexplore.ieee.org/document/9466396 @@ -203,4 +209,5 @@ ______________________________________________________________________ [roslink]: https://github.com/url-kaist/patchwork-plusplus-ros [sjlink]: https://github.com/seungjae24 [sourcecodelink]: https://github.com/url-kaist/patchwork-plusplus/tree/master/cpp/patchworkpp +[usagelink]: USAGE.md [wraplink]: https://github.com/url-kaist/patchwork-plusplus/tree/master/python/patchworkpp diff --git a/USAGE.md b/USAGE.md index da092c0..a43194e 100644 --- a/USAGE.md +++ b/USAGE.md @@ -14,6 +14,15 @@ ______________________________________________________________________ The Patchwork and Patchwork++ papers use **different** ground-truth definitions on SemanticKITTI. The eval driver `python/examples/evaluate_semantickitti.py` supports both via `--eval_protocol {patchwork, patchworkpp}`. +### Why the two papers disagree + +The disagreement is concentrated on one class: **`vegetation` (label 70)**. SemanticKITTI's `vegetation` label conflates two visually similar but physically very different things — low ground cover (grass, terrain weeds, leaves on flat ground) and overhead foliage / branches / hedge tops. The first is essentially ground; the second is not. + +- The **original Patchwork paper** picked a height-based proxy: `vegetation` points with `z < −1.30 m` w.r.t. the sensor frame count as ground, anything above does not. Simple, but it mislabels overhead foliage in low-mounted sensors and ground vegetation on hills. +- The **Patchwork++ paper** (Sec. IV.A) treats this as fundamentally unresolvable from labels alone and **excludes** `vegetation` from the evaluation entirely: *"the points labeled as vegetation are not evaluated as ground nor non-ground points exceptionally because it is impractical to regard the vegetation as a single ground or non-ground class"*. The points are still fed to the algorithm — only the scoring drops them. + +Either choice is defensible; they just yield different numbers on the same predictions. Always use the protocol that matches the paper you're comparing against. + ### A. `--eval_protocol patchwork` (original Patchwork repo protocol) - **Ground GT** = `{ROAD (40), PARKING (44), SIDEWALK (48), OTHER_GROUND (49), LANE_MARKING (60), VEGETATION (70, only if z < −1.30 m), TERRAIN (72)}`