linux下使用SWIG实现Python调用C++ sdk读取相机图片
最近在弄相机的项目,算法用python 在linux下使用SWIG实现Python调用C++ sdk读取相机图片,获取Mat图像,并转换成numpy。
另外,多说一句,海康之类的监控摄像头支持rtsp协议,opencv 可以打开rtps地址读取摄像头,所以如果只是读取图像,不需要sdk,直接opencv方便实用。
参考了很多网上的资料:
- http://www.cppblog.com/wanghaiguang/archive/2016/08/18/214201.html
- https://cering.github.io/2015/12/08/使用SWIG实现Python调用C-C-代码/
- http://note.qidong.name/2018/01/hello-swig-example/
- http://notes.yeshiwei.com/programming/swig_python.html
- https://www.cnblogs.com/as3asddd/p/7582425.html
SWIG
SWIG是Simplified Wrapper and Interface Generator的缩写。SWIG本质上是个代码生成器,为C/C++程序生成到其他语言的包装代码(wrapper code,为了生成这些包装代码,SWIG需要一个接口描述文件,描述将什么样的接口暴露给其他语言。SWIG可以直接接受”.h”头文件做为接口描述文件。
一个小例子
先写一个C++类,之后用python调用该类。
//c++源文件
//example.h
#include <iostream>
using namespace std;
class Example{
public:
void say_hello();
//example.cpp
#include "example.h"
void Example::say_hello()
{
printf("hello");
}
再写一个swig模块定义文件如下
%module example
%{
#include "example.h"
%}
%include "example.h"
swig -python -c++ example.i,生成example_wrap.cxx和python文件example.py。
之后利用example_wrap.cxx和example.cpp生成一个链接库,重命名为_example.so,之后利用example.py和_example.so就可以导入example的包了。
g++ -c -fPIC -I/usr/include/python3.5m example.cpp
g++ -c -fPIC -I/usr/include/python3.5m example_wrap.cxx
g++ -shared example.o example_wrap.o -o _example.so -lpython3.5m
使用opencv
在编写接口文件的时候,要将依赖的头文件都添加进来,而opencv里面的文件繁多,在Github上面有人已经写好了opencv.i
新的.i文件
%module example
%include <opencv.i>
%cv_instantiate_all_defaults
%{
#include "example.h"
using namespace std;
%}
%include "example.h"
生成example_wrap.cxx和python文件example.py
swig -I/home/user/opencv-swig/lib/ -I/usr/local/include/ -python -c++ camera_py.i
根据自己的目录改下路径,之后生成.so文件就可以了。需要注意,返回的img要通过np.asarray转换一下类型。
cam = example.camera_py()
img = cam.get_img()
cv2.imshow('frame',np.asarray(img))