Skip to content

Commit c527b3c

Browse files
Merge pull request opencv#19319 from TolyaTalamanov:at/introduce-gopaque-garray-for-python
[G-API] Introduce GOpaque and GArray for python * Introduce GOpaque and GArray for python * Fix ctor * Avoid code duplication by using macros * gapi: move Python-specific files to misc/python * Fix windows build Co-authored-by: Alexander Alekhin <alexander.a.alekhin@gmail.com>
1 parent 8fa0133 commit c527b3c

File tree

4 files changed

+213
-2
lines changed

4 files changed

+213
-2
lines changed
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
// This file is part of OpenCV project.
2+
// It is subject to the license terms in the LICENSE file found in the top-level directory
3+
// of this distribution and at http://opencv.org/license.html.
4+
//
5+
// Copyright (C) 2021 Intel Corporation
6+
7+
#ifndef OPENCV_GAPI_PYTHON_BRIDGE_HPP
8+
#define OPENCV_GAPI_PYTHON_BRIDGE_HPP
9+
10+
#include <opencv2/gapi.hpp>
11+
#include <opencv2/gapi/garg.hpp>
12+
#include <opencv2/gapi/gopaque.hpp>
13+
14+
#define ID(T, E) T
15+
#define ID_(T, E) ID(T, E),
16+
17+
#define WRAP_ARGS(T, E, G) \
18+
G(T, E)
19+
20+
#define SWITCH(type, LIST_G, HC) \
21+
switch(type) { \
22+
LIST_G(HC, HC) \
23+
default: \
24+
GAPI_Assert(false && "Unsupported type"); \
25+
}
26+
27+
#define GARRAY_TYPE_LIST_G(G, G2) \
28+
WRAP_ARGS(bool , cv::gapi::ArgType::CV_BOOL, G) \
29+
WRAP_ARGS(int , cv::gapi::ArgType::CV_INT, G) \
30+
WRAP_ARGS(double , cv::gapi::ArgType::CV_DOUBLE, G) \
31+
WRAP_ARGS(float , cv::gapi::ArgType::CV_FLOAT, G) \
32+
WRAP_ARGS(std::string , cv::gapi::ArgType::CV_STRING, G) \
33+
WRAP_ARGS(cv::Point , cv::gapi::ArgType::CV_POINT, G) \
34+
WRAP_ARGS(cv::Point2f , cv::gapi::ArgType::CV_POINT2F, G) \
35+
WRAP_ARGS(cv::Size , cv::gapi::ArgType::CV_SIZE, G) \
36+
WRAP_ARGS(cv::Rect , cv::gapi::ArgType::CV_RECT, G) \
37+
WRAP_ARGS(cv::Scalar , cv::gapi::ArgType::CV_SCALAR, G) \
38+
WRAP_ARGS(cv::Mat , cv::gapi::ArgType::CV_MAT, G) \
39+
WRAP_ARGS(cv::GMat , cv::gapi::ArgType::CV_GMAT, G2)
40+
41+
#define GOPAQUE_TYPE_LIST_G(G, G2) \
42+
WRAP_ARGS(bool , cv::gapi::ArgType::CV_BOOL, G) \
43+
WRAP_ARGS(int , cv::gapi::ArgType::CV_INT, G) \
44+
WRAP_ARGS(double , cv::gapi::ArgType::CV_DOUBLE, G) \
45+
WRAP_ARGS(float , cv::gapi::ArgType::CV_FLOAT, G) \
46+
WRAP_ARGS(std::string , cv::gapi::ArgType::CV_STRING, G) \
47+
WRAP_ARGS(cv::Point , cv::gapi::ArgType::CV_POINT, G) \
48+
WRAP_ARGS(cv::Point2f , cv::gapi::ArgType::CV_POINT2F, G) \
49+
WRAP_ARGS(cv::Size , cv::gapi::ArgType::CV_SIZE, G) \
50+
WRAP_ARGS(cv::Rect , cv::gapi::ArgType::CV_RECT, G2) \
51+
52+
namespace cv {
53+
namespace gapi {
54+
55+
// NB: cv.gapi.CV_BOOL in python
56+
enum ArgType {
57+
CV_BOOL,
58+
CV_INT,
59+
CV_DOUBLE,
60+
CV_FLOAT,
61+
CV_STRING,
62+
CV_POINT,
63+
CV_POINT2F,
64+
CV_SIZE,
65+
CV_RECT,
66+
CV_SCALAR,
67+
CV_MAT,
68+
CV_GMAT,
69+
};
70+
71+
} // namespace gapi
72+
73+
namespace detail {
74+
75+
template <template <typename> class Wrapper, typename T>
76+
struct WrapType { using type = Wrapper<T>; };
77+
78+
template <template <typename> class T, typename... Types>
79+
using MakeVariantType = cv::util::variant<typename WrapType<T, Types>::type...>;
80+
81+
template<typename T> struct ArgTypeTraits;
82+
83+
#define DEFINE_TYPE_TRAITS(T, E) \
84+
template <> \
85+
struct ArgTypeTraits<T> { \
86+
static constexpr const cv::gapi::ArgType type = E; \
87+
}; \
88+
89+
GARRAY_TYPE_LIST_G(DEFINE_TYPE_TRAITS, DEFINE_TYPE_TRAITS)
90+
91+
} // namespace detail
92+
93+
class GAPI_EXPORTS_W_SIMPLE GOpaqueT
94+
{
95+
public:
96+
using Storage = cv::detail::MakeVariantType<cv::GOpaque, GOPAQUE_TYPE_LIST_G(ID_, ID)>;
97+
98+
template<typename T>
99+
GOpaqueT(cv::GOpaque<T> arg) : m_type(cv::detail::ArgTypeTraits<T>::type), m_arg(arg) { };
100+
101+
GAPI_WRAP GOpaqueT(gapi::ArgType type) : m_type(type)
102+
{
103+
104+
#define HC(T, K) case K: \
105+
m_arg = cv::GOpaque<T>(); \
106+
break;
107+
108+
SWITCH(type, GOPAQUE_TYPE_LIST_G, HC)
109+
#undef HC
110+
}
111+
112+
cv::detail::GOpaqueU strip() {
113+
#define HC(T, K) case Storage:: index_of<cv::GOpaque<T>>(): \
114+
return cv::util::get<cv::GOpaque<T>>(m_arg).strip(); \
115+
116+
SWITCH(m_arg.index(), GOPAQUE_TYPE_LIST_G, HC)
117+
#undef HC
118+
119+
GAPI_Assert(false);
120+
}
121+
122+
GAPI_WRAP gapi::ArgType type() { return m_type; }
123+
124+
private:
125+
gapi::ArgType m_type;
126+
Storage m_arg;
127+
};
128+
129+
class GAPI_EXPORTS_W_SIMPLE GArrayT
130+
{
131+
public:
132+
using Storage = cv::detail::MakeVariantType<cv::GArray, GARRAY_TYPE_LIST_G(ID_, ID)>;
133+
134+
template<typename T>
135+
GArrayT(cv::GArray<T> arg) : m_type(cv::detail::ArgTypeTraits<T>::type), m_arg(arg) { };
136+
137+
GAPI_WRAP GArrayT(gapi::ArgType type) : m_type(type)
138+
{
139+
140+
#define HC(T, K) case K: \
141+
m_arg = cv::GArray<T>(); \
142+
break;
143+
144+
SWITCH(type, GARRAY_TYPE_LIST_G, HC)
145+
#undef HC
146+
}
147+
148+
cv::detail::GArrayU strip() {
149+
#define HC(T, K) case Storage:: index_of<cv::GArray<T>>(): \
150+
return cv::util::get<cv::GArray<T>>(m_arg).strip(); \
151+
152+
SWITCH(m_arg.index(), GARRAY_TYPE_LIST_G, HC)
153+
#undef HC
154+
155+
GAPI_Assert(false);
156+
}
157+
158+
GAPI_WRAP gapi::ArgType type() { return m_type; }
159+
160+
private:
161+
gapi::ArgType m_type;
162+
Storage m_arg;
163+
};
164+
165+
} // namespace cv
166+
167+
#endif // OPENCV_GAPI_PYTHON_BRIDGE_HPP
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/usr/bin/env python
2+
3+
import numpy as np
4+
import cv2 as cv
5+
import os
6+
7+
from tests_common import NewOpenCVTests
8+
9+
class gapi_types_test(NewOpenCVTests):
10+
11+
def test_garray_type(self):
12+
types = [cv.gapi.CV_BOOL , cv.gapi.CV_INT , cv.gapi.CV_DOUBLE , cv.gapi.CV_FLOAT,
13+
cv.gapi.CV_STRING, cv.gapi.CV_POINT , cv.gapi.CV_POINT2F, cv.gapi.CV_SIZE ,
14+
cv.gapi.CV_RECT , cv.gapi.CV_SCALAR, cv.gapi.CV_MAT , cv.gapi.CV_GMAT]
15+
16+
for t in types:
17+
g_array = cv.GArrayT(t)
18+
self.assertEqual(t, g_array.type())
19+
20+
21+
def test_gopaque_type(self):
22+
types = [cv.gapi.CV_BOOL , cv.gapi.CV_INT , cv.gapi.CV_DOUBLE , cv.gapi.CV_FLOAT,
23+
cv.gapi.CV_STRING, cv.gapi.CV_POINT , cv.gapi.CV_POINT2F, cv.gapi.CV_SIZE ,
24+
cv.gapi.CV_RECT]
25+
26+
for t in types:
27+
g_opaque = cv.GOpaqueT(t)
28+
self.assertEqual(t, g_opaque.type())
29+
30+
31+
if __name__ == '__main__':
32+
NewOpenCVTests.bootstrap()

