Python 包装C++;使用Cython具有OpenCV参数的函数
我有一个我用C写的类++Python 包装C++;使用Cython具有OpenCV参数的函数,python,c++,opencv,cython,Python,C++,Opencv,Cython,我有一个我用C写的类++ #include "segmenter_interface.h" #include "video_marker.cpp" #include <opencv2/imgcodecs.hpp> #include <opencv2/videoio/videoio.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/opencv.hpp> #include &l
#include "segmenter_interface.h"
#include "video_marker.cpp"
#include <opencv2/imgcodecs.hpp>
#include <opencv2/videoio/videoio.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/opencv.hpp>
#include <vector>
class UserDivide : public SegmenterInterface{
public:
virtual void SegmentVideo(cv::VideoCapture *vc,
std::vector<Segment> *indices);
}
错误消息如下所示:
Error compiling Cython file:
------------------------------------------------------------
...
cdef UserDivide *thisptr # hold a C++ instance
def __cinit__(self):
self.thisptr = new UserDivide()
def __dealloc__(self):
del self.thisptr
def SegmentVideo(self, VideoCapture *vc, vector[Segment] *indices):
^
------------------------------------------------------------
pyuser_divide.pyx:22:27: Cannot convert Python object argument to type 'VideoCapture *'
Error compiling Cython file:
------------------------------------------------------------
...
cdef UserDivide *thisptr # hold a C++ instance
def __cinit__(self):
self.thisptr = new UserDivide()
def __dealloc__(self):
del self.thisptr
def SegmentVideo(self, VideoCapture *vc, vector[Segment] *indices):
^
------------------------------------------------------------
pyuser_divide.pyx:22:45: Cannot convert Python object argument to type 'vector[Segment] *'
不幸的是,这只是一个部分答案:我知道问题所在,但不知道解决办法 你的第二个问题很容易解决。问题在于它希望指向C++向量,但它得到了一个Python列表。Cython可以自动将列表转换为向量并返回,但在指针处会丢失
# put this at the of your file top, and remove
# cdef extern from "<vector>" namespace "std": (etc)
#
# Cython has automatically defined these!
from libcpp.vector cimport vector
# ... other code goes here ...
# accept a list
def SegmentVideo(self, VideoCapture *vc, list indices):
cdef vector[Segment] indices_vector = indices # autoconversion happens
output = self.thisptr.SegmentVideo(vc, &indices_vector)
# are you expecting the vector to be changed, and do you want to keep the changes?
# if so then do
indices[:] = indices_vector
# if you don't care about changes then don't bother
return output
#将此文件放在文件顶部,然后删除
#来自“命名空间”std的cdef外部程序(等)
#
#Cython已经自动定义了这些!
从libcpp.vector cimport vector
# ... 其他代码在这里。。。
#接受名单
def段视频(自拍、视频捕获*vc、列表索引):
cdef向量[段]索引_向量=索引#发生自动转换
输出=self.thisptr.SegmentVideo(vc和索引\U向量)
#您是否希望向量发生更改,是否希望保留更改?
#如果是这样,那就做吧
索引[:]=索引向量
#如果你不在乎改变,那就不要麻烦了
返回输出
您的第一个问题(无法将Python对象参数转换为类型“VideoCapture*”
)是我无法解决的问题。本质上,CV2模块生成Python对象(可能是围绕OpenCV中定义的C++指针的包装),并且没有明显的方法从那些Python对象生成C++指针——您必须确定它存储在哪里。
我不会完全重复的快速浏览表明VideoCapture python对象在我的系统上是32字节(空的python对象是16字节)。然而,在我看来,这两个额外的8字节空间的内容都不像指针
大多数OpenCV Python包装看起来是从C++代码中自生的(至少我可以说),这意味着它不太容易弄清楚它是如何包装的。一种可能有用的方法是尝试通过他们的代码生成器运行
UserDivide
,看看是否可以通过这种方式为其生成python绑定….您能提供Cython报告的确切错误消息吗?您是对的,我不认为有一个很好的方法来使用我上面定义的VideoCapture对象。在为一个好的解决方案旋转轮子之后,我决定包装我需要的东西,以便将视频捕获对象传递给我的UserDivide对象。也就是说,我包装VideoCapture,实现VideoCapture(std::string&filename)构造函数,然后将VideoCapture python类传递给UserDivide python类。所以现在我不使用opencv提供的任何包装。
Error compiling Cython file:
------------------------------------------------------------
...
cdef UserDivide *thisptr # hold a C++ instance
def __cinit__(self):
self.thisptr = new UserDivide()
def __dealloc__(self):
del self.thisptr
def SegmentVideo(self, VideoCapture *vc, vector[Segment] *indices):
^
------------------------------------------------------------
pyuser_divide.pyx:22:27: Cannot convert Python object argument to type 'VideoCapture *'
Error compiling Cython file:
------------------------------------------------------------
...
cdef UserDivide *thisptr # hold a C++ instance
def __cinit__(self):
self.thisptr = new UserDivide()
def __dealloc__(self):
del self.thisptr
def SegmentVideo(self, VideoCapture *vc, vector[Segment] *indices):
^
------------------------------------------------------------
pyuser_divide.pyx:22:45: Cannot convert Python object argument to type 'vector[Segment] *'
# put this at the of your file top, and remove
# cdef extern from "<vector>" namespace "std": (etc)
#
# Cython has automatically defined these!
from libcpp.vector cimport vector
# ... other code goes here ...
# accept a list
def SegmentVideo(self, VideoCapture *vc, list indices):
cdef vector[Segment] indices_vector = indices # autoconversion happens
output = self.thisptr.SegmentVideo(vc, &indices_vector)
# are you expecting the vector to be changed, and do you want to keep the changes?
# if so then do
indices[:] = indices_vector
# if you don't care about changes then don't bother
return output