__init__.py 10 KB

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