Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 75c472f

Browse files
committed
ch52
1 parent 3b13988 commit 75c472f

File tree

1 file changed

+84
-0
lines changed

1 file changed

+84
-0
lines changed
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
# Python C++ binding in OpenCV
2+
http://docs.opencv.org/3.2.0/da/d49/tutorial_py_bindings_basics.html
3+
4+
## OpenCV-Python绑定如何工作?
5+
6+
7+
### 学习目标:
8+
9+
* 如何生成OpenCV-Python绑定?
10+
* 如何将新的OpenCV模块扩展到Python?
11+
12+
### 如何生成OpenCV-Python绑定?
13+
14+
在OpenCV中,所有算法都用C ++实现。但是这些算法可以从Python,Java等不同的语言使用。这可以通过绑定生成器来实现。这些生成器在C ++和Python之间创建了一个桥梁,使用户能够从Python调用C ++函数。要了解背景中发生的情况,需要熟悉Python / C API。官方Python文档[1]可以找到一个将C ++函数扩展为Python的简单示例。因此,通过手动编写其包装函数将OpenCV中的所有功能扩展到Python是一项耗时的任务。因此,OpenCV以更智能的方式实现。OpenCV使用位于modules / python / src2中的Python脚本从C ++头自动生成这些包装函数。我们将研究他们做什么。
15+
16+
首先,modules / python / CMakeFiles.txt是一个CMake脚本,它将模块扩展到Python。它将自动检查所有模块的扩展名并抓取其头文件。这些头文件包含该特定模块的所有类,函数,常量等的列表。
17+
18+
其次,这些头文件传递给Python脚本modules / python / src2 / gen2.py。这是Python绑定生成器脚本。它调用另一个Python脚本modules / python / src2 / hdr_parser.py。这是头解析器脚本。这个头文件解析器将完整的头文件分成小的Python列表。所以这些列表包含有关特定函数,类等的所有细节。例如,一个函数将被解析以获取包含函数名,返回类型,输入参数,参数类型等的列表。最终列表包含所有函数的详细信息,结构体,类别等。
19+
20+
但是头解析器不解析头文件中的所有函数/类。开发人员必须指定哪些函数应该导出到Python。为此,有一些宏添加到这些声明的开始,使头解析器能够识别要解析的函数。这些宏由编程特定功能的开发人员添加。简而言之,开发者决定哪些功能应该扩展到Python,哪些不是。这些宏的细节将在下一个会议中给出。
21+
22+
所以头解析器返回一个最后一个解析函数列表。我们的生成器脚本(gen2.py)将为头解析器解析的所有函数/ classes / enums / struct创建包装函数(您可以在build / modules / python /文件夹中编译时找到这些头文件作为pyopencv_generated _ * .h文件)。但是可能会有一些基本的OpenCV数据类型,如Mat,Vec4i,Size。他们需要手动扩展。例如,一个Mat类型应该扩展到Numpy数组,Size应该被扩展为一个两个整数的元组等等。类似地,可能有一些复杂的结构体/类/函数等需要手动扩展。所有这些手动包装器功能都放在modules / python / src2 / cv2.cpp中。
23+
24+
所以现在只剩下的是编译这些包装文件,这给我们提供了cv2模块。所以当你调用一个函数的时候,你可以用Python中的res = equalizeHist(img1,img2)来传递两个numpy数组,你会发现另外一个numpy数组作为输出。所以这些numpy数组被转换为cv :: Mat,然后调用C ++中的equalizeHist()函数。最终的结果,res将被转换成一个Numpy数组。所以简而言之,几乎所有的操作都是用C ++完成的,这给了我们几乎与C ++相同的速度。
25+
26+
所以这是OpenCV-Python绑定生成的基本版本。
27+
28+
如何将新模块扩展到Python?
29+
30+
头文件解析器基于添加到函数声明中的一些包装器宏解析头文件。枚举常数不需要任何包装宏。它们被自动包装。但是剩下的函数,类等都需要包装宏。
31+
32+
使用CV_EXPORTS_W宏扩展函数。一个例子如下所示。
33+
```C++
34+
CV_EXPORTS_W void equalizeHist(InputArray src,OutputArray dst);
35+
```
36+
标题解析器可以了解InputArray,OutputArray等关键字的输入和输出参数。但有时候,我们可能需要对输入和输出进行硬编码。为此,使用像CV_OUT,CV_IN_OUT等宏。
37+
```
38+
CV_EXPORTS_W void minEnclosingCircle(InputArray points,
39+
CV_OUT Point2f&center,CV_OUT float&radius);
40+
```
41+
对于大班,也使用CV_EXPORTS_W。要扩展类方法,使用CV_WRAP。类似地,CV_PROP用于类字段。
42+
```
43+
class CV_EXPORTS_W CLAHE : public Algorithm
44+
{
45+
public:
46+
CV_WRAP virtual void apply(InputArray src, OutputArray dst) = 0;
47+
CV_WRAP virtual void setClipLimit(double clipLimit) = 0;
48+
CV_WRAP virtual double getClipLimit() const = 0;
49+
}
50+
```
51+
可以使用CV_EXPORTS_AS扩展重载功能。但是我们需要传递一个新名称,以便每个函数都将被Python中的该名称调用。以下为积分函数。有三个功能可用,所以每个功能都用Python中的后缀命名。类似地,CV_WRAP_AS可用于包装重载方法。
52+
```
53+
CV_EXPORTS_W void integral( InputArray src, OutputArray sum, int sdepth = -1 );
54+
CV_EXPORTS_AS(integral2) void integral( InputArray src, OutputArray sum,
55+
OutputArray sqsum, int sdepth = -1, int sqdepth = -1 );
56+
CV_EXPORTS_AS(integral3) void integral( InputArray src, OutputArray sum,
57+
OutputArray sqsum, OutputArray tilted,
58+
int sdepth = -1, int sqdepth = -1 );
59+
```
60+
使用CV_EXPORTS_W_SIMPLE扩展小类/结构体。这些结构体通过值传递给C ++函数。示例是KeyPoint,Match等。它们的方法由CV_WRAP扩展,字段由CV_PROP_RW扩展。
61+
```
62+
class CV_EXPORTS_W_SIMPLE DMatch
63+
{
64+
public:
65+
CV_WRAP DMatch();
66+
CV_WRAP DMatch(int _queryIdx, int _trainIdx, float _distance);
67+
CV_WRAP DMatch(int _queryIdx, int _trainIdx, int _imgIdx, float _distance);
68+
CV_PROP_RW int queryIdx; // query descriptor index
69+
CV_PROP_RW int trainIdx; // train descriptor index
70+
CV_PROP_RW int imgIdx; // train image index
71+
CV_PROP_RW float distance;
72+
};
73+
```
74+
可以使用CV_EXPORTS_W_MAP导出一些其他小类/结构体,将其导出到Python本机字典。Moments()是一个例子。
75+
```
76+
class CV_EXPORTS_W_MAP Moments
77+
{
78+
public:
79+
CV_PROP_RW double m00, m10, m01, m20, m11, m02, m30, m21, m12, m03;
80+
CV_PROP_RW double mu20, mu11, mu02, mu30, mu21, mu12, mu03;
81+
CV_PROP_RW double nu20, nu11, nu02, nu30, nu21, nu12, nu03;
82+
};
83+
```
84+
所以这些是OpenCV中可用的主要扩展宏。通常,开发人员必须将适当的宏放在适当的位置。休息由生成器脚本完成。有时,发生器脚本可能不能创建包装器的特殊情况。这样的功能需要手动处理,为此您可以编写自己的pyopencv _ *。hpp扩展头文件,并将它们放入模块的misc / python子目录中。但大多数情况下,根据OpenCV编码指南编写的代码将被生成器脚本自动包装。

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /