如何将 python 中的 this"a[0:3, 0:3]" 表达为 c++(pybind11)?
How to express this"a[0:3, 0:3]" in python as c++(pybind11)?
最近在使用pybind11的时候遇到了如何使用python代码a[0: 3,0: 3]
实现这个问题。目前有slice功能,但是没有找到相关的使用手册,导致访问不正确
ps: 你说的这个方法我试过,但是当我把矩阵打印出来的时候,发现不对。我不知道原因。请帮我。非常感谢。
cout result
py::scoped_interpreter guard{};
py::module np = py::module::import("numpy");
py::object random = np.attr("random");
py::module sys = py::module::import("sys");
py::print(sys.attr("path"));
py::module scipy = py::module::import("scipy.ndimage");
// get scipy.optimize.curve_fit
py::function affine_transform = scipy.attr("affine_transform");
py::array_t<float> new_affine = np.attr("eye")(4);
py::array_t<float> new_af = new_affine[py::make_tuple(py::slice(0, 3, 1), py::slice(0, 3, 1))];
std::cout << numpy_to_cv_mat(new_affine) << endl;
std::cout << new_af.size() << endl;
std::cout << numpy_to_cv_mat(new_af) << endl;
cv::Mat numpy_to_cv_mat(py::array_t<float>& input) { py::buffer_info buf = input.request(); cv::Mat mat(buf.shape[0], buf.shape[1], CV_32FC1, (float*)buf.ptr); return mat; }
此处需要一些详细信息。首先,py::slice(start, stop, step)
通过 pybind11 创建一个切片对象,就像 slice(start, stop, step)
在 Python 中创建的一样。
其次,给定一个 py::array
对象 a
,[]
运算符确实适用于 C++ 中的切片 (a[py::slice(s0,s1,st)]
) 但是 有一个重要警告:a[]
允许(并编译)多个参数,但实际上只有一个参数用于切片,因此 a[slice(...), slice(...)]
仅在第一个维度上应用切片。
对于多维切片,[]
运算符必须传递 py::tuple
个 py::slice
个对象。例如,Python 中的 a[0:3,0:3]
在 C++ 中将转换为以下内容:
// a is py::array
a[py::make_tuple(py::slice(0,3,1), py::slice(0,3,1))]
综上所述,这是一个完整的示例,它根据 start/stop 输入创建和切片二维数组:
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
namespace py = pybind11;
py::array do_slice(py::array a, py::int_ start, py::int_ stop) {
auto res = a[py::make_tuple(py::slice(start, stop, 1), py::slice(start, stop, 1))];
return res;
}
PYBIND11_MODULE(ex, m) {
m.def("do_slice", &do_slice);
}
编译后的一些使用示例:
>>> import numpy as np
>>> a = np.arange(16).reshape(4,4)
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
>>> import ex
>>> ex.do_slice(a, 0, 1)
array([[0]])
>>> ex.do_slice(a, 0, 2)
array([[0, 1],
[4, 5]])
>>> ex.do_slice(a, 0, 3)
array([[ 0, 1, 2],
[ 4, 5, 6],
[ 8, 9, 10]])
最近在使用pybind11的时候遇到了如何使用python代码a[0: 3,0: 3]
实现这个问题。目前有slice功能,但是没有找到相关的使用手册,导致访问不正确
ps: 你说的这个方法我试过,但是当我把矩阵打印出来的时候,发现不对。我不知道原因。请帮我。非常感谢。
cout result
py::scoped_interpreter guard{};
py::module np = py::module::import("numpy");
py::object random = np.attr("random");
py::module sys = py::module::import("sys");
py::print(sys.attr("path"));
py::module scipy = py::module::import("scipy.ndimage");
// get scipy.optimize.curve_fit
py::function affine_transform = scipy.attr("affine_transform");
py::array_t<float> new_affine = np.attr("eye")(4);
py::array_t<float> new_af = new_affine[py::make_tuple(py::slice(0, 3, 1), py::slice(0, 3, 1))];
std::cout << numpy_to_cv_mat(new_affine) << endl;
std::cout << new_af.size() << endl;
std::cout << numpy_to_cv_mat(new_af) << endl;
cv::Mat numpy_to_cv_mat(py::array_t<float>& input) { py::buffer_info buf = input.request(); cv::Mat mat(buf.shape[0], buf.shape[1], CV_32FC1, (float*)buf.ptr); return mat; }
此处需要一些详细信息。首先,py::slice(start, stop, step)
通过 pybind11 创建一个切片对象,就像 slice(start, stop, step)
在 Python 中创建的一样。
其次,给定一个 py::array
对象 a
,[]
运算符确实适用于 C++ 中的切片 (a[py::slice(s0,s1,st)]
) 但是 有一个重要警告:a[]
允许(并编译)多个参数,但实际上只有一个参数用于切片,因此 a[slice(...), slice(...)]
仅在第一个维度上应用切片。
对于多维切片,[]
运算符必须传递 py::tuple
个 py::slice
个对象。例如,Python 中的 a[0:3,0:3]
在 C++ 中将转换为以下内容:
// a is py::array
a[py::make_tuple(py::slice(0,3,1), py::slice(0,3,1))]
综上所述,这是一个完整的示例,它根据 start/stop 输入创建和切片二维数组:
#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
namespace py = pybind11;
py::array do_slice(py::array a, py::int_ start, py::int_ stop) {
auto res = a[py::make_tuple(py::slice(start, stop, 1), py::slice(start, stop, 1))];
return res;
}
PYBIND11_MODULE(ex, m) {
m.def("do_slice", &do_slice);
}
编译后的一些使用示例:
>>> import numpy as np
>>> a = np.arange(16).reshape(4,4)
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
>>> import ex
>>> ex.do_slice(a, 0, 1)
array([[0]])
>>> ex.do_slice(a, 0, 2)
array([[0, 1],
[4, 5]])
>>> ex.do_slice(a, 0, 3)
array([[ 0, 1, 2],
[ 4, 5, 6],
[ 8, 9, 10]])