github.com/kaydxh/golang@v0.0.131/pkg/gocv/cgo/third_path/opencv4/include/opencv2/gapi/gcomputation.hpp (about) 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) 2018 Intel Corporation 6 7 8 #ifndef OPENCV_GAPI_GCOMPUTATION_HPP 9 #define OPENCV_GAPI_GCOMPUTATION_HPP 10 11 #include <functional> 12 13 #include <opencv2/gapi/util/util.hpp> 14 #include <opencv2/gapi/gcommon.hpp> 15 #include <opencv2/gapi/gproto.hpp> 16 #include <opencv2/gapi/garg.hpp> 17 #include <opencv2/gapi/gcompiled.hpp> 18 #include <opencv2/gapi/gstreaming.hpp> 19 20 namespace cv { 21 22 namespace detail 23 { 24 // FIXME: move to algorithm, cover with separate tests 25 // FIXME: replace with O(1) version (both memory and compilation time) 26 template<typename...> 27 struct last_type; 28 29 template<typename T> 30 struct last_type<T> { using type = T;}; 31 32 template<typename T, typename... Ts> 33 struct last_type<T, Ts...> { using type = typename last_type<Ts...>::type; }; 34 35 template<typename... Ts> 36 using last_type_t = typename last_type<Ts...>::type; 37 } 38 39 // Forward-declare the serialization objects 40 namespace gapi { 41 namespace s11n { 42 struct IIStream; 43 struct IOStream; 44 } // namespace s11n 45 } // namespace gapi 46 47 /** 48 * \addtogroup gapi_main_classes 49 * @{ 50 * 51 * @brief G-API classes for constructed and compiled graphs. 52 */ 53 /** 54 * @brief GComputation class represents a captured computation 55 * graph. GComputation objects form boundaries for expression code 56 * user writes with G-API, allowing to compile and execute it. 57 * 58 * G-API computations are defined with input/output data 59 * objects. G-API will track automatically which operations connect 60 * specified outputs to the inputs, forming up a call graph to be 61 * executed. The below example expresses calculation of Sobel operator 62 * for edge detection (\f$G = \sqrt{G_x^2 + G_y^2}\f$): 63 * 64 * @snippet modules/gapi/samples/api_ref_snippets.cpp graph_def 65 * 66 * Full pipeline can be now captured with this object declaration: 67 * 68 * @snippet modules/gapi/samples/api_ref_snippets.cpp graph_cap_full 69 * 70 * Input/output data objects on which a call graph should be 71 * reconstructed are passed using special wrappers cv::GIn and 72 * cv::GOut. G-API will track automatically which operations form a 73 * path from inputs to outputs and build the execution graph appropriately. 74 * 75 * Note that cv::GComputation doesn't take ownership on data objects 76 * it is defined. Moreover, multiple GComputation objects may be 77 * defined on the same expressions, e.g. a smaller pipeline which 78 * expects that image gradients are already pre-calculated may be 79 * defined like this: 80 * 81 * @snippet modules/gapi/samples/api_ref_snippets.cpp graph_cap_sub 82 * 83 * The resulting graph would expect two inputs and produce one 84 * output. In this case, it doesn't matter if gx/gy data objects are 85 * results of cv::gapi::Sobel operators -- G-API will stop unrolling 86 * expressions and building the underlying graph one reaching this 87 * data objects. 88 * 89 * The way how GComputation is defined is important as its definition 90 * specifies graph _protocol_ -- the way how the graph should be 91 * used. Protocol is defined by number of inputs, number of outputs, 92 * and shapes of inputs and outputs. 93 * 94 * In the above example, sobelEdge expects one Mat on input and 95 * produces one Mat; while sobelEdgeSub expects two Mats on input and 96 * produces one Mat. GComputation's protocol defines how other 97 * computation methods should be used -- cv::GComputation::compile() and 98 * cv::GComputation::apply(). For example, if a graph is defined on 99 * two GMat inputs, two cv::Mat objects have to be passed to apply() 100 * for execution. GComputation checks protocol correctness in runtime 101 * so passing a different number of objects in apply() or passing 102 * cv::Scalar instead of cv::Mat there would compile well as a C++ 103 * source but raise an exception in run-time. G-API also comes with a 104 * typed wrapper cv::GComputationT<> which introduces this type-checking in 105 * compile-time. 106 * 107 * cv::GComputation itself is a thin object which just captures what 108 * the graph is. The compiled graph (which actually process data) is 109 * represented by class GCompiled. Use compile() method to generate a 110 * compiled graph with given compile options. cv::GComputation can 111 * also be used to process data with implicit graph compilation 112 * on-the-fly, see apply() for details. 113 * 114 * GComputation is a reference-counted object -- once defined, all its 115 * copies will refer to the same instance. 116 * 117 * @sa GCompiled 118 */ 119 class GAPI_EXPORTS_W GComputation 120 { 121 public: 122 class Priv; 123 typedef std::function<GComputation()> Generator; 124 125 // Various constructors enable different ways to define a computation: ///// 126 // 1. Generic constructors 127 /** 128 * @brief Define a computation using a generator function. 129 * 130 * Graph can be defined in-place directly at the moment of its 131 * construction with a lambda: 132 * 133 * @snippet modules/gapi/samples/api_ref_snippets.cpp graph_gen 134 * 135 * This may be useful since all temporary objects (cv::GMats) and 136 * namespaces can be localized to scope of lambda, without 137 * contaminating the parent scope with probably unnecessary objects 138 * and information. 139 * 140 * @param gen generator function which returns a cv::GComputation, 141 * see Generator. 142 */ 143 GComputation(const Generator& gen); // Generator 144 // overload 145 146 /** 147 * @brief Generic GComputation constructor. 148 * 149 * Constructs a new graph with a given protocol, specified as a 150 * flow of operations connecting input/output objects. Throws if 151 * the passed boundaries are invalid, e.g. if there's no 152 * functional dependency (path) between given outputs and inputs. 153 * 154 * @param ins Input data vector. 155 * @param outs Output data vector. 156 * 157 * @note Don't construct GProtoInputArgs/GProtoOutputArgs objects 158 * directly, use cv::GIn()/cv::GOut() wrapper functions instead. 159 * 160 * @sa @ref gapi_data_objects 161 */ 162 GAPI_WRAP GComputation(GProtoInputArgs &&ins, 163 GProtoOutputArgs &&outs); // Arg-to-arg overload 164 165 // 2. Syntax sugar and compatibility overloads 166 /** 167 * @brief Defines an unary (one input -- one output) computation 168 * 169 * @overload 170 * @param in input GMat of the defined unary computation 171 * @param out output GMat of the defined unary computation 172 */ 173 GAPI_WRAP GComputation(GMat in, GMat out); // Unary overload 174 175 /** 176 * @brief Defines an unary (one input -- one output) computation 177 * 178 * @overload 179 * @param in input GMat of the defined unary computation 180 * @param out output GScalar of the defined unary computation 181 */ 182 GAPI_WRAP GComputation(GMat in, GScalar out); // Unary overload (scalar) 183 184 /** 185 * @brief Defines a binary (two inputs -- one output) computation 186 * 187 * @overload 188 * @param in1 first input GMat of the defined binary computation 189 * @param in2 second input GMat of the defined binary computation 190 * @param out output GMat of the defined binary computation 191 */ 192 GAPI_WRAP GComputation(GMat in1, GMat in2, GMat out); // Binary overload 193 194 /** 195 * @brief Defines a binary (two inputs -- one output) computation 196 * 197 * @overload 198 * @param in1 first input GMat of the defined binary computation 199 * @param in2 second input GMat of the defined binary computation 200 * @param out output GScalar of the defined binary computation 201 */ 202 GComputation(GMat in1, GMat in2, GScalar out); // Binary 203 // overload 204 // (scalar) 205 206 /** 207 * @brief Defines a computation with arbitrary input/output number. 208 * 209 * @overload 210 * @param ins vector of inputs GMats for this computation 211 * @param outs vector of outputs GMats for this computation 212 * 213 * Use this overload for cases when number of computation 214 * inputs/outputs is not known in compile-time -- e.g. when graph 215 * is programmatically generated to build an image pyramid with 216 * the given number of levels, etc. 217 */ 218 GComputation(const std::vector<GMat> &ins, // Compatibility overload 219 const std::vector<GMat> &outs); 220 221 // Various versions of apply(): //////////////////////////////////////////// 222 // 1. Generic apply() 223 /** 224 * @brief Compile graph on-the-fly and immediately execute it on 225 * the inputs data vectors. 226 * 227 * Number of input/output data objects must match GComputation's 228 * protocol, also types of host data objects (cv::Mat, cv::Scalar) 229 * must match the shapes of data objects from protocol (cv::GMat, 230 * cv::GScalar). If there's a mismatch, a run-time exception will 231 * be generated. 232 * 233 * Internally, a cv::GCompiled object is created for the given 234 * input format configuration, which then is executed on the input 235 * data immediately. cv::GComputation caches compiled objects 236 * produced within apply() -- if this method would be called next 237 * time with the same input parameters (image formats, image 238 * resolution, etc), the underlying compiled graph will be reused 239 * without recompilation. If new metadata doesn't match the cached 240 * one, the underlying compiled graph is regenerated. 241 * 242 * @note compile() always triggers a compilation process and 243 * produces a new GCompiled object regardless if a similar one has 244 * been cached via apply() or not. 245 * 246 * @param ins vector of input data to process. Don't create 247 * GRunArgs object manually, use cv::gin() wrapper instead. 248 * @param outs vector of output data to fill results in. cv::Mat 249 * objects may be empty in this vector, G-API will automatically 250 * initialize it with the required format & dimensions. Don't 251 * create GRunArgsP object manually, use cv::gout() wrapper instead. 252 * @param args a list of compilation arguments to pass to the 253 * underlying compilation process. Don't create GCompileArgs 254 * object manually, use cv::compile_args() wrapper instead. 255 * 256 * @sa @ref gapi_data_objects, @ref gapi_compile_args 257 */ 258 void apply(GRunArgs &&ins, GRunArgsP &&outs, GCompileArgs &&args = {}); // Arg-to-arg overload 259 260 /// @private -- Exclude this function from OpenCV documentation 261 GAPI_WRAP GRunArgs apply(const cv::detail::ExtractArgsCallback &callback, 262 GCompileArgs &&args = {}); 263 264 /// @private -- Exclude this function from OpenCV documentation 265 void apply(const std::vector<cv::Mat>& ins, // Compatibility overload 266 const std::vector<cv::Mat>& outs, 267 GCompileArgs &&args = {}); 268 269 // 2. Syntax sugar and compatibility overloads 270 #if !defined(GAPI_STANDALONE) 271 /** 272 * @brief Execute an unary computation (with compilation on the fly) 273 * 274 * @overload 275 * @param in input cv::Mat for unary computation 276 * @param out output cv::Mat for unary computation 277 * @param args compilation arguments for underlying compilation 278 * process. 279 */ 280 void apply(cv::Mat in, cv::Mat &out, GCompileArgs &&args = {}); // Unary overload 281 282 /** 283 * @brief Execute an unary computation (with compilation on the fly) 284 * 285 * @overload 286 * @param in input cv::Mat for unary computation 287 * @param out output cv::Scalar for unary computation 288 * @param args compilation arguments for underlying compilation 289 * process. 290 */ 291 void apply(cv::Mat in, cv::Scalar &out, GCompileArgs &&args = {}); // Unary overload (scalar) 292 293 /** 294 * @brief Execute a binary computation (with compilation on the fly) 295 * 296 * @overload 297 * @param in1 first input cv::Mat for binary computation 298 * @param in2 second input cv::Mat for binary computation 299 * @param out output cv::Mat for binary computation 300 * @param args compilation arguments for underlying compilation 301 * process. 302 */ 303 void apply(cv::Mat in1, cv::Mat in2, cv::Mat &out, GCompileArgs &&args = {}); // Binary overload 304 305 /** 306 * @brief Execute an binary computation (with compilation on the fly) 307 * 308 * @overload 309 * @param in1 first input cv::Mat for binary computation 310 * @param in2 second input cv::Mat for binary computation 311 * @param out output cv::Scalar for binary computation 312 * @param args compilation arguments for underlying compilation 313 * process. 314 */ 315 void apply(cv::Mat in1, cv::Mat in2, cv::Scalar &out, GCompileArgs &&args = {}); // Binary overload (scalar) 316 317 /** 318 * @brief Execute a computation with arbitrary number of 319 * inputs/outputs (with compilation on-the-fly). 320 * 321 * @overload 322 * @param ins vector of input cv::Mat objects to process by the 323 * computation. 324 * @param outs vector of output cv::Mat objects to produce by the 325 * computation. 326 * @param args compilation arguments for underlying compilation 327 * process. 328 * 329 * Numbers of elements in ins/outs vectors must match numbers of 330 * inputs/outputs which were used to define this GComputation. 331 */ 332 void apply(const std::vector<cv::Mat>& ins, // Compatibility overload 333 std::vector<cv::Mat>& outs, 334 GCompileArgs &&args = {}); 335 #endif // !defined(GAPI_STANDALONE) 336 // Various versions of compile(): ////////////////////////////////////////// 337 // 1. Generic compile() - requires metas to be passed as vector 338 /** 339 * @brief Compile the computation for specific input format(s). 340 * 341 * This method triggers compilation process and produces a new 342 * GCompiled object which then can process data of the given 343 * format. Passing data with different format to the compiled 344 * computation will generate a run-time exception. 345 * 346 * @param in_metas vector of input metadata configuration. Grab 347 * metadata from real data objects (like cv::Mat or cv::Scalar) 348 * using cv::descr_of(), or create it on your own. 349 * @param args compilation arguments for this compilation 350 * process. Compilation arguments directly affect what kind of 351 * executable object would be produced, e.g. which kernels (and 352 * thus, devices) would be used to execute computation. 353 * 354 * @return GCompiled, an executable computation compiled 355 * specifically for the given input parameters. 356 * 357 * @sa @ref gapi_compile_args 358 */ 359 GCompiled compile(GMetaArgs &&in_metas, GCompileArgs &&args = {}); 360 361 // 2. Syntax sugar - variadic list of metas, no extra compile args 362 // FIXME: SFINAE looks ugly in the generated documentation 363 /** 364 * @overload 365 * 366 * Takes a variadic parameter pack with metadata 367 * descriptors for which a compiled object needs to be produced. 368 * 369 * @return GCompiled, an executable computation compiled 370 * specifically for the given input parameters. 371 */ 372 template<typename... Ts> 373 auto compile(const Ts&... metas) -> 374 typename std::enable_if<detail::are_meta_descrs<Ts...>::value, GCompiled>::type 375 { 376 return compile(GMetaArgs{GMetaArg(metas)...}, GCompileArgs()); 377 } 378 379 // 3. Syntax sugar - variadic list of metas, extra compile args 380 // (seems optional parameters don't work well when there's an variadic template 381 // comes first) 382 // 383 // Ideally it should look like: 384 // 385 // template<typename... Ts> 386 // GCompiled compile(const Ts&... metas, GCompileArgs &&args) 387 // 388 // But not all compilers can handle this (and seems they shouldn't be able to). 389 // FIXME: SFINAE looks ugly in the generated documentation 390 /** 391 * @overload 392 * 393 * Takes a variadic parameter pack with metadata 394 * descriptors for which a compiled object needs to be produced, 395 * followed by GCompileArgs object representing compilation 396 * arguments for this process. 397 * 398 * @return GCompiled, an executable computation compiled 399 * specifically for the given input parameters. 400 */ 401 template<typename... Ts> 402 auto compile(const Ts&... meta_and_compile_args) -> 403 typename std::enable_if<detail::are_meta_descrs_but_last<Ts...>::value 404 && std::is_same<GCompileArgs, detail::last_type_t<Ts...> >::value, 405 GCompiled>::type 406 { 407 //FIXME: wrapping meta_and_compile_args into a tuple to unwrap them inside a helper function is the overkill 408 return compile(std::make_tuple(meta_and_compile_args...), 409 typename detail::MkSeq<sizeof...(Ts)-1>::type()); 410 } 411 412 413 // FIXME: Document properly in the Doxygen format 414 // Video-oriented pipeline compilation: 415 // 1. A generic version 416 /** 417 * @brief Compile the computation for streaming mode. 418 * 419 * This method triggers compilation process and produces a new 420 * GStreamingCompiled object which then can process video stream 421 * data of the given format. Passing a stream in a different 422 * format to the compiled computation will generate a run-time 423 * exception. 424 * 425 * @param in_metas vector of input metadata configuration. Grab 426 * metadata from real data objects (like cv::Mat or cv::Scalar) 427 * using cv::descr_of(), or create it on your own. 428 * 429 * @param args compilation arguments for this compilation 430 * process. Compilation arguments directly affect what kind of 431 * executable object would be produced, e.g. which kernels (and 432 * thus, devices) would be used to execute computation. 433 * 434 * @return GStreamingCompiled, a streaming-oriented executable 435 * computation compiled specifically for the given input 436 * parameters. 437 * 438 * @sa @ref gapi_compile_args 439 */ 440 GStreamingCompiled compileStreaming(GMetaArgs &&in_metas, GCompileArgs &&args = {}); 441 442 /// @private -- Exclude this function from OpenCV documentation 443 GAPI_WRAP GStreamingCompiled compileStreaming(const cv::detail::ExtractMetaCallback &callback, 444 GCompileArgs &&args = {}); 445 446 /** 447 * @brief Compile the computation for streaming mode. 448 * 449 * This method triggers compilation process and produces a new 450 * GStreamingCompiled object which then can process video stream 451 * data in any format. Underlying mechanisms will be adjusted to 452 * every new input video stream automatically, but please note that 453 * _not all_ existing backends support this (see reshape()). 454 * 455 * @param args compilation arguments for this compilation 456 * process. Compilation arguments directly affect what kind of 457 * executable object would be produced, e.g. which kernels (and 458 * thus, devices) would be used to execute computation. 459 * 460 * @return GStreamingCompiled, a streaming-oriented executable 461 * computation compiled for any input image format. 462 * 463 * @sa @ref gapi_compile_args 464 */ 465 GAPI_WRAP GStreamingCompiled compileStreaming(GCompileArgs &&args = {}); 466 467 // 2. Direct metadata version 468 /** 469 * @overload 470 * 471 * Takes a variadic parameter pack with metadata 472 * descriptors for which a compiled object needs to be produced. 473 * 474 * @return GStreamingCompiled, a streaming-oriented executable 475 * computation compiled specifically for the given input 476 * parameters. 477 */ 478 template<typename... Ts> 479 auto compileStreaming(const Ts&... metas) -> 480 typename std::enable_if<detail::are_meta_descrs<Ts...>::value, GStreamingCompiled>::type 481 { 482 return compileStreaming(GMetaArgs{GMetaArg(metas)...}, GCompileArgs()); 483 } 484 485 // 2. Direct metadata + compile arguments version 486 /** 487 * @overload 488 * 489 * Takes a variadic parameter pack with metadata 490 * descriptors for which a compiled object needs to be produced, 491 * followed by GCompileArgs object representing compilation 492 * arguments for this process. 493 * 494 * @return GStreamingCompiled, a streaming-oriented executable 495 * computation compiled specifically for the given input 496 * parameters. 497 */ 498 template<typename... Ts> 499 auto compileStreaming(const Ts&... meta_and_compile_args) -> 500 typename std::enable_if<detail::are_meta_descrs_but_last<Ts...>::value 501 && std::is_same<GCompileArgs, detail::last_type_t<Ts...> >::value, 502 GStreamingCompiled>::type 503 { 504 //FIXME: wrapping meta_and_compile_args into a tuple to unwrap them inside a helper function is the overkill 505 return compileStreaming(std::make_tuple(meta_and_compile_args...), 506 typename detail::MkSeq<sizeof...(Ts)-1>::type()); 507 } 508 509 // Internal use only 510 /// @private 511 Priv& priv(); 512 /// @private 513 const Priv& priv() const; 514 /// @private 515 explicit GComputation(cv::gapi::s11n::IIStream &); 516 /// @private 517 void serialize(cv::gapi::s11n::IOStream &) const; 518 519 protected: 520 521 // 4. Helper methods for (3) 522 /// @private 523 template<typename... Ts, int... IIs> 524 GCompiled compile(const std::tuple<Ts...> &meta_and_compile_args, detail::Seq<IIs...>) 525 { 526 GMetaArgs meta_args = {GMetaArg(std::get<IIs>(meta_and_compile_args))...}; 527 GCompileArgs comp_args = std::get<sizeof...(Ts)-1>(meta_and_compile_args); 528 return compile(std::move(meta_args), std::move(comp_args)); 529 } 530 template<typename... Ts, int... IIs> 531 GStreamingCompiled compileStreaming(const std::tuple<Ts...> &meta_and_compile_args, detail::Seq<IIs...>) 532 { 533 GMetaArgs meta_args = {GMetaArg(std::get<IIs>(meta_and_compile_args))...}; 534 GCompileArgs comp_args = std::get<sizeof...(Ts)-1>(meta_and_compile_args); 535 return compileStreaming(std::move(meta_args), std::move(comp_args)); 536 } 537 void recompile(GMetaArgs&& in_metas, GCompileArgs &&args); 538 /// @private 539 std::shared_ptr<Priv> m_priv; 540 }; 541 /** @} */ 542 543 namespace gapi 544 { 545 // FIXME: all these standalone functions need to be added to some 546 // common documentation section 547 /** 548 * @brief Define an tagged island (subgraph) within a computation. 549 * 550 * Declare an Island tagged with `name` and defined from `ins` to `outs` 551 * (exclusively, as ins/outs are data objects, and regioning is done on 552 * operations level). 553 * Throws if any operation between `ins` and `outs` are already assigned 554 * to another island. 555 * 556 * Islands allow to partition graph into subgraphs, fine-tuning 557 * the way it is scheduled by the underlying executor. 558 * 559 * @param name name of the Island to create 560 * @param ins vector of input data objects where the subgraph 561 * begins 562 * @param outs vector of output data objects where the subgraph 563 * ends. 564 * 565 * The way how an island is defined is similar to how 566 * cv::GComputation is defined on input/output data objects. 567 * Same rules apply here as well -- if there's no functional 568 * dependency between inputs and outputs or there's not enough 569 * input data objects were specified to properly calculate all 570 * outputs, an exception is thrown. 571 * 572 * Use cv::GIn() / cv::GOut() to specify input/output vectors. 573 */ 574 void GAPI_EXPORTS island(const std::string &name, 575 GProtoInputArgs &&ins, 576 GProtoOutputArgs &&outs); 577 } // namespace gapi 578 579 } // namespace cv 580 #endif // OPENCV_GAPI_GCOMPUTATION_HPP