modules/python/bindings/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ foreach(m ${OPENCV_PYTHON_MODULES})
2626
list(APPEND opencv_hdrs "${hdr}")
2727
endif()
2828
endforeach()
29+
30+
# both wrapping and C++ implementation
31+
file(GLOB hdr2 ${OPENCV_MODULE_${m}_LOCATION}/misc/python/python_*.hpp)
32+
list(APPEND opencv_hdrs ${hdr2})
33+
list(APPEND opencv_userdef_hdrs ${hdr2})
34+
2935
file(GLOB hdr ${OPENCV_MODULE_${m}_LOCATION}/misc/python/shadow*.hpp)
3036
list(APPEND opencv_hdrs ${hdr})
3137
file(GLOB userdef_hdrs ${OPENCV_MODULE_${m}_LOCATION}/misc/python/pyopencv*.hpp)

modules/python/src2/gen2.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1020,8 +1020,14 @@ def gen(self, srcfiles, output_path):
10201020
decls = self.parser.parse(hdr)
10211021
if len(decls) == 0:
10221022
continue
1023-
if hdr.find('opencv2/') >= 0: #Avoid including the shadow files
1024-
self.code_include.write( '#include "{0}"\n'.format(hdr[hdr.rindex('opencv2/'):]) )
1023+
1024+
if hdr.find('misc/python/shadow_') < 0: # Avoid including the "shadow_" files
1025+
if hdr.find('opencv2/') >= 0:
1026+
# put relative path
1027+
self.code_include.write('#include "{0}"\n'.format(hdr[hdr.rindex('opencv2/'):]))
1028+
else:
1029+
self.code_include.write('#include "{0}"\n'.format(hdr))
1030+
10251031
for decl in decls:
10261032
name = decl[0]
10271033
if name.startswith("struct") or name.startswith("class"):

0 commit comments

Comments
 (0)