C++ 是一种编译型(compiled)语言,设计重点是性能、效率和使用灵活性,偏向于系统编程、嵌入式、资源受限的软件和系统。

Python是一种解释型(interpreted)语言,同样也支持不同的编程范式。Python 内置了常用数据结构(str, tuple, list, dict),简洁的语法、丰富的内置库(os,sys,urllib,...)和三方库(numpy, tf, torch ...),功能强大。最为重要的是和能够和多种服务(flask…)和tensorflow、pytorch等无缝联合,从而方便将你的算法开放出去。

一方面,我们需要编译型语言(C++)性能;一方面,也需要解释型语言(Python)的灵活。这时,pybind11 可以用作 C++ 和 Python 之间沟通的桥梁。

Pybind11 是一个轻量级只包含头文件的库,用于 Python 和 C++ 之间接口转换,可以为现有的 C++ 代码创建 Python 接口绑定。Pybind11 通过 C++ 编译时的自省来推断类型信息,来最大程度地减少传统拓展 Python 模块时繁杂的样板代码, 已经实现了 STL 数据结构、智能指针、类、函数重载、实例方法等到Python的转换,其中函数可以接收和返回自定义数据类型的值、指针或引用。

由于在Windows上和在Linux上使用会有较大不同,所以我这里将分为两个部分来说明问题,本文为上篇,具体说明Windows+VS实现

1、vs的最简单调用

新创建项目,做以下修改:

python中cv库可以用来分类吗 python的cv_python中cv库可以用来分类吗

 




python中cv库可以用来分类吗 python的cv_Python_02


 


python中cv库可以用来分类吗 python的cv_python中cv库可以用来分类吗_03


 


这几个都是标准配置【当然还有更简便方法】,正常生成


# include  "pch.h"
# include  <iostream >
# include  <pybind11 /pybind11.h >
namespace py  = pybind11;
PYBIND11_MODULE(example, m) {
    m.doc()  =  "pybind11 example module";
     // Add bindings here
    m.def( "foo", []() {
         return  "Hello, World!";
    });
}


 


其中:


The  PYBIND11_MODULE()  macro creates a function that will be called when an  import  statement is issued from within Python. The module name ( example ) is given as the first macro argument (it should not be in quotes). The second argument ( m ) defines a variable of type  py::module  which is the main interface for creating bindings. The method  module::def()  generates binding code that exposes the  add()  function to Python.

 


生成结果中,只有pyd是需要的.


python中cv库可以用来分类吗 python的cv_Python_04


 

 


当你的python调用和pyd的文件在同一个目录下面就可以进行调用。


 


python中cv库可以用来分类吗 python的cv_python_05


 

 


pyd是什么格式的文件:
1.PYD是一种PYTHON动态模块。
2.实质上还是dll文件,只是改了后缀为PYD。


 

python中cv库可以用来分类吗 python的cv_Python_06

这里特别需要注意,就是.pyd文件名和GOPyWarper这个函数名字一定要一样,否则报

python中cv库可以用来分类吗 python的cv_python_07

错误。

2、vs添加OpenCV的调用

配置中,需要添加OpeCV部分。分别是附加包含目录和附加依赖项。

python中cv库可以用来分类吗 python的cv_OpenCV_08

python中cv库可以用来分类吗 python的cv_Python_09

 

 



PYBIND11_MODULE(example, m) {


 


    m.doc() = "pybind11 example module";


 


    // Add bindings here


    m.def("foo", []() {


        Mat src = imread("e:/template/lena.jpg");


        Mat gray;


        cvtColor(src, gray, COLOR_BGR2GRAY);


        imshow("gray", gray);


        waitKey(0);//必须要设置,否则卡死


        return "Hello, OpenCV!";


    });


python中cv库可以用来分类吗 python的cv_Python_10


这种调用是没有问题的,关键的问题在于numpy数组和Mat的相互转换。只有这样,才能够将Mat和Python高质量融合。


 


python中cv库可以用来分类吗 python的cv_python_11


// python调用C++.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。        
        //        
#        include         "pch.h"        
#        include         <iostream        >        
#        include         <opencv2        /core.hpp        >        
#        include         <opencv2        /imgcodecs.hpp        >        
#        include         <opencv2        /imgproc.hpp        >        
#        include         <opencv2        /highgui.hpp        >        
#        include         <pybind11        /pybind11.h        >        
using         namespace cv;        
using         namespace std;        
namespace py         = pybind11;        
PYBIND11_MODULE(example, m) {        
    m.doc()         =         "pybind11 example module";        
            // Add bindings here        
    m.def(        "foo", [](string strPath) {        
        Mat src         = imread(strPath);        
        Mat gray;        
        cvtColor(src, gray, COLOR_BGR2GRAY);        
        imshow(        "gray", gray);        
        waitKey(        0);        //必须设置,否则卡死        
                return         "Hello, OpenCV!";        
    });        
}

 


3、图片Mat作为输入和list作为输出


对于实际项目而言来说,输入的是图片,输出的vector(numpy),这里就涉及到格式转换问题,目前找到解决方案。


src = cv2.imread( '', 1) 
var1 = GOPyWarper.test_rgb_to_gray(src)
cv2.imshow( 'gray',var1)


python中cv库可以用来分类吗 python的cv_python中cv库可以用来分类吗_12


 


python中cv库可以用来分类吗 python的cv_OpenCV_13

python中cv库可以用来分类吗 python的cv_OpenCV_14


 


给出了3通道和1通道的numpy和Mat的转换,基本上是够用的,其它转换可以在内部进行。


然后在接口中有进一步封装,这个都是非常好理解的。


python中cv库可以用来分类吗 python的cv_python中cv库可以用来分类吗_15


在输出这一块,有非常容易的方法,参考:这种方法虽然丑陋,但是有效。


py : :list test_pyramid_image(py : :array_t < unsigned  char > & input) {
     py::list out;

    for (int i = 0; i < 100; i++)


    {


        out.append<py::int_>(i);


    }


    return out;


python中cv库可以用来分类吗 python的cv_python中cv库可以用来分类吗_16


 


4、融合实现GOFindPip算法


python中cv库可以用来分类吗 python的cv_python中cv库可以用来分类吗_17


输入图片,输出圆心数组(x、y排列),实现功能。


python中cv库可以用来分类吗 python的cv_OpenCV_18


py : :list GO_FindPips(py : :array_t < unsigned  char > & input) {
     //输出结果
    py : :list out;
……


转换为release模式,能力有数量级的提升。


 


总的来看,在Windoes上的部署,由于VS提供了许多方便,所以比较流畅。