前言
一些处理矩阵运算,图像处理算法,直接采用python实现可能速度稍微慢,效率不高,或者为了直接在python中调用其他C++第三方库。 图像,矩阵在python中通常表示为numpy.ndarray,因此如何在C++中解析numpy对象,numpy的数据如何传递到C++非常关键,解决了这些问题,就可以丝滑的在python numpy和C++中切换,互相调用。
开发、测试环境
windows 10, 64bit
Anaconda3, with python 3.7
Visual Studio 2017
pycharm
pybind11
C++ Numpy
image.png
image.png
image.png
image.png
demo1
1d numpy.ndarray
2d numpy.ndarray
3d numpy.ndarray
C++ numpy传递参数
C++代码
#include
#include
#include
namespace py = pybind11;
/*
1d矩阵相加
*/
py::array_t add_arrays_1d(py::array_t& input1, py::array_t& input2) {
// 获取input1, input2的信息
py::buffer_info buf1 = input1.request();
py::buffer_info buf2 = input2.request();
if (buf1.ndim !=1 || buf2.ndim !=1)
{
throw std::runtime_error("Number of dimensions must be one");
}
if (buf1.size !=buf2.size)
{
throw std::runtime_error("Input shape must match");
}
//申请空间
auto result = py::array_t(buf1.size);
py::buffer_info buf3 = result.request();
//获取numpy.ndarray 数据指针
double* ptr1 = (double*)buf1.ptr;
double* ptr2 = (double*)buf2.ptr;
double* ptr3 = (double*)buf3.ptr;
//指针访问numpy.ndarray
for (int i = 0; i < buf1.shape[0]; i++)
{
ptr3[i] = ptr1[i] + ptr2[i];
}
return result;
}
/*
2d矩阵相加
*/
py::array_t add_arrays_2d(py::array_t& input1, py::array_t& input2) {
py::buffer_info buf1 = input1.request();
py::buffer_info buf2 = input2.request();
if (buf1.ndim != 2 || buf2.ndim != 2)
{
throw std::runtime_error("numpy.ndarray dims must be 2!");
}
if ((buf1.shape[0] != buf2.shape[0])|| (buf1.shape[1] != buf2.shape[1]))
{
throw std::runtime_error("two array shape must be match!");
}
//申请内存
auto result = py::array_t(buf1.size);
//转换为2d矩阵
result.resize({buf1.shape[0],buf1.shape[1]});
py::buffer_info buf_result = result.request();
//指针访问读写 numpy.ndarray
double* ptr1 = (double*)buf1.ptr;
double* ptr2 = (double*)buf2.ptr;
double* ptr_result = (double*)buf_result.ptr;
for (int i = 0; i < buf1.shape[0]; i++)
{
for (int j = 0; j < buf1.shape[1]; j++)
{
auto value1 = ptr1[i*buf1.shape[1] + j];
auto value2 = ptr2[i*buf2.shape[1] + j];
ptr_result[i*buf_result.shape[1] + j] = value1 + value2;
}
}
return result;
}
//py::array_t add_arrays_3d(py::array_t& input1, py::array_t& input2) {
//
// py::buffer_info buf1 = input1.request();
// py::buffer_info buf2 = input2.request();
//
// if (buf1.ndim != 3 || buf2.ndim != 3)
// throw std::runtime_error("numpy array dim must is 3!");
//
// for (int i = 0; i < buf1.ndim; i++)
// {
// if (buf1.shape[i]!=buf2.shape[i])
// {
// throw std::runtime_error("inputs shape must match!");
// }
// }
//
// // 输出
// auto result = py::array_t(buf1.size);
// result.resize({ buf1.shape[0], buf1.shape[1], buf1.shape[2] });
// py::buffer_info buf_result = result.request();
//
// // 指针读写numpy数据
// double* ptr1 = (double*)buf1.ptr;
// double* ptr2 = (double*)buf2.ptr;
// double* ptr_result = (double*)buf_result.ptr;
//
// for (int i = 0; i < buf1.size; i++)
// {
// std::cout << ptr1[i] << std::endl;
// }
//
// /*for (int i = 0;