From e21a60aa9e7726e4df478e4252f172c055be58d1 Mon Sep 17 00:00:00 2001 From: jcchr Date: Thu, 30 Jan 2025 11:05:30 +0100 Subject: [PATCH 1/2] instance segmentation interface --- .../py_bindings/py_instance_segmentation.cpp | 163 ++++++++++++++++++ 1 file changed, 163 insertions(+) create mode 100644 src/cpp/py_bindings/py_instance_segmentation.cpp diff --git a/src/cpp/py_bindings/py_instance_segmentation.cpp b/src/cpp/py_bindings/py_instance_segmentation.cpp new file mode 100644 index 00000000..f7f9f778 --- /dev/null +++ b/src/cpp/py_bindings/py_instance_segmentation.cpp @@ -0,0 +1,163 @@ +/* + * Copyright (C) 2025 Intel Corporation + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#include "models/instance_segmentation.h" +#include "models/results.h" +#include "py_utils.hpp" + +namespace pyutils = vision::nanobind::utils; + +using ScoresOutput = nb::ndarray; +using LabelsOutput = nb::ndarray; + +void init_instance_segmentation(nb::module_& m) { + nb::class_(m, "MaskRCNNModel") + .def_static( + "create_model", + [](const std::string& model_path, + const std::map& configuration, + bool preload, + const std::string& device) { + auto ov_any_config = ov::AnyMap(); + for (const auto& item : configuration) { + ov_any_config[item.first] = pyutils::py_object_to_any(item.second, item.first); + } + + + return MaskRCNNModel::create_model(model_path, ov_any_config, preload, device); + }, + nb::arg("model_path"), + nb::arg("configuration") = ov::AnyMap({}), + nb::arg("preload") = true, + nb::arg("device") = "AUTO") + + .def("__call__", + [](MaskRCNNModel& self, const nb::ndarray<>& input) { + return self.infer(pyutils::wrap_np_mat(input)); + }) + .def("infer_batch", + [](MaskRCNNModel& self, const std::vector> inputs) { + std::vector input_mats; + input_mats.reserve(inputs.size()); + + for (const auto& input : inputs) { + input_mats.push_back(pyutils::wrap_np_mat(input)); + } + + return self.inferBatch(input_mats); + }) + .def_prop_ro_static("__model__", [](nb::object) { + return MaskRCNNModel::ModelType; + }); + + nb::class_(m, "InstanceSegmentationResult") + .def(nb::init>(), nb::arg("frameId") = -1, nb::arg("metaData") = nullptr) + .def_prop_ro( + "feature_vector", + [](InstanceSegmentationResult& r) { + if (!r.feature_vector) { + return nb::ndarray(); + } + + return nb::ndarray(r.feature_vector.data(), + r.feature_vector.get_shape().size(), + r.feature_vector.get_shape().data()); + }, + nb::rv_policy::reference_internal) + .def_prop_ro("label_names", + [](InstanceSegmentationResult& r) { + size_t labels_count = static_cast(r.segmentedObjects.size()); + std::vector labels(labels_count); + + for (size_t i = 0; i < labels_count; ++i) { + labels[i] = r.segmentedObjects[i].label; + } + + return labels; + }) + .def_prop_ro("labels", + [](InstanceSegmentationResult& r) { + size_t labels_count = static_cast(r.segmentedObjects.size()); + std::vector labels(labels_count); + + for (size_t i = 0; i < labels_count; ++i) { + labels[i] = r.segmentedObjects[i].labelID; + } + + return LabelsOutput(labels.data(), {labels_count}).cast(); + }) + .def_prop_ro("scores", + [](InstanceSegmentationResult& r) { + size_t scores_count = static_cast(r.segmentedObjects.size()); + std::vector scores(scores_count); + + for (size_t i = 0; i < scores_count; ++i) { + scores[i] = r.segmentedObjects[i].confidence; + } + + return ScoresOutput(scores.data(), {scores_count}).cast(); + }) + .def_prop_ro("bboxes", + [](InstanceSegmentationResult& r) { + size_t boxes_count = static_cast(r.segmentedObjects.size()); + std::vector> boxes(boxes_count); + + for (size_t i = 0; i < boxes_count; ++i) { + std::vector box(4); + box[0] = r.segmentedObjects[i].tl().x; + box[1] = r.segmentedObjects[i].tl().y; + box[2] = r.segmentedObjects[i].br().x; + box[3] = r.segmentedObjects[i].br().y; + boxes[i] = box; + } + + return boxes; + }) + .def_prop_ro("masks", + [](InstanceSegmentationResult& r) { + size_t elements_count = static_cast(r.segmentedObjects.size()); + std::vector>> masks(elements_count); + + for (size_t i = 0; i < elements_count; ++i) { + int rows = r.segmentedObjects[i].mask.rows; + int cols = r.segmentedObjects[i].mask.cols; + + std::vector> mask(rows, std::vector(cols)); + + for (int row = 0; row < rows; ++row) { + for (int col = 0; col < cols; ++col) { + mask[row][col] = r.segmentedObjects[i].mask.at(row, col); + } + } + + masks[i] = mask; + } + + return masks; + }) + .def_prop_ro( + "saliency_map", + [](InstanceSegmentationResult& r) { + if (r.saliency_map.empty()) { + return nb::ndarray(); + } + int rows = r.saliency_map[0].rows; + int cols = r.saliency_map[0].cols; + int num_matrices = r.saliency_map.size(); + + return nb::ndarray(&r.saliency_map, + {static_cast(num_matrices), + static_cast(rows), + static_cast(cols)}); + }, + nb::rv_policy::reference_internal); +} From 72f4bf12b82c148e86c41adcb5a84d36da5c71cc Mon Sep 17 00:00:00 2001 From: jcchr Date: Thu, 30 Jan 2025 15:27:42 +0100 Subject: [PATCH 2/2] clang-format correction --- .../py_bindings/py_instance_segmentation.cpp | 118 +++++++++--------- 1 file changed, 58 insertions(+), 60 deletions(-) diff --git a/src/cpp/py_bindings/py_instance_segmentation.cpp b/src/cpp/py_bindings/py_instance_segmentation.cpp index f7f9f778..9e864010 100644 --- a/src/cpp/py_bindings/py_instance_segmentation.cpp +++ b/src/cpp/py_bindings/py_instance_segmentation.cpp @@ -32,7 +32,6 @@ void init_instance_segmentation(nb::module_& m) { ov_any_config[item.first] = pyutils::py_object_to_any(item.second, item.first); } - return MaskRCNNModel::create_model(model_path, ov_any_config, preload, device); }, nb::arg("model_path"), @@ -74,76 +73,76 @@ void init_instance_segmentation(nb::module_& m) { }, nb::rv_policy::reference_internal) .def_prop_ro("label_names", - [](InstanceSegmentationResult& r) { - size_t labels_count = static_cast(r.segmentedObjects.size()); - std::vector labels(labels_count); + [](InstanceSegmentationResult& r) { + size_t labels_count = static_cast(r.segmentedObjects.size()); + std::vector labels(labels_count); - for (size_t i = 0; i < labels_count; ++i) { - labels[i] = r.segmentedObjects[i].label; - } + for (size_t i = 0; i < labels_count; ++i) { + labels[i] = r.segmentedObjects[i].label; + } - return labels; - }) + return labels; + }) .def_prop_ro("labels", - [](InstanceSegmentationResult& r) { - size_t labels_count = static_cast(r.segmentedObjects.size()); - std::vector labels(labels_count); + [](InstanceSegmentationResult& r) { + size_t labels_count = static_cast(r.segmentedObjects.size()); + std::vector labels(labels_count); - for (size_t i = 0; i < labels_count; ++i) { - labels[i] = r.segmentedObjects[i].labelID; - } + for (size_t i = 0; i < labels_count; ++i) { + labels[i] = r.segmentedObjects[i].labelID; + } - return LabelsOutput(labels.data(), {labels_count}).cast(); - }) + return LabelsOutput(labels.data(), {labels_count}).cast(); + }) .def_prop_ro("scores", - [](InstanceSegmentationResult& r) { - size_t scores_count = static_cast(r.segmentedObjects.size()); - std::vector scores(scores_count); + [](InstanceSegmentationResult& r) { + size_t scores_count = static_cast(r.segmentedObjects.size()); + std::vector scores(scores_count); - for (size_t i = 0; i < scores_count; ++i) { - scores[i] = r.segmentedObjects[i].confidence; - } + for (size_t i = 0; i < scores_count; ++i) { + scores[i] = r.segmentedObjects[i].confidence; + } - return ScoresOutput(scores.data(), {scores_count}).cast(); - }) + return ScoresOutput(scores.data(), {scores_count}).cast(); + }) .def_prop_ro("bboxes", - [](InstanceSegmentationResult& r) { - size_t boxes_count = static_cast(r.segmentedObjects.size()); - std::vector> boxes(boxes_count); - - for (size_t i = 0; i < boxes_count; ++i) { - std::vector box(4); - box[0] = r.segmentedObjects[i].tl().x; - box[1] = r.segmentedObjects[i].tl().y; - box[2] = r.segmentedObjects[i].br().x; - box[3] = r.segmentedObjects[i].br().y; - boxes[i] = box; - } - - return boxes; - }) + [](InstanceSegmentationResult& r) { + size_t boxes_count = static_cast(r.segmentedObjects.size()); + std::vector> boxes(boxes_count); + + for (size_t i = 0; i < boxes_count; ++i) { + std::vector box(4); + box[0] = r.segmentedObjects[i].tl().x; + box[1] = r.segmentedObjects[i].tl().y; + box[2] = r.segmentedObjects[i].br().x; + box[3] = r.segmentedObjects[i].br().y; + boxes[i] = box; + } + + return boxes; + }) .def_prop_ro("masks", - [](InstanceSegmentationResult& r) { - size_t elements_count = static_cast(r.segmentedObjects.size()); - std::vector>> masks(elements_count); + [](InstanceSegmentationResult& r) { + size_t elements_count = static_cast(r.segmentedObjects.size()); + std::vector>> masks(elements_count); - for (size_t i = 0; i < elements_count; ++i) { - int rows = r.segmentedObjects[i].mask.rows; - int cols = r.segmentedObjects[i].mask.cols; + for (size_t i = 0; i < elements_count; ++i) { + int rows = r.segmentedObjects[i].mask.rows; + int cols = r.segmentedObjects[i].mask.cols; - std::vector> mask(rows, std::vector(cols)); + std::vector> mask(rows, std::vector(cols)); - for (int row = 0; row < rows; ++row) { - for (int col = 0; col < cols; ++col) { - mask[row][col] = r.segmentedObjects[i].mask.at(row, col); - } - } + for (int row = 0; row < rows; ++row) { + for (int col = 0; col < cols; ++col) { + mask[row][col] = r.segmentedObjects[i].mask.at(row, col); + } + } - masks[i] = mask; - } + masks[i] = mask; + } - return masks; - }) + return masks; + }) .def_prop_ro( "saliency_map", [](InstanceSegmentationResult& r) { @@ -154,10 +153,9 @@ void init_instance_segmentation(nb::module_& m) { int cols = r.saliency_map[0].cols; int num_matrices = r.saliency_map.size(); - return nb::ndarray(&r.saliency_map, - {static_cast(num_matrices), - static_cast(rows), - static_cast(cols)}); + return nb::ndarray( + &r.saliency_map, + {static_cast(num_matrices), static_cast(rows), static_cast(cols)}); }, nb::rv_policy::reference_internal); }