美文网首页C++学习opencv for Java图像处理
pybind11—函数,返回值,数据转换

pybind11—函数,返回值,数据转换

作者: 侠之大者_7d3f | 来源:发表于2019-02-13 18:04 被阅读3次

    前言


    类型

    返回自定义类型数据(结构体/类)

    定义一个C++结构体,表示自定义的类型。

    struct MyData
    {
        int x;
        int y;
        int w;
        int h;
    };
    
    

    接口函数
    输入:废弃(无用处)
    返回:MyData类型指针

    /*
    返回自定义类型数据 MyData
    */
    MyData* get_data2(int length) {
        MyData* data = new MyData();
        
        data->x = 10;
        data->y = 20;
        data->w = 30;
        data->h = 30;
    
        return data;
    
    }
    

    python扩展代码
    注意:返回值策略,返回一个引用

    image.png image.png image.png
    image.png
    PYBIND11_MODULE(demo6, m) {
    
        m.doc() = "Simple demo";
    
        py::class_<MyData>(m, "MyData")
            .def_readwrite("x", &MyData::x)
            .def_readwrite("y", &MyData::y)
            .def_readwrite("w", &MyData::w)
            .def_readwrite("h", &MyData::h);
    
        m.def("get_data2", &get_data2, py::return_value_policy::reference);
    
    }
    

    测试结果

    image.png

    返回 python list 类型

    py::list

    接口函数

    /*
    返回python list
    */
    py::list get_data3(int len) {
        py::list data;
        for (int i = 0; i < len; i++)
        {
            data.append<int>(255);
        }
    
        return data;
    }
    
    

    python扩展代码

    PYBIND11_MODULE(demo6, m) {
      m.def("get_data3", &get_data3, py::return_value_policy::reference);
    }
    

    测试结果

    image.png

    返回python tuple类型

    py::tuple

    接口函数

    /*
    返回python tuple
    */
    py::tuple get_data4(int len) {
        py::tuple data(len);
        for (int i = 0; i < len; i++)
        {
            data[i] = 128;
        }
    
        return data;
    
    }
    
    

    python扩展代码

    PYBIND11_MODULE(demo6, m) {
      m.def("get_data4", &get_data4, py::return_value_policy::reference);
    }
    

    测试结果

    image.png

    矩阵操作——返回Eigen::Matrix类型

    Eigen是一个矩阵线性代数运算库,封装了矩阵类型,包含许多矩阵计算方法。Eigen是header-only的,不需要编译,只需要包含路径即可。

    image.png

    visaul studio配置

    image.png

    C++ Eigen::Matrix 类型在 python中对应 numpy.ndarray类型。

    首先,需要包含头文件
    #include<pybind11/eigen.h>
    #include<Eigen/Dense>

    接口函数

    /*
    https://blog.csdn.net/j_d_c/article/details/78903393
    返回 Eigen::Matrix类型, 在python中表示为numpy.ndarray
    */
    Eigen::Matrix<unsigned char, 32, 32> get_matrix_eigen() {
    
        Eigen::Matrix<unsigned char, 32, 32> mat;
        for (int i = 0; i < 32; i++)
        {
            for (int j = 0; j < 32; j++)
            {
                //索引元素
                mat(i,j) = 64;
            }
        }
    
        return mat;
    
    }
    
    
    /*
    计算矩阵相加
    Eigen::Matrix3f
    */
    Eigen::Matrix3f calc_mat_add(Eigen::Matrix3f a, Eigen::Matrix3f b) {
        return a + b;
    }
    
    /*
    创建3x3矩阵
    输入: list,  size=9
    返回:Eigen::Matrix3f,  python 中numpy.ndarray
    */
    Eigen::Matrix3f create_mat_3x3(py::list in) {
        assert(in.size() == 9);
        Eigen::Matrix3f mat;
        int count = 0;
        for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                mat(i, j) = py::cast<float>(in[count]);
                count++;
    
            }
        }
    
        return mat;
    
    }
    

    python扩展代码

    
    PYBIND11_MODULE(demo6, m) {
    
        m.def("get_matrix_eigen", &get_matrix_eigen, py::return_value_policy::reference);
        m.def("calc_mat_add", &calc_mat_add, py::return_value_policy::reference);
        m.def("create_mat_3x3", &create_mat_3x3, py::return_value_policy::reference);
    
    }
    

    python测试代码

    func6 = demo6.get_matrix_eigen()
    print(func6)
    
    func7 = demo6.calc_mat_add(np.array([[1, 2, 3],
                                         [3, 2, 1],
                                         [4, 5, 6]]),
                               np.array([[3, 3, 1],
                                         [6, 4, 6],
                                         [7, 7, 9]]))
    
    print(func7)
    
    func8 = demo6.create_mat_3x3([1, 2, 3, 4, 5, 6, 7, 8, 9])
    print(func8)
    
    image.png image.png image.png

    完整工程

    C++

    #include<iostream>
    #include<pybind11/pybind11.h>
    #include<pybind11/complex.h>
    #include<pybind11/eigen.h>
    #include<Eigen/Dense>
    
    
    /*
    file:///D:/pybind11-master/docs/.build/html/advanced/functions.html
    */
    
    namespace py = pybind11;
    
    
    struct MyData
    {
        int x;
        int y;
        int w;
        int h;
    };
    
    unsigned char* get_data(int length) {
        unsigned char* data = new unsigned char[length];
        for (int i = 0; i < length; i++)
        {
            data[i] = 255;
        }
    
        return data;
    }
    
    /*
    返回自定义类型数据 MyData
    */
    MyData* get_data2(int length) {
        MyData* data = new MyData();
        
        data->x = 10;
        data->y = 20;
        data->w = 30;
        data->h = 30;
    
        return data;
    
    }
    
    /*
    返回python list
    */
    py::list get_data3(int len) {
        py::list data;
        for (int i = 0; i < len; i++)
        {
            data.append<int>(255);
        }
    
        return data;
    }
    
    /*
    返回python tuple
    */
    py::tuple get_data4(int len) {
        py::tuple data(len);
        for (int i = 0; i < len; i++)
        {
            data[i] = 128;
        }
    
        return data;
    
    }
    
    
    /*
    返回 python complex复数
    */
    std::complex<float> get_complex() {
        py::list data;
        std::complex<float> item(1, 2);
        return item;
    
    }
    
    /*
    https://blog.csdn.net/j_d_c/article/details/78903393
    返回 Eigen::Matrix类型, 在python中表示为numpy.ndarray
    */
    Eigen::Matrix<unsigned char, 32, 32> get_matrix_eigen() {
    
        Eigen::Matrix<unsigned char, 32, 32> mat;
        for (int i = 0; i < 32; i++)
        {
            for (int j = 0; j < 32; j++)
            {
                //索引元素
                mat(i,j) = 64;
            }
        }
    
        return mat;
    
    }
    
    
    /*
    计算矩阵相加
    Eigen::Matrix3f
    */
    Eigen::Matrix3f calc_mat_add(Eigen::Matrix3f a, Eigen::Matrix3f b) {
        return a + b;
    }
    
    /*
    创建3x3矩阵
    输入: list,  size=9
    返回:Eigen::Matrix3f,  python 中numpy.ndarray
    */
    Eigen::Matrix3f create_mat_3x3(py::list in) {
        assert(in.size() == 9);
        Eigen::Matrix3f mat;
        int count = 0;
        for (int i = 0; i < 3; i++)
        {
            for (int j = 0; j < 3; j++)
            {
                mat(i, j) = py::cast<float>(in[count]);
                count++;
    
            }
        }
    
        return mat;
    
    }
    
    
    
    /*
    https://blog.csdn.net/u013701860/article/details/86313781
    */
    
    PYBIND11_MODULE(demo6, m) {
    
        m.doc() = "Simple demo";
    
        py::class_<MyData>(m, "MyData")
            .def_readwrite("x", &MyData::x)
            .def_readwrite("y", &MyData::y)
            .def_readwrite("w", &MyData::w)
            .def_readwrite("h", &MyData::h);
    
        m.def("get_data", &get_data, py::return_value_policy::reference);
        m.def("get_data2", &get_data2, py::return_value_policy::reference);
        m.def("get_data3", &get_data3, py::return_value_policy::reference);
        m.def("get_data4", &get_data4, py::return_value_policy::reference);
        m.def("get_complex", &get_complex, py::return_value_policy::reference);
        m.def("get_matrix_eigen", &get_matrix_eigen, py::return_value_policy::reference);
        m.def("calc_mat_add", &calc_mat_add, py::return_value_policy::reference);
        m.def("create_mat_3x3", &create_mat_3x3, py::return_value_policy::reference);
    
    }
    
    

    python

    import demo6.demo6 as demo6
    import numpy as np
    
    
    func1 = demo6.get_data(10)
    print(func1)
    help(demo6)
    
    func2 = demo6.get_data2(10)
    print(func2)
    
    func3 = demo6.get_data3(20)
    print(func3)
    
    func4 = demo6.get_data4(10)
    print(func4)
    
    func5 = demo6.get_complex()
    print(func5)
    
    func6 = demo6.get_matrix_eigen()
    print(func6)
    
    func7 = demo6.calc_mat_add(np.array([[1, 2, 3],
                                         [3, 2, 1],
                                         [4, 5, 6]]),
                               np.array([[3, 3, 1],
                                         [6, 4, 6],
                                         [7, 7, 9]]))
    
    print(func7)
    
    func8 = demo6.create_mat_3x3([1, 2, 3, 4, 5, 6, 7, 8, 9])
    print(func8)
    
    

    相关文章

      网友评论

        本文标题:pybind11—函数,返回值,数据转换

        本文链接:https://www.haomeiwen.com/subject/iypdeqtx.html