python 通过pybind11向C++ dll 传递数组 图像

传递python中的List

pybind11 很贴心地帮你把 vector<T> 跟 python 的 list 做好了转换,你只需要 #include <pybind11/stl.h> 即可 [1]

C++端代码


#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <vector>
using std::vector;

namespace py = pybind11;



vector<float> ListMul(vector<float>& in_list, float coef) {
	vector<float> ret_vec;
	ret_vec.clear();
	ret_vec.reserve(in_list.size()); // Requests that the vector capacity be at least enough to contain n elements.
	for (size_t i = 0; i < in_list.size(); ++i) {
		int v = in_list[i];
		ret_vec.push_back(coef * v);
	}
	return ret_vec;
}


PYBIND11_MODULE(example, m) {
	m.doc() = "pass and return a list";
	m.def("ListMul", &ListMul, "example function");
}

python端调用

import example

print(example.ListMul([1.0, 2, 3, 4, 5, 6], 5))

python端的数据类型有时候不是那么严格,会进行自动转换,但是python float到c的int会出错,

类似地还有map<Tk, Tv>在 python 里对应的就是 Dict[Tk, Tv] [1]。

传递Numpy 数组

两个数组相加的案例 [2]

C++端代码

#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>


namespace py = pybind11;



py::array_t<double> add_arrays(py::array_t<double> input1, py::array_t<double> input2) {
	// read input arrays buffer_info
	py::buffer_info buf1 = input1.request(), buf2 = input2.request();

	if (buf1.size != buf2.size)
		throw std::runtime_error("Input shapes must match");

	// allocate the output buffer
	py::array_t<double> result = py::array_t<double>(buf1.size);

	py::buffer_info buf3 = result.request(); // acquire buffer info

	double *ptr1 = (double *)buf1.ptr, *ptr2 = (double *)buf2.ptr, *ptr3 = (double *)buf3.ptr;
	size_t high = buf1.shape[0];
	size_t width = buf1.shape[1];

	// Add both arrays
	for (size_t idy = 0; idy < high; idy++)
	{
		for (size_t idx = 0; idx < width; idx++)
		{
			int curIdx = idy*width + idx;
			ptr3[curIdx] = ptr1[curIdx] + ptr2[curIdx];

		}
	}

	/* Reshape result to have same shape as input */
	result.resize({ high, width });

	return result;
}

PYBIND11_MODULE(example, m) {
	m.doc() = "Add two vectors using pybind11"; // optional module docstring
	m.def("add_arrays", &add_arrays, "Add two NumPy arrays");
}

python端调用

import numpy as np
import example

a = np.ones((10,3))
b = np.ones((10,3)) * 3
c = example.add_arrays(a, b)
print(c)

These numpy array arguments can either be generic py:array or typed py:array_t<double>. The properties of the numpy array can be obtained by calling its request method. This returns a struct of the following form [3]:

struct buffer_info {
    void *ptr;
    size_t itemsize;
    std::string format;
    int ndim;
    std::vector<size_t> shape;
    std::vector<size_t> strides;
};

python传递图像到c++ dll

根据上面的案例,很容易写出C++端代码



#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>


#include <iostream>
using namespace std;

namespace py = pybind11;

#include <io.h>  
#include <fcntl.h>  
// display console
void OpenConsole()
{
	// create a console
	AllocConsole();

	// 
	FILE* stream;
	freopen_s(&stream, "CON", "r", stdin); //
	freopen_s(&stream, "CON", "w", stdout); //

	SetConsoleTitleA("Information output"); //

	HANDLE _handleOutput;
	_handleOutput = GetStdHandle(STD_OUTPUT_HANDLE);

	// FreeConsole();
}


void GetImage(py::array_t<char> input1)
{
	py::buffer_info buf1 = input1.request();
    OpenConsole();
	printf("dim:%d \n", buf1.ndim);

	for (int cnt = 0; cnt < buf1.ndim; cnt++)
	{
		printf("dim size %d : %d\n", cnt, buf1.shape[cnt]);
	}
	unsigned char *ptr1 = (unsigned char *)buf1.ptr;
	printf("image data: %d %d %d %d %d %d\n", ptr1[0], ptr1[1], ptr1[2], ptr1[3], ptr1[4], ptr1[5]);
}

PYBIND11_MODULE(example, m) {
	m.doc() = "Get NumPy arrays"; // optional module docstring

	m.def("GetImage", &GetImage, "Get NumPy arrays");
}

python端代码

import numpy as np
import example
from PIL import Image #PIL pakage name is Pillow 


 
im = Image.open('leopard-2.png')

in_data = np.asarray(im, dtype=np.uint8)
in_data = np.rollaxis(in_data,2,0)

print(type(in_data))

example.GetImage(in_data)

 

参考

[1] pybind11 入門玩樂筆記(二) – Dboy Liao – Medium

[2] http://christianjaques.ch/pybind-is-great/

[3] http://people.duke.edu/~ccc14/cspy/18G_C++_Python_pybind11.html

这里面提供了很多丰富的案例

https://pybind11.readthedocs.io/en/stable/advanced/pycpp/numpy.html?highlight=numpy#arrays

https://docs.python.org/3/c-api/buffer.html

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Luchang-Li

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值