Aluode/PerceptionLabPortable
0
1__all__ = ['op', 'kernel']
2
3import sys
4import cv2 as cv
5
6# NB: Register function in specific module
7def register(mname):
8 def parameterized(func):
9 sys.modules[mname].__dict__[func.__name__] = func
10 return func
11 return parameterized
12
13
14@register('cv2.gapi')
15def networks(*args):
16 return cv.gapi_GNetPackage(list(map(cv.detail.strip, args)))
17
18
19@register('cv2.gapi')
20def compile_args(*args):
21 return list(map(cv.GCompileArg, args))
22
23
24@register('cv2')
25def GIn(*args):
26 return [*args]
27
28
29@register('cv2')
30def GOut(*args):
31 return [*args]
32
33
34@register('cv2')
35def gin(*args):
36 return [*args]
37
38
39@register('cv2.gapi')
40def descr_of(*args):
41 return [*args]
42
43
44@register('cv2')
45class GOpaque():
46 # NB: Inheritance from c++ class cause segfault.
47 # So just aggregate cv.GOpaqueT instead of inheritance
48 def __new__(cls, argtype):
49 return cv.GOpaqueT(argtype)
50
51 class Bool():
52 def __new__(self):
53 return cv.GOpaqueT(cv.gapi.CV_BOOL)
54
55 class Int():
56 def __new__(self):
57 return cv.GOpaqueT(cv.gapi.CV_INT)
58
59 class Int64():
60 def __new__(self):
61 return cv.GOpaqueT(cv.gapi.CV_INT64)
62
63 class UInt64():
64 def __new__(self):
65 return cv.GOpaqueT(cv.gapi.CV_UINT64)
66
67 class Double():
68 def __new__(self):
69 return cv.GOpaqueT(cv.gapi.CV_DOUBLE)
70
71 class Float():
72 def __new__(self):
73 return cv.GOpaqueT(cv.gapi.CV_FLOAT)
74
75 class String():
76 def __new__(self):
77 return cv.GOpaqueT(cv.gapi.CV_STRING)
78
79 class Point():
80 def __new__(self):
81 return cv.GOpaqueT(cv.gapi.CV_POINT)
82
83 class Point2f():
84 def __new__(self):
85 return cv.GOpaqueT(cv.gapi.CV_POINT2F)
86
87 class Point3f():
88 def __new__(self):
89 return cv.GOpaqueT(cv.gapi.CV_POINT3F)
90
91 class Size():
92 def __new__(self):
93 return cv.GOpaqueT(cv.gapi.CV_SIZE)
94
95 class Rect():
96 def __new__(self):
97 return cv.GOpaqueT(cv.gapi.CV_RECT)
98
99 class Prim():
100 def __new__(self):
101 return cv.GOpaqueT(cv.gapi.CV_DRAW_PRIM)
102
103 class Any():
104 def __new__(self):
105 return cv.GOpaqueT(cv.gapi.CV_ANY)
106
107@register('cv2')
108class GArray():
109 # NB: Inheritance from c++ class cause segfault.
110 # So just aggregate cv.GArrayT instead of inheritance
111 def __new__(cls, argtype):
112 return cv.GArrayT(argtype)
113
114 class Bool():
115 def __new__(self):
116 return cv.GArrayT(cv.gapi.CV_BOOL)
117
118 class Int():
119 def __new__(self):
120 return cv.GArrayT(cv.gapi.CV_INT)
121
122 class Int64():
123 def __new__(self):
124 return cv.GArrayT(cv.gapi.CV_INT64)
125
126 class UInt64():
127 def __new__(self):
128 return cv.GArrayT(cv.gapi.CV_UINT64)
129
130 class Double():
131 def __new__(self):
132 return cv.GArrayT(cv.gapi.CV_DOUBLE)
133
134 class Float():
135 def __new__(self):
136 return cv.GArrayT(cv.gapi.CV_FLOAT)
137
138 class String():
139 def __new__(self):
140 return cv.GArrayT(cv.gapi.CV_STRING)
141
142 class Point():
143 def __new__(self):
144 return cv.GArrayT(cv.gapi.CV_POINT)
145
146 class Point2f():
147 def __new__(self):
148 return cv.GArrayT(cv.gapi.CV_POINT2F)
149
150 class Point3f():
151 def __new__(self):
152 return cv.GArrayT(cv.gapi.CV_POINT3F)
153
154 class Size():
155 def __new__(self):
156 return cv.GArrayT(cv.gapi.CV_SIZE)
157
158 class Rect():
159 def __new__(self):
160 return cv.GArrayT(cv.gapi.CV_RECT)
161
162 class Scalar():
163 def __new__(self):
164 return cv.GArrayT(cv.gapi.CV_SCALAR)
165
166 class Mat():
167 def __new__(self):
168 return cv.GArrayT(cv.gapi.CV_MAT)
169
170 class GMat():
171 def __new__(self):
172 return cv.GArrayT(cv.gapi.CV_GMAT)
173
174 class Prim():
175 def __new__(self):
176 return cv.GArray(cv.gapi.CV_DRAW_PRIM)
177
178 class Any():
179 def __new__(self):
180 return cv.GArray(cv.gapi.CV_ANY)
181
182
183# NB: Top lvl decorator takes arguments
184def op(op_id, in_types, out_types):
185
186 garray_types= {
187 cv.GArray.Bool: cv.gapi.CV_BOOL,
188 cv.GArray.Int: cv.gapi.CV_INT,
189 cv.GArray.Int64: cv.gapi.CV_INT64,
190 cv.GArray.UInt64: cv.gapi.CV_UINT64,
191 cv.GArray.Double: cv.gapi.CV_DOUBLE,
192 cv.GArray.Float: cv.gapi.CV_FLOAT,
193 cv.GArray.String: cv.gapi.CV_STRING,
194 cv.GArray.Point: cv.gapi.CV_POINT,
195 cv.GArray.Point2f: cv.gapi.CV_POINT2F,
196 cv.GArray.Point3f: cv.gapi.CV_POINT3F,
197 cv.GArray.Size: cv.gapi.CV_SIZE,
198 cv.GArray.Rect: cv.gapi.CV_RECT,
199 cv.GArray.Scalar: cv.gapi.CV_SCALAR,
200 cv.GArray.Mat: cv.gapi.CV_MAT,
201 cv.GArray.GMat: cv.gapi.CV_GMAT,
202 cv.GArray.Prim: cv.gapi.CV_DRAW_PRIM,
203 cv.GArray.Any: cv.gapi.CV_ANY
204 }
205
206 gopaque_types= {
207 cv.GOpaque.Size: cv.gapi.CV_SIZE,
208 cv.GOpaque.Rect: cv.gapi.CV_RECT,
209 cv.GOpaque.Bool: cv.gapi.CV_BOOL,
210 cv.GOpaque.Int: cv.gapi.CV_INT,
211 cv.GOpaque.Int64: cv.gapi.CV_INT64,
212 cv.GOpaque.UInt64: cv.gapi.CV_UINT64,
213 cv.GOpaque.Double: cv.gapi.CV_DOUBLE,
214 cv.GOpaque.Float: cv.gapi.CV_FLOAT,
215 cv.GOpaque.String: cv.gapi.CV_STRING,
216 cv.GOpaque.Point: cv.gapi.CV_POINT,
217 cv.GOpaque.Point2f: cv.gapi.CV_POINT2F,
218 cv.GOpaque.Point3f: cv.gapi.CV_POINT3F,
219 cv.GOpaque.Size: cv.gapi.CV_SIZE,
220 cv.GOpaque.Rect: cv.gapi.CV_RECT,
221 cv.GOpaque.Prim: cv.gapi.CV_DRAW_PRIM,
222 cv.GOpaque.Any: cv.gapi.CV_ANY
223 }
224
225 type2str = {
226 cv.gapi.CV_BOOL: 'cv.gapi.CV_BOOL' ,
227 cv.gapi.CV_INT: 'cv.gapi.CV_INT' ,
228 cv.gapi.CV_INT64: 'cv.gapi.CV_INT64' ,
229 cv.gapi.CV_UINT64: 'cv.gapi.CV_UINT64' ,
230 cv.gapi.CV_DOUBLE: 'cv.gapi.CV_DOUBLE' ,
231 cv.gapi.CV_FLOAT: 'cv.gapi.CV_FLOAT' ,
232 cv.gapi.CV_STRING: 'cv.gapi.CV_STRING' ,
233 cv.gapi.CV_POINT: 'cv.gapi.CV_POINT' ,
234 cv.gapi.CV_POINT2F: 'cv.gapi.CV_POINT2F' ,
235 cv.gapi.CV_POINT3F: 'cv.gapi.CV_POINT3F' ,
236 cv.gapi.CV_SIZE: 'cv.gapi.CV_SIZE',
237 cv.gapi.CV_RECT: 'cv.gapi.CV_RECT',
238 cv.gapi.CV_SCALAR: 'cv.gapi.CV_SCALAR',
239 cv.gapi.CV_MAT: 'cv.gapi.CV_MAT',
240 cv.gapi.CV_GMAT: 'cv.gapi.CV_GMAT',
241 cv.gapi.CV_DRAW_PRIM: 'cv.gapi.CV_DRAW_PRIM'
242 }
243
244 # NB: Second lvl decorator takes class to decorate
245 def op_with_params(cls):
246 if not in_types:
247 raise Exception('{} operation should have at least one input!'.format(cls.__name__))
248
249 if not out_types:
250 raise Exception('{} operation should have at least one output!'.format(cls.__name__))
251
252 for i, t in enumerate(out_types):
253 if t not in [cv.GMat, cv.GScalar, *garray_types, *gopaque_types]:
254 raise Exception('{} unsupported output type: {} in position: {}'
255 .format(cls.__name__, t.__name__, i))
256
257 def on(*args):
258 if len(in_types) != len(args):
259 raise Exception('Invalid number of input elements!\nExpected: {}, Actual: {}'
260 .format(len(in_types), len(args)))
261
262 for i, (t, a) in enumerate(zip(in_types, args)):
263 if t in garray_types:
264 if not isinstance(a, cv.GArrayT):
265 raise Exception("{} invalid type for argument {}.\nExpected: {}, Actual: {}"
266 .format(cls.__name__, i, cv.GArrayT.__name__, type(a).__name__))
267
268 elif a.type() != garray_types[t]:
269 raise Exception("{} invalid GArrayT type for argument {}.\nExpected: {}, Actual: {}"
270 .format(cls.__name__, i, type2str[garray_types[t]], type2str[a.type()]))
271
272 elif t in gopaque_types:
273 if not isinstance(a, cv.GOpaqueT):
274 raise Exception("{} invalid type for argument {}.\nExpected: {}, Actual: {}"
275 .format(cls.__name__, i, cv.GOpaqueT.__name__, type(a).__name__))
276
277 elif a.type() != gopaque_types[t]:
278 raise Exception("{} invalid GOpaque type for argument {}.\nExpected: {}, Actual: {}"
279 .format(cls.__name__, i, type2str[gopaque_types[t]], type2str[a.type()]))
280
281 else:
282 if t != type(a):
283 raise Exception('{} invalid input type for argument {}.\nExpected: {}, Actual: {}'
284 .format(cls.__name__, i, t.__name__, type(a).__name__))
285
286 op = cv.gapi.__op(op_id, cls.outMeta, *args)
287
288 out_protos = []
289 for i, out_type in enumerate(out_types):
290 if out_type == cv.GMat:
291 out_protos.append(op.getGMat())
292 elif out_type == cv.GScalar:
293 out_protos.append(op.getGScalar())
294 elif out_type in gopaque_types:
295 out_protos.append(op.getGOpaque(gopaque_types[out_type]))
296 elif out_type in garray_types:
297 out_protos.append(op.getGArray(garray_types[out_type]))
298 else:
299 raise Exception("""In {}: G-API operation can't produce the output with type: {} in position: {}"""
300 .format(cls.__name__, out_type.__name__, i))
301
302 return tuple(out_protos) if len(out_protos) != 1 else out_protos[0]
303
304 # NB: Extend operation class
305 cls.id = op_id
306 cls.on = staticmethod(on)
307 return cls
308
309 return op_with_params
310
311
312def kernel(op_cls):
313 # NB: Second lvl decorator takes class to decorate
314 def kernel_with_params(cls):
315 # NB: Add new members to kernel class
316 cls.id = op_cls.id
317 cls.outMeta = op_cls.outMeta
318 return cls
319
320 return kernel_with_params
321
322
323cv.gapi.wip.GStreamerPipeline = cv.gapi_wip_gst_GStreamerPipeline
324 