美文网首页ocr
python调用c++ so库· pybind11(二)

python调用c++ so库· pybind11(二)

作者: 夕一啊 | 来源:发表于2019-12-19 20:19 被阅读0次

简单介绍看(一)

计算iou复杂例子

pybind主要是用在把python的array传给c++,变成c++可以处理的类型
这里计算交集并集用到了clipper库,
iou.cpp

#include "pybind11/pybind11.h"
#include "pybind11/numpy.h"
#include "pybind11/stl.h"
#include "pybind11/stl_bind.h"

#include "clipper/clipper.hpp"

namespace py = pybind11;
namespace cl = ClipperLib;


namespace iou{

    using Polygon = cl::Path; //其实是两层的vector,

    float paths_area(const ClipperLib::Paths &ps) {
        float area = 0;
        for (auto &&p: ps)
            area += cl::Area(p);
        return area;
    }

    // clipper 库计算iou
    float poly_iou(const Polygon &a, const Polygon &b) {
        cl::Clipper clpr;
        clpr.AddPath(a, cl::ptSubject, true);
        clpr.AddPath(b, cl::ptClip, true);

        cl::Paths inter, uni;
        clpr.Execute(cl::ctIntersection, inter, cl::pftEvenOdd);
        clpr.Execute(cl::ctUnion, uni, cl::pftEvenOdd);

        auto inter_area = paths_area(inter);
        auto uni_area = paths_area(uni);
        float tmp = 0.01;
        return std::abs(inter_area) / std::max(std::abs(uni_area), tmp);
    }

    //其实是两层的vector,所以直接push,把多边形的点都加进去
    Polygon get_poly(const float *data, size_t n){
        using cInt = cl::cInt;
        Polygon a{ {cInt(data[0]), cInt(data[1])}};
        std::vector<std::vector<cInt>> ret;
        for (size_t i = 2; i < n;) {
            a.emplace_back(cInt(data[i]), cInt(data[i+1]));
            i += 2;
        }
        return a;
    }
  
    // 接收python数据类型,转换为c++数据类型,用指针来访问数组
    float iou(
    py::array_t<float, py::array::c_style> poly_one,
    py::array_t<float, py::array::c_style> poly_two)
    {
        auto poly_one_c = poly_one.request();
        auto poly_two_c = poly_two.request();
        auto line_count = poly_one_c.shape[0];
        auto cont_coutn = poly_two_c.shape[0];

        auto ptr_one = static_cast<float *>(poly_one_c.ptr);
        auto ptr_two = static_cast<float *>(poly_two_c.ptr);
        auto a = get_poly(ptr_one, poly_one_c.shape[0]);
        auto b = get_poly(ptr_two, poly_two_c.shape[0]);

        return poly_iou(a, b);
    }
}


PYBIND11_MODULE(iou, m){
    m.def("iou_cpp", &iou::iou, " re-implementation pse algorithm(cpp)", py::arg("poly_one"), py::arg("poly_two"));
}

编译so

g++ -o iou.so -I include  -std=c++11 -O3 -I/opt/conda/include/python3.6m -I/opt/conda/include/python3.6m  -Wno-unused-result -Wsign-compare -march=nocona -mtune=haswell -ftree-vectorize -fPIC -fstack-protector-strong -O3 -ffunction-sections -pipe  -fdebug-prefix-map=/tmp/build/80754af9/python_1564510748219/work=/usr/local/src/conda/python-3.6.9 -fdebug-prefix-map=/opt/conda=/usr/local/src/conda-prefix -fuse-linker-plugin -ffat-lto-objects -flto-partition=none -flto -DNDEBUG -fwrapv -O3 -Wall -L/opt/conda/lib/python3.6/config-3.6m-x86_64-linux-gnu -L/opt/conda/lib -lpython3.6m -lpthread -ldl  -lutil -lrt -lm  -Xlinker -export-dynamic iou.cpp include/clipper/clipper.cpp --shared -f

对比python和刚写的c++库

import numpy as np
from iou import iou_cpp
from shapely.geometry import Polygon
import time

def cpp_iou():
    time0 = time.time()
    poly_one = np.array([10,10,30,10,30,30,20,30,10,30]).astype(np.float32)
    poly_two = np.array([20,20,40,20,40,40,20,40]).astype(np.float32)
    print("iou:", iou_cpp(poly_one, poly_two))
    print("cpp cost:%.5f ms"%((time.time() - time0) * 1000))

def py_iou():
    time0 = time.time()
    poly_one = np.array([[10,10],[30,10],[30,30],[10,30]]).astype(np.float32)
    poly_two = np.array([[20,20],[40,20],[40,40],[20,40]]).astype(np.float32)
    poly_one = Polygon(poly_one)
    poly_two = Polygon(poly_two)
    print("iou:", poly_one.intersection(poly_two).area / poly_one.union(poly_two).area)
    print("py  cost:%.5f ms"%((time.time() - time0) * 1000))


if __name__ == "__main__":

    print("\nfisrt time:")
    cpp_iou()
    py_iou()
    print("\nsecond time:")
    cpp_iou()
    py_iou()

结果,c++写的比python shapely.geometry 快很多

fisrt time:
iou: 0.1428571492433548
cpp cost:0.36979 ms
iou: 0.14285714285714285
py  cost:1.79982 ms

second time:
iou: 0.1428571492433548
cpp cost:0.14234 ms
iou: 0.14285714285714285
py  cost:0.78845 ms

相关文章

网友评论

    本文标题:python调用c++ so库· pybind11(二)

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