SWIG 擴展Opencv python調用C++


osx:10.12 g++ 7.1 swig 3.0.12 opencv 3.2.0

SWIG是Simplified Wrapper and Interface Generator的縮寫。是Python中調用C代碼的另一種方法。在這個方法中,開發人員必須編寫一個額外的接口文件來作為SWIG(終端工具)的入口

SWIG在官網上有很詳細的例子這里就只針對opencv進行講述

安裝SWIG

brew install swig

這里用一個小例子來先簡單介紹SWIG

//example.hpp
#ifndef example_hpp
#define example_hpp
#include <iostream>
#include <vector>
class Test{
public:
	Test(){
		for(int i=0;i<10;i++) v.push_back(i);
	}
	void see();
private:
	std::vector<int> v;
};
#endif
//example.cpp
#include "example.hpp"
#include <stdio.h>
using namespace std;
void Test::see(){
	for(int i=0;i<(this->v).size();i++) 
		printf("%d ",v[i]);
}

如何將這個類以及這個類的方法放在python里面調用呢

1.編寫轉換規則 example.i(接口文件)

%module example
%include "std_vector.i"
%{
	#include "example.hpp"
%}
%include "example.hpp"

第一行 %module后面的名字是被封裝的模塊名稱,Python通過這個名稱來加載程序。

第二行是文件所以依賴的頭文件,vector本是STL里面的,但是SWIG已經有對應的"std_vector.i"寫好了,所以可以直接%include "std_vector.i",如果在python里面需要用到vector的話,在轉換規則里面還要添加模版類型,具體參考SWIG的DOC http://www.swig.org/Doc1.3/Library.html

大括號里面所添加的內容,一般包含此文件需要的一些函數聲明和頭文件。

最后一行是聲明了要封裝的函數和變量,因為函數聲明寫在了頭文件里面,如果全部封裝的話可以直接%include 頭文件名

2.封裝代碼,生成中間文件

swig -python -c++ example.i

這樣會生成兩個文件

example.cxx,example.py

example.cxx :編譯c++時用

example.py:python import包時使用

3.使用distutils工具或命令編譯

"""
setup.py
"""
from distutils.core import setup,Extension
setup(name = "example", 
      version = "1.0", 
    ext_modules = [Extension("_example", ["example_wrap.cxx", 	"example.cpp"],
   extra_compile_args = ['-std=c++11'])],
   py_modules=['example'])

sudo python setup.py install

注意模塊名稱那里一定前面要加下划線

這會將生成的_example.so 和 example.py 送到python對應的package文件夾里

額外的參數和額外的庫都跟着需要更改

4.Python引用

In [1]: from example import *
In [2]: x = Test()
In [3]: x.see()
0 1 2 3 4 5 6 7 8 9 

注意的問題:

c++中聲明的方法必須實現

GCC版本要和Python的底層版本一樣

在編寫接口文件的時候,需要將依賴的頭文件都添加進來,而opencv里面的文件繁多,在Github上面有人已經寫好了opencv.i

opencv-swig

安裝方法:

沒什么安裝方法。。。下載文件直接將lib里面的文件復制到你Code的文件夾下面就好了。

使用方法在主頁上有介紹

需要注意的是在寫接口文件的時候,如果需要自己定義vector在python里面的接口,會出現redefinition的問題,因為作者寫的借口文件里面已經實現過了vector的接口,不需要寫,其他的STL類沒有試過,出現redefinition時估計也是一樣的問題。

作者沒有寫文檔,在調用接口的時候需要去查作者的test,比如opencv里面的

cv::Mat ,在封裝成python之后需要調用作者的module_name.Mat.from_array(img)轉換成cv::Mat

參考文檔:

http://blog.csdn.net/jiangpeng59/article/details/73554835

http://cering.github.io/2015/12/08/使用SWIG實現Python調用C-C-代碼/

https://github.com/renatoGarcia/opencv-swig

http://www.swig.org/tutorial.html

http://www.swig.org/Doc1.3/Library.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM