python 调用 c++dll, 包含类以及opencv Ma

2018-06-12  本文已影响0人  去大海边吹海风

前言

由于这个尝试花了一些时间,所以记录下来。由于我是尝试的很多理论地方不大懂,我把我尝试成功的部门记录下来,希望对大家有所帮助。

我的环境是windows10 + vs2015

创建 vs dll project

python所有不同的调用方式都需要先建一个dll project。

python 调用 c++普通函数

为了写文档,尝试了以下链接中的简单例子,可行。
https://blog.csdn.net/sloanqin/article/details/51505478

python 调用 struct

最开始尝试struct是以下链接中的例子,可行。
https://blog.csdn.net/iceboy314159/article/details/53192175

python 调用 class

pro.h 文件

#include <opencv2/opencv.hpp>

#ifndef _pro_header_2014_  
#define _pro_header_2014_  

#ifdef EXPORT_PRO_DLL  
#define PRO_API __declspec(dllexport)  
#else  
#define PRO_API __declspec(dllimport)  
#endif  

class Foo
{
    public:
        Foo(cv::Mat);
        void bar();
        int* foobar(cv::Mat);
    private:
        cv::Mat val;
};

extern "C"
{
    PRO_API Foo* Foo_new(int rows, int cols, unsigned char* imgdata);
    PRO_API void Foo_bar(Foo* foo); 
    PRO_API int* Foo_foobar(Foo* foo, int rows, int cols, unsigned char* imgdata);
}
#endif // !_pro_header_2014_  

pro.cpp 文件

#define EXPORT_PRO_DLL

#include "pro.h"
#include "string.h"
#include<iostream>

using namespace std;

Foo::Foo(cv::Mat n)
{
    val = n;
}
void Foo::bar()
{
    std::cout << "Value is " << val << std::endl;
}
int* Foo::foobar(cv::Mat n)
{
    int *data = new int[2];
    data[0] = 1;
    data[1] = 2;
    return data;
}

 
PRO_API Foo* Foo_new(int rows,int cols, unsigned char* imgdata) { 
    cv::Mat img(rows, cols, CV_8UC3, (void *)imgdata);
    return new Foo(img);
}
PRO_API void Foo_bar(Foo* foo) { foo->bar(); }
PRO_API int* Foo_foobar(Foo* foo, int rows, int cols, unsigned char* imgdata) {
    cv::Mat img(rows, cols, CV_8UC3, (void *)imgdata);
    return foo->foobar(img);
}

python code, 其中的图像读入,需要根据你自己的修改

from ctypes import *

class Foo(object):
    def __init__(self, img):
        lib.Foo_new.argtypes = [c_int,c_int,POINTER(c_ubyte)]
        lib.Foo_new.restype = c_void_p
        lib.Foo_bar.argtypes = [c_void_p]
        lib.Foo_bar.restype = c_void_p
        lib.Foo_foobar.argtypes = [c_void_p,c_int,c_int,POINTER(c_ubyte)]
        lib.Foo_foobar.restype = POINTER(c_int)
        (rows, cols) = (img.shape[0], img.shape[1])
        self.obj = lib.Foo_new(rows, cols,img.ctypes.data_as(POINTER(c_ubyte)))
    def bar(self):
        lib.Foo_bar(self.obj)

    def foobar(self, img):
        (rows, cols) = (img.shape[0], img.shape[1])
        return lib.Foo_foobar(self.obj, rows, cols,img.ctypes.data_as(POINTER(c_ubyte)))

if __name__ == '__main__':
    root_path = 'E:/tracking/data/Girl'
    imglist = scan_image(os.path.join(root_path, 'img'))
    for imgname in imglist:
        img = cv2.imread(os.path.join(root_path, 'img', imgname))
        f = Foo(img)
        f.bar()
        rect = f.foobar(img)
        print(rect[0],rect[1])

后记

参考文章

class 调用:
http://www.auctoris.co.uk/2017/04/29/calling-c-classes-from-python-with-ctypes/
Mat 处理方式:
https://stackoverflow.com/questions/19031836/get-background-model-from-backgroundsubtractormog2-in-python

上一篇 下一篇

猜你喜欢

热点阅读