Skip to content

Commit

Permalink
bind_vector
Browse files Browse the repository at this point in the history
initializer_list -> vector
TODO: Check F-Score values are correct
  • Loading branch information
ssheorey committed Nov 16, 2024
1 parent 2f8a97c commit b8651e9
Show file tree
Hide file tree
Showing 12 changed files with 57 additions and 29 deletions.
7 changes: 3 additions & 4 deletions cpp/open3d/t/geometry/PointCloud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1332,10 +1332,9 @@ int PointCloud::PCAPartition(int max_points) {
return num_partitions;
}

std::vector<float> PointCloud::ComputeDistance(
const PointCloud &pcd2,
std::initializer_list<Metric> metrics,
MetricParameters params) const {
std::vector<float> PointCloud::ComputeDistance(const PointCloud &pcd2,
std::vector<Metric> metrics,
MetricParameters params) const {
if (!IsCPU() || !pcd2.IsCPU()) {
utility::LogWarning(
"ComputeDistance is implemented only on CPU. Computing on "
Expand Down
2 changes: 1 addition & 1 deletion cpp/open3d/t/geometry/PointCloud.h
Original file line number Diff line number Diff line change
Expand Up @@ -707,7 +707,7 @@ class PointCloud : public Geometry, public DrawableGeometry {
/// different metrics.
std::vector<float> ComputeDistance(
const PointCloud &pcd2,
std::initializer_list<Metric> metrics = {Metric::ChamferDistance},
std::vector<Metric> metrics = {Metric::ChamferDistance},
MetricParameters params = MetricParameters()) const;

protected:
Expand Down
2 changes: 1 addition & 1 deletion cpp/open3d/t/geometry/TriangleMesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1593,7 +1593,7 @@ PointCloud TriangleMesh::SamplePointsUniformly(

std::vector<float> TriangleMesh::ComputeDistance(
const TriangleMesh &mesh2,
std::initializer_list<Metric> metrics,
std::vector<Metric> metrics,
MetricParameters params) const {
if (!IsCPU() || !mesh2.IsCPU()) {
utility::LogWarning(
Expand Down
2 changes: 1 addition & 1 deletion cpp/open3d/t/geometry/TriangleMesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -1030,7 +1030,7 @@ class TriangleMesh : public Geometry, public DrawableGeometry {
/// different metrics.
std::vector<float> ComputeDistance(
const TriangleMesh &mesh2,
std::initializer_list<Metric> metrics = {Metric::ChamferDistance},
std::vector<Metric> metrics = {Metric::ChamferDistance},
MetricParameters params = MetricParameters()) const;

protected:
Expand Down
15 changes: 8 additions & 7 deletions cpp/open3d/t/geometry/kernel/Metrics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,17 @@ namespace geometry {
std::vector<float> OPEN3D_LOCAL
ComputeDistanceCommon(core::Tensor distance12,
core::Tensor distance21,
std::initializer_list<Metric> metrics,
std::vector<Metric> metrics,
MetricParameters params) {
std::vector<float> metric_values;
float metric_val;

for (Metric metric : metrics) {
switch (metric) {
case Metric::ChamferDistance:
metric_val = 0.5 * (distance21.Mean({-1}).Item<float>() +
distance12.Mean({-1}).Item<float>());
metric_val = 0.5 *
(distance21.Reshape({-1}).Mean({0}).Item<float>() +
distance12.Reshape({-1}).Mean({0}).Item<float>());
metric_values.push_back(metric_val);
break;
case Metric::FScore:
Expand All @@ -35,13 +36,13 @@ ComputeDistanceCommon(core::Tensor distance12,
// Workaround since we don't have Tensor::CountNonZeros
float precision = 0., recall = 0.;
for (size_t i = 0;
i < static_cast<size_t>(distance12.GetLength()); ++i)
i < static_cast<size_t>(distance12.NumElements()); ++i)
precision += p_distance12[i] < radius;
precision *= 100. / distance12.GetLength();
precision *= 100. / distance12.NumElements();
for (size_t i = 0;
i < static_cast<size_t>(distance21.GetLength()); ++i)
i < static_cast<size_t>(distance21.NumElements()); ++i)
recall += p_distance21[i] < radius;
recall *= 100. / distance21.GetLength();
recall *= 100. / distance21.NumElements();
float fscore = 0.0;
if (precision + recall > 0) {
fscore = 2 * precision * recall / (precision + recall);
Expand Down
2 changes: 1 addition & 1 deletion cpp/open3d/t/geometry/kernel/Metrics.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ namespace geometry {

std::vector<float> ComputeDistanceCommon(core::Tensor distance12,
core::Tensor distance21,
std::initializer_list<Metric> metrics,
std::vector<Metric> metrics,
MetricParameters params);
}
} // namespace t
Expand Down
2 changes: 1 addition & 1 deletion cpp/pybind/data/dataset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ void pybind_data_classes(py::module& m) {
m, "DataDescriptor",
"DataDescriptor is a class that describes a data file. It contains "
"the URL mirrors to download the file, the MD5 hash of the file, "
"and wether to extract the file.");
"and whether to extract the file.");
data_descriptor
.def(py::init([](const std::vector<std::string>& urls,
const std::string& md5,
Expand Down
13 changes: 10 additions & 3 deletions cpp/pybind/t/geometry/geometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@

#include "open3d/t/geometry/Geometry.h"

#include <pybind11/stl_bind.h>

#include <vector>

#include "pybind/docstring.h"
#include "pybind/open3d_pybind.h"
#include "pybind/t/geometry/geometry.h"

namespace open3d {
Expand Down Expand Up @@ -50,7 +53,8 @@ void pybind_geometry_declarations(py::module& m) {
"Chamfer Distance")
.value("FScore", Metric::FScore, "F-Score")
.export_values();
py::class_<MetricParameters>(
py::bind_vector<std::vector<Metric>>(m_geometry, "VectorMetric");
py::class_<MetricParameters> metric_parameters(
m_geometry, "MetricParameters",
"Holder for various parameters required by metrics.");

Expand All @@ -69,9 +73,12 @@ void pybind_geometry_declarations(py::module& m) {
void pybind_geometry_definitions(py::module& m) {
auto m_geometry = static_cast<py::module>(m.attr("geometry"));

auto metric_params = static_cast<py::class_<MetricParameters>>(
auto metric_parameters = static_cast<py::class_<MetricParameters>>(
m_geometry.attr("MetricParameters"));
metric_params.def(py::init<const std::vector<float>&, size_t>())
metric_parameters
.def(py::init<const std::vector<float>&, size_t>(),
"fscore_radius"_a = std::vector<float>{0.01},
"n_sampled_points"_a = 1000)
.def_readwrite("fscore_radius", &MetricParameters::fscore_radius,
"Radius for computing the F-Score. A match between "
"a point and its nearest neighbor is sucessful if "
Expand Down
9 changes: 4 additions & 5 deletions cpp/pybind/t/geometry/trianglemesh.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1086,11 +1086,10 @@ adjacent triangles to the edge is `<= 2`.
Example::
dataset = o3d.data.AvocadoModel()
model = o3d.io.read_triangle_model(dataset.path)
meshes = o3d.t.geometry.TriangleMesh.from_triangle_mesh_model(model)
pcd = meshes[0].sample_points_uniformly(1000)
o3d.visualization.draw([model, pcd])
mesh = o3d.t.geometry.TriangleMesh.create_box()
mesh.vertex.colors = mesh.vertex.positions.clone()
pcd = mesh.sample_points_uniformly(100000)
o3d.visualization.draw([mesh, pcd], point_size=5, show_ui=True, show_skybox=False)
)");

Expand Down
1 change: 1 addition & 0 deletions cpp/pybind/utility/eigen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ namespace utility {

void pybind_eigen_declarations(py::module &m) {
auto intvector = pybind_eigen_vector_of_scalar<int>(m, "IntVector");
auto floatvector = pybind_eigen_vector_of_scalar<float>(m, "FloatVector");
auto doublevector =
pybind_eigen_vector_of_scalar<double>(m, "DoubleVector");
auto vector3dvector = pybind_eigen_vector_of_vector<Eigen::Vector3d>(
Expand Down
17 changes: 17 additions & 0 deletions python/test/t/geometry/test_pointcloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -193,3 +193,20 @@ def test_pickle(device):
assert pcd_load.point.positions.device == device and pcd_load.point.positions.dtype == o3c.float32
np.testing.assert_equal(pcd.point.positions.cpu().numpy(),
pcd_load.point.positions.cpu().numpy())


def test_metrics():

from open3d.t.geometry import Metric, MetricParameters
pos = o3d.t.geometry.TriangleMesh.create_box().vertex.positions
pcd1 = o3d.t.geometry.PointCloud(pos.clone())
pcd2 = o3d.t.geometry.PointCloud(pos * 1.2)

metric_params = MetricParameters(
fscore_radius=o3d.utility.FloatVector((0.05, 0.15)))
metrics = pcd1.compute_distance(pcd2,
(Metric.ChamferDistance, Metric.FScore),
metric_params)

print(metrics)
np.testing.assert_allclose(metrics, (0.03, 200. / 3, 100), rtol=1e-6)
14 changes: 9 additions & 5 deletions python/test/t/geometry/test_trianglemesh.py
Original file line number Diff line number Diff line change
Expand Up @@ -1399,10 +1399,14 @@ def test_metrics():
from open3d.t.geometry import Metric, MetricParameters
box1 = o3d.t.geometry.TriangleMesh.create_box()
box2 = o3d.t.geometry.TriangleMesh.create_box()
box2.vertex.positions += 0.1
box2.vertex.positions *= 1.2

metrics = box1.compute_distance(
box2, (Metric.ChamferDistance, Metric.FScore),
MetricParameters(fscore_radius=(0.05, 0.15), n_sampled_points=10))
metric_params = MetricParameters(fscore_radius=o3d.utility.FloatVector(
(0.05, 0.15)),
n_sampled_points=100000)
metrics = box1.compute_distance(box2,
(Metric.ChamferDistance, Metric.FScore),
metric_params)

assert metrics == (0.1, 0, 1)
print(metrics)
np.testing.assert_allclose(metrics, (0.1, 45, 53.2), rtol=0.05)

0 comments on commit b8651e9

Please sign in to comment.