opensfm/src/dense/depthmap_bind.h (117 lines of code) (raw):

#pragma once #include <dense/depthmap.h> #include <foundation/python_types.h> using namespace foundation; namespace dense { class DepthmapEstimatorWrapper { public: void AddView(pyarray_d K, pyarray_d R, pyarray_d t, pyarray_uint8 image, pyarray_uint8 mask) { if ((image.shape(0) != mask.shape(0)) || (image.shape(1) != mask.shape(1))){ throw std::invalid_argument("image and mask must have matching shapes."); } de_.AddView(K.data(), R.data(), t.data(), image.data(), mask.data(), image.shape(1), image.shape(0)); } void SetDepthRange(double min_depth, double max_depth, int num_depth_planes) { de_.SetDepthRange(min_depth, max_depth, num_depth_planes); } void SetPatchMatchIterations(int n) { de_.SetPatchMatchIterations(n); } void SetPatchSize(int size) { de_.SetPatchSize(size); } void SetMinPatchSD(float sd) { de_.SetMinPatchSD(sd); } py::object ComputePatchMatch() { DepthmapEstimatorResult result; { py::gil_scoped_release release; de_.ComputePatchMatch(&result); } return ComputeReturnValues(result); } py::object ComputePatchMatchSample() { DepthmapEstimatorResult result; { py::gil_scoped_release release; de_.ComputePatchMatchSample(&result); } return ComputeReturnValues(result); } py::object ComputeBruteForce() { DepthmapEstimatorResult result; { py::gil_scoped_release release; de_.ComputeBruteForce(&result); } return ComputeReturnValues(result); } py::object ComputeReturnValues(const DepthmapEstimatorResult &result) { py::list retn; retn.append(py_array_from_data(result.depth.ptr<float>(0), result.depth.rows, result.depth.cols)); retn.append(py_array_from_data(result.plane.ptr<float>(0), result.plane.rows, result.plane.cols, 3)); retn.append(py_array_from_data(result.score.ptr<float>(0), result.score.rows, result.score.cols)); retn.append(py_array_from_data(result.nghbr.ptr<int>(0), result.nghbr.rows, result.nghbr.cols)); return std::move(retn); } private: DepthmapEstimator de_; }; class DepthmapCleanerWrapper { public: void SetSameDepthThreshold(float t) { dc_.SetSameDepthThreshold(t); } void SetMinConsistentViews(int n) { dc_.SetMinConsistentViews(n); } void AddView(pyarray_d K, pyarray_d R, pyarray_d t, pyarray_f depth) { dc_.AddView(K.data(), R.data(), t.data(), depth.data(), depth.shape(1), depth.shape(0)); } py::object Clean() { cv::Mat depth; { py::gil_scoped_release release; dc_.Clean(&depth); } return py_array_from_data(depth.ptr<float>(0), depth.rows, depth.cols); } private: DepthmapCleaner dc_; }; class DepthmapPrunerWrapper { public: void SetSameDepthThreshold(float t) { dp_.SetSameDepthThreshold(t); } void AddView(pyarray_d K, pyarray_d R, pyarray_d t, pyarray_f depth, pyarray_f plane, pyarray_uint8 color, pyarray_uint8 label) { if ((depth.shape(0) != plane.shape(0)) || (depth.shape(1) != plane.shape(1))){ throw std::invalid_argument("depth and plane must have matching shapes."); } if ((depth.shape(0) != color.shape(0)) || (depth.shape(1) != color.shape(1))){ throw std::invalid_argument("depth and color must have matching shapes."); } if ((depth.shape(0) != label.shape(0)) || (depth.shape(1) != label.shape(1))){ throw std::invalid_argument("depth and label must have matching shapes."); } dp_.AddView(K.data(), R.data(), t.data(), depth.data(), plane.data(), color.data(), label.data(), depth.shape(1), depth.shape(0)); } py::object Prune() { std::vector<float> points; std::vector<float> normals; std::vector<unsigned char> colors; std::vector<unsigned char> labels; { py::gil_scoped_release release; dp_.Prune(&points, &normals, &colors, &labels); } py::list retn; int n = int(points.size()) / 3; retn.append(py_array_from_data(&points[0], n, 3)); retn.append(py_array_from_data(&normals[0], n, 3)); retn.append(py_array_from_data(&colors[0], n, 3)); retn.append(py_array_from_data(&labels[0], n)); return std::move(retn); } private: DepthmapPruner dp_; }; } // namespace dense