如何将 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::tuplepy::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]])