opencv 3.0 beta 创建新模块(可在 Python 中使用)



我已经在本地向OpenCV 3.0测试版(在本地contrib存储库中(添加了一个模块,该模块在C++中运行良好。现在我试图让它在 Python 中工作,但没有成功。

正如这里所建议的,我用CV_EXPORTS_W替换了我的CV_EXPORTS,并将宏CV_WRAP添加到我希望能够在 Python 中调用的类中的函数中(如此处所述(。

我还通过查看源代码发现,我必须在模块CMakeLists.txt中添加一些如下所示的WRAP python

set(the_description "Extended video processing module. Includes an object tracker")
set(OPENCV_MODULE_IS_PART_OF_WORLD OFF)
ocv_define_module(xvideo opencv_core opencv_imgproc opencv_highgui WRAP python)
target_link_libraries(opencv_xvideo)

但看起来我仍然缺少一些东西,因为我的类和方法在 Python 中不存在。例如,以下代码:

import numpy as np
import cv2
frameManager = cv2.FrameManager.create()

产生以下错误:

AttributeError: 'module' object has no attribute 'FrameManager'

作为补充信息,我发现我的类出现在生成的文件中(编译时(build/modules/python2/pyopencv_generated_include.h

...
#include "opencv2/xvideo/framemanager.hpp"
...

但不出现在其他pyopencv_generated_*.h文件中。

你有关于我在这里缺少什么的任何信息吗? 或者你知道如何使用新模块扩展OpenCV 3.0的指南吗?(没有找到(

好吧,看来我必须在这里尝试我自己的狗粮。

xvideo/

include/opencv2/xvideo.hpp:

#ifndef __OPENCV_xvideo_HPP__
#define __OPENCV_xvideo_HPP__
/** @defgroup xvideo Additional video processing algorithms
*/
#include "opencv2/core.hpp"
namespace cv {
namespace xvideo {
    struct CV_EXPORTS_W FrameManager
    {
        CV_WRAP void foo(InputArray inp, float v);
        CV_WRAP static Ptr<FrameManager> create();
    };
}
}

xvideo/src/framemanager.cpp:

#include "opencv2/xvideo.hpp"
namespace cv
{
namespace xvideo
{

    void FrameManager::foo(InputArray inp, float v) {}
    Ptr<FrameManager> FrameManager::create() { return makePtr<FrameManager>(); }
}
}

相同的CmakeLists.txt,你正在使用。

现在运行 cmake(-gui( ,看,那BUILD_opencv_xvideo=ON,配置,生成。

然后重建,不要忘记运行make install (或在VS中构建安装程序(

>>> help(cv2.xvideo)
Help on module cv2.xvideo in cv2:
NAME
    cv2.xvideo
FILE
    (built-in)
FUNCTIONS
    FrameManager_create(...)
        FrameManager_create() -> retval

>>> fm = cv2.xvideo.FrameManager_create()
>>> help(fm)
Help on xvideo_FrameManager object:
class xvideo_FrameManager(__builtin__.object)
 |  Methods defined here:
 |
 |  __repr__(...)
 |      x.__repr__() <==> repr(x)
 |
 |  foo(...)
 |      foo(inp, v) -> None
 |
 |  ----------------------------------------------------------------------
 |  Data and other attributes defined here:
 |
 |  __new__ = <built-in method __new__ of type object>
 |      T.__new__(S, ...) -> a new object with type S, a subtype of T

从上一个答案开始(谢谢@berak(,我将代码一点一点地转换为我的代码。据我所知,我至少可以说两件事:

不要使用对抽象纯类的引用:

myFunction(abstractType &myObject)转换为myFunction(Ptr<abstractType> myObject) Ptr是 OpenCV 智能指针的位置。

不要忘记帮助OpenCV通过引用传递的输出函数参数:

例如:myFunction(CV_OUT SomeType &output) .PS :还有CV_IN_OUT关键字。有关更多详细信息,请参阅此处。

我仍然遇到嵌套命名空间的问题:

我正在使用一些类型的函数参数 std::string .似乎在编译步骤中,为绑定生成的文件(pyopencv_generated_*.h(不正确(它们使用string而不是std::string(,在创建文件时产生错误cv2.soerror: ‘string’ was not declared in this scope。我通过使用类String而不是似乎是OpenCV一部分的std::string绕过了该错误。

但是由于我没有真正解决问题,现在我有同样的错误,但有一些std::vector<...>论点。不幸的是,我无法提供指向项目(私有(的位桶的链接,但如果有人知道出了什么问题,我制作了一个简单的示例代码,面对同样的错误。有示例代码:

xxxvideo/include/opencv2/xxxvideo.hpp

#ifndef __OPENCV_XXXVIDEO_HPP__
#define __OPENCV_XXXVIDEO_HPP__
/** @defgroup xxxvideo Additional video processing algorithms
*/
#include "opencv2/core.hpp"
#include <string>
#include <vector>
//#include "xxxvideo/framemanager_all.hpp"
namespace cv {
namespace xxxvideo {
class CV_EXPORTS_W DynamicState : public Algorithm
{
    public:
        virtual ~DynamicState(){};
        CV_WRAP virtual Mat toMatrix();
};
class CV_EXPORTS_W DynamicModel : public Algorithm
{
    public:
        virtual ~DynamicModel(){};
        CV_WRAP virtual std::vector< Ptr<DynamicState> > getAllStates();
};
}}
#endif

xxxvideo/src/dynamicmodelimpl.cpp

#include "opencv2/xxxvideo.hpp"
using namespace std;
using namespace cv;
using namespace cv::xxxvideo;
vector< Ptr<DynamicState> > DynamicModel::getAllStates()
{
    vector< Ptr<DynamicState> > states;
    return states;
}
Mat DynamicState::toMatrix()
{
    Mat m;
    return m;
}

xxxvideo/CMakeLists.txt

set(the_description "Exxxtended video processing module. Includes an object tracker")
set(OPENCV_MODULE_IS_PART_OF_WORLD OFF)
ocv_define_module(xxxvideo opencv_core opencv_imgproc opencv_highgui WRAP python)
target_link_libraries(opencv_xxxvideo)

并且有我得到的错误:

[ 98%] Generating pyopencv_generated_include.h, pyopencv_generated_funcs.h, pyopencv_generated_types.h, pyopencv_generated_type_reg.h, pyopencv_generated_ns_reg.h
Scanning dependencies of target opencv_python2
[ 98%] Building CXX object modules/python2/CMakeFiles/opencv_python2.dir/__/src2/cv2.cpp.o
In file included from /home/matthieu/libs/opencv/opencv-trunk/modules/python/src2/cv2.cpp:1217:0:
/home/matthieu/libs/opencv/opencv-trunk/build/modules/python2/pyopencv_generated_types.h: In function ‘PyObject* pyopencv_cv_xxxvideo_xxxvideo_DynamicModel_getAllStates(PyObject*, PyObject*, PyObject*)’:
/home/matthieu/libs/opencv/opencv-trunk/build/modules/python2/pyopencv_generated_types.h:15927:5: error: ‘vector_Ptr_DynamicState’ was not declared in this scope
     vector_Ptr_DynamicState retval;
     ^

如果您对问题有任何想法,欢迎帮助;)

##

## 编辑 : ##

所以我开始研究 Python 绑定是如何生成的(可以在这里找到解释的开头(。相关文件位于文件夹 modules/python/src2 中。我发现了两件事可能与我的问题有关。

首先,OpenCV 中使用的所有vector<...>类型似乎都在第 87 行和第 110 行之间的文件cv2.cpp中定义:

typedef std::vector<uchar> vector_uchar;
typedef std::vector<char> vector_char;
typedef std::vector<int> vector_int;
typedef std::vector<float> vector_float;
typedef std::vector<double> vector_double;
typedef std::vector<Point> vector_Point;
typedef std::vector<Point2f> vector_Point2f;
typedef std::vector<Vec2f> vector_Vec2f;
typedef std::vector<Vec3f> vector_Vec3f;
typedef std::vector<Vec4f> vector_Vec4f;
typedef std::vector<Vec6f> vector_Vec6f;
typedef std::vector<Vec4i> vector_Vec4i;
typedef std::vector<Rect> vector_Rect;
typedef std::vector<KeyPoint> vector_KeyPoint;
typedef std::vector<Mat> vector_Mat;
typedef std::vector<DMatch> vector_DMatch;
typedef std::vector<String> vector_String;
typedef std::vector<Scalar> vector_Scalar;
typedef std::vector<std::vector<char> > vector_vector_char;
typedef std::vector<std::vector<Point> > vector_vector_Point;
typedef std::vector<std::vector<Point2f> > vector_vector_Point2f;
typedef std::vector<std::vector<Point3f> > vector_vector_Point3f;
typedef std::vector<std::vector<DMatch> > vector_vector_DMatch;

其次,从第 204 行函数def parse_arg(self, arg_str, argno):的文件hdr_parser.py中的参数类型中删除std::命名空间:

arg_type = self.batch_replace(arg_type, [("std::", ""), ("cv::", ""), ("::", "_")])

我的部分解决方案:

研究这个问题,在我的错误中,我想出了在定义类 DynamicState 之后xxxvideo.hpp文件中添加一个 typedef 的想法:

typedef std::vector< cv::Ptr<DynamicState> >  vector_Ptr_DynamicState;
编译错误消失了,

但现在,我在python中import cv2时出现错误:

>>> import cv2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: /usr/local/opencv/opencv-trunk/lib/python2.7/dist-packages/cv2.so: undefined symbol: _ZTIN2cv8xxxvideo12DynamicStateE

同样,如果有人对我应该做什么有任何想法,或者如果你能把我的问题转达给可能的人,我将不胜感激。

##

## 编辑(再次(: ##

实际上,我的错误在又一轮cmake ..后消失了,makesudo make install。这似乎已经纠正了错误。

相关内容

  • 没有找到相关文章

最新更新