g-api notes

目录

  • Q: What is GOrigin? What the meaning of parameters GMat(const GNode &n, std::size_t out)
  • Q: how does cv::Mat convert to cv::gapi::own::Mat? how memory is handled?
  • Q: Why not compile in GComputation ctor, but in apply()?
  • Q: Why compile inputs is in_metas but not out_metas?
  • Q: How does ade work? What is the meaning of these passes, eg
  • Q: How to impl a MergeChannel() operator?
  • Q: How is registered kernels dispatched?

class GAPI_EXPORTS GMat
{
public:
    GMat();                                 // Empty constructor
    GMat(const GNode &n, std::size_t out);  // Operation result constructor

    GOrigin& priv();                        // Internal use only
    const GOrigin& priv()  const;           // Internal use only

private:
    std::shared_ptr<GOrigin> m_priv;
};

Q: What is GOrigin? What the meaning of parameters GMat(const GNode &n, std::size_t out)

A: It seems GOrigin means the source of a edge, it consists of 2 parts: from which node‘s which index (a node may have multiple outputs?)


#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/gapi.hpp>
#include <opencv2/gapi/core.hpp>
#include <opencv2/gapi/imgproc.hpp>

int main(int argc, char *argv[])
{
    cv::VideoCapture cap;
    if (argc > 1) cap.open(argv[1]);
    else cap.open(0);
    CV_Assert(cap.isOpened());

    cv::GMat in;
    cv::GMat vga      = cv::gapi::resize(in, cv::Size(), 0.5, 0.5);
    cv::GMat gray     = cv::gapi::BGR2Gray(vga);
    cv::GMat blurred  = cv::gapi::blur(gray, cv::Size(5,5));
    cv::GMat edges    = cv::gapi::Canny(blurred, 32, 128, 3);
    cv::GMat b,g,r;
    std::tie(b,g,r)   = cv::gapi::split3(vga);
    cv::GMat out      = cv::gapi::merge3(b, g | edges, r);
    cv::GComputation ac(in, out);

    cv::Mat input_frame;
    cv::Mat output_frame;
    CV_Assert(cap.read(input_frame));
    do
    {
        ac.apply(input_frame, output_frame);
        cv::imshow("output", output_frame);
    } while (cap.read(input_frame) && cv::waitKey(30) < 0);

    return 0;
}

Q: how does cv::Mat convert to cv::gapi::own::Mat? how memory is handled?

A: when break down to the apply() function. the paramaters are converted to:


>   opencv_world400d.dll!cv::GComputation::apply(
    std::vector[cv::util::variant[cv::Mat,cv::Scalar_[double],cv::UMat,cv::gapi::own::Mat,cv::gapi::own::Scalar,cv::detail::VectorRef],std::allocator[cv::util::variant[cv::Mat,cv::Scalar_[double],cv::UMat,cv::gapi::own::Mat,cv::gapi::own::Scalar,cv::detail::VectorRef] ] ] && ins,
    std::vector[cv::util::variant[cv::Mat *,cv::Scalar_[double] *,cv::UMat *,cv::gapi::own::Mat *,cv::gapi::own::Scalar *,cv::detail::VectorRef],std::allocator[cv::util::variant[cv::Mat *,cv::Scalar_[double] *,cv::UMat *,cv::gapi::own::Mat *,cv::gapi::own::Scalar *,cv::detail::VectorRef] ] ] && outs,
    std::vector[cv::GCompileArg,std::allocator[cv::GCompileArg] ] && args) Line 102 C++

void cv::GComputation::apply(GRunArgs &&ins, GRunArgsP &&outs, GCompileArgs &&args)
{
    const auto in_metas = descr_of(ins);
    // FIXME Graph should be recompiled when GCompileArgs have changed
    if (m_priv->m_lastMetas != in_metas)
    {
        if (m_priv->m_lastCompiled &&
            m_priv->m_lastCompiled.canReshape() &&
            formats_are_same(m_priv->m_lastMetas, in_metas))
        {
            m_priv->m_lastCompiled.reshape(in_metas, args);
        }
        else
        {
            // FIXME: Had to construct temporary object as compile() takes && (r-value)
            m_priv->m_lastCompiled = compile(GMetaArgs(in_metas), std::move(args));
        }
        m_priv->m_lastMetas = in_metas;
    }
    m_priv->m_lastCompiled(std::move(ins), std::move(outs));
}

cv::GComputation ac(in, out);
ac.apply(input_frame, output_frame);

Q: Why not compile in GComputation ctor, but in apply()?

A: because only when apply the input shape can be determined

m_priv->m_lastCompiled = compile(GMetaArgs(in_metas), std::move(args));

Q: Why compile inputs is in_metas but not out_metas?

A: because use in_metas to determine graph‘s every node‘s shapes


cv::gimpl::GCompiler::GCompiler(const cv::GComputation &c,
                                GMetaArgs              &&metas,
                                GCompileArgs           &&args)
    : m_c(c), m_metas(std::move(metas)), m_args(std::move(args))
{
    using namespace std::placeholders;
    m_all_kernels       = getKernelPackage(m_args);
    auto lookup_order   = getCompileArg<gapi::GLookupOrder>(m_args).value_or(gapi::GLookupOrder());
    auto dump_path      = getGraphDumpDirectory(m_args);

    m_e.addPassStage("init");
    m_e.addPass("init", "check_cycles",  ade::passes::CheckCycles());
    m_e.addPass("init", "expand_kernels",  std::bind(passes::expandKernels, _1,
                                                     m_all_kernels)); // NB: package is copied
    m_e.addPass("init", "topo_sort",     ade::passes::TopologicalSort());
    m_e.addPass("init", "init_islands",  passes::initIslands);
    m_e.addPass("init", "check_islands", passes::checkIslands);
    // TODO:
    // - Check basic graph validity (i.e., all inputs are connected)
    // - Complex dependencies (i.e. parent-child) unrolling
    // - etc, etc, etc

    // Remove GCompoundBackend to avoid calling setupBackend() with it in the list
    m_all_kernels.remove(cv::gapi::compound::backend());
    m_e.addPass("init", "resolve_kernels", std::bind(passes::resolveKernels, _1,
                                                     std::ref(m_all_kernels), // NB: and not copied here
                                                     lookup_order));

    m_e.addPass("init", "check_islands_content", passes::checkIslandsContent);
    m_e.addPassStage("meta");
    m_e.addPass("meta", "initialize",   std::bind(passes::initMeta, _1, std::ref(m_metas)));
    m_e.addPass("meta", "propagate",    std::bind(passes::inferMeta, _1, false));
    m_e.addPass("meta", "finalize",     passes::storeResultingMeta);
    // moved to another stage, FIXME: two dumps?
    //    m_e.addPass("meta", "dump_dot",     passes::dumpDotStdout);

    // Special stage for backend-specific transformations
    // FIXME: document passes hierarchy and order for backend developers
    m_e.addPassStage("transform");

    m_e.addPassStage("exec");
    m_e.addPass("exec", "fuse_islands",     passes::fuseIslands);
    m_e.addPass("exec", "sync_islands",     passes::syncIslandTags);

    if (dump_path.has_value())
    {
        m_e.addPass("exec", "dump_dot", std::bind(passes::dumpGraph, _1,
                                                  dump_path.value()));
    }

    // Process backends at the last moment (after all G-API passes are added).
    ade::ExecutionEngineSetupContext ectx(m_e);
    auto backends = m_all_kernels.backends();
    for (auto &b : backends)
    {
        b.priv().addBackendPasses(ectx);
    }
}

Q: How does ade work? What is the meaning of these passes, eg

A: TODO???


   m_e.addPass("init", "check_cycles",  ade::passes::CheckCycles());
    m_e.addPass("init", "expand_kernels",  std::bind(passes::expandKernels, _1,
                                                     m_all_kernels)); // NB: package is copied
    m_e.addPass("init", "topo_sort",     ade::passes::TopologicalSort());
    m_e.addPass("init", "init_islands",  passes::initIslands);
    m_e.addPass("init", "check_islands", passes::checkIslands);

Q: How to impl a MergeChannel() operator?

A: ???

Q: How is registered kernels dispatched?

A:refer following callstack

    opencv_world400d.dll!GCPUCanny::run(const cv::Mat & in, double thr1, double thr2, int apSize, bool l2gradient, cv::Mat & out) Line 161  C++
    opencv_world400d.dll!cv::detail::OCVCallHelper<GCPUCanny,std::tuple<cv::GMat,double,double,int,bool>,std::tuple<cv::GMat> >::call_and_postprocess<cv::Mat,double,double,int,bool>::call<cv::detail::tracked_cv_mat>(cv::Mat && <ins_0>, double && <ins_1>, double && <ins_2>, int && <ins_3>, bool && <ins_4>, cv::detail::tracked_cv_mat && <outs_0>) Line 224 C++
    opencv_world400d.dll!cv::detail::OCVCallHelper<GCPUCanny,std::tuple<cv::GMat,double,double,int,bool>,std::tuple<cv::GMat> >::call_impl<0,1,2,3,4,0>(cv::GCPUContext & ctx, cv::detail::Seq<0,1,2,3,4> __formal, cv::detail::Seq<0> __formal) Line 237   C++
    opencv_world400d.dll!cv::detail::OCVCallHelper<GCPUCanny,std::tuple<cv::GMat,double,double,int,bool>,std::tuple<cv::GMat> >::call(cv::GCPUContext & ctx) Line 245   C++
    opencv_world400d.dll!std::_Invoker_functor::_Call<void (__cdecl*& __ptr64)(cv::GCPUContext & __ptr64),cv::GCPUContext & __ptr64>(void(*)(cv::GCPUContext &) & _Obj, cv::GCPUContext & <_Args_0>) Line 1377  C++
    opencv_world400d.dll!std::invoke<void (__cdecl*& __ptr64)(cv::GCPUContext & __ptr64),cv::GCPUContext & __ptr64>(void(*)(cv::GCPUContext &) & _Obj, cv::GCPUContext & <_Args_0>) Line 1445   C++
    opencv_world400d.dll!std::_Invoke_ret<void,void (__cdecl*& __ptr64)(cv::GCPUContext & __ptr64),cv::GCPUContext & __ptr64>(std::_Forced<void,1> __formal, void(*)(cv::GCPUContext &) & <_Vals_0>, cv::GCPUContext & <_Vals_1>) Line 1462 C++
    opencv_world400d.dll!std::_Func_impl<void (__cdecl*)(cv::GCPUContext & __ptr64),std::allocator<int>,void,cv::GCPUContext & __ptr64>::_Do_call(cv::GCPUContext & <_Args_0>) Line 214 C++
    opencv_world400d.dll!std::_Func_class<void,cv::GCPUContext & __ptr64>::operator()(cv::GCPUContext & <_Args_0>) Line 280 C++
    opencv_world400d.dll!cv::GCPUKernel::apply(cv::GCPUContext & ctx) Line 52   C++
    opencv_world400d.dll!cv::gimpl::GCPUExecutable::run(std::vector<std::pair<cv::gimpl::RcDesc,cv::util::variant<cv::Mat,cv::Scalar_<double>,cv::UMat,cv::gapi::own::Mat,cv::gapi::own::Scalar,cv::detail::VectorRef> >,std::allocator<std::pair<cv::gimpl::RcDesc,cv::util::variant<cv::Mat,cv::Scalar_<double>,cv::UMat,cv::gapi::own::Mat,cv::gapi::own::Scalar,cv::detail::VectorRef> > > > && input_objs, std::vector<std::pair<cv::gimpl::RcDesc,cv::util::variant<cv::Mat *,cv::Scalar_<double> *,cv::UMat *,cv::gapi::own::Mat *,cv::gapi::own::Scalar *,cv::detail::VectorRef> >,std::allocator<std::pair<cv::gimpl::RcDesc,cv::util::variant<cv::Mat *,cv::Scalar_<double> *,cv::UMat *,cv::gapi::own::Mat *,cv::gapi::own::Scalar *,cv::detail::VectorRef> > > > && output_objs) Line 210   C++
>   opencv_world400d.dll!cv::gimpl::GExecutor::run(cv::gimpl::GRuntimeArgs && args) Line 213    C++
    opencv_world400d.dll!cv::GCompiled::Priv::run(cv::gimpl::GRuntimeArgs && args) Line 39  C++
    opencv_world400d.dll!cv::GCompiled::operator()(std::vector<cv::util::variant<cv::Mat,cv::Scalar_<double>,cv::UMat,cv::gapi::own::Mat,cv::gapi::own::Scalar,cv::detail::VectorRef>,std::allocator<cv::util::variant<cv::Mat,cv::Scalar_<double>,cv::UMat,cv::gapi::own::Mat,cv::gapi::own::Scalar,cv::detail::VectorRef> > > && ins, std::vector<cv::util::variant<cv::Mat *,cv::Scalar_<double> *,cv::UMat *,cv::gapi::own::Mat *,cv::gapi::own::Scalar *,cv::detail::VectorRef>,std::allocator<cv::util::variant<cv::Mat *,cv::Scalar_<double> *,cv::UMat *,cv::gapi::own::Mat *,cv::gapi::own::Scalar *,cv::detail::VectorRef> > > && outs) Line 95   C++
    opencv_world400d.dll!cv::GComputation::apply(std::vector<cv::util::variant<cv::Mat,cv::Scalar_<double>,cv::UMat,cv::gapi::own::Mat,cv::gapi::own::Scalar,cv::detail::VectorRef>,std::allocator<cv::util::variant<cv::Mat,cv::Scalar_<double>,cv::UMat,cv::gapi::own::Mat,cv::gapi::own::Scalar,cv::detail::VectorRef> > > && ins, std::vector<cv::util::variant<cv::Mat *,cv::Scalar_<double> *,cv::UMat *,cv::gapi::own::Mat *,cv::gapi::own::Scalar *,cv::detail::VectorRef>,std::allocator<cv::util::variant<cv::Mat *,cv::Scalar_<double> *,cv::UMat *,cv::gapi::own::Mat *,cv::gapi::own::Scalar *,cv::detail::VectorRef> > > && outs, std::vector<cv::GCompileArg,std::allocator<cv::GCompileArg> > && args) Line 120 C++
    opencv_world400d.dll!cv::GComputation::apply(cv::Mat in, cv::Mat & out, std::vector<cv::GCompileArg,std::allocator<cv::GCompileArg> > && args) Line 140 C++
    testGapi.exe!main(int argc, char * * argv) Line 33  C++

原文地址:https://www.cnblogs.com/cutepig/p/12041551.html

时间: 2024-10-15 17:52:30

g-api notes的相关文章

git notes

[背景介绍] git一般在生成一个commit之后,如果需要修改到commit里面的commit message的话,一般会使得commit tree本身发生变化.如果只是修改commit tree的HEAD还好,如果是修改较前的一个commit,会导致后面的commit tree全都会乱掉.我们就需要有一种方法来保证:修改commit的commit message时,不需要动到commit tree.这就是我们这里要介绍到的git notes. [用法] 1. 为一个commit添加notes

RESTful API的设计原则

最近一直在做公司的一个API平台的项目,前后大约有半年多了,中间穿插了好多其他的项目一起做的.上周经理要求写文档,我就重新打开项目开始检阅之前的代码,发现好多地方当初设计的并不合理,忽然就想到,一个好的API平台,应该怎么来设计呢?有哪些规范要遵守呢?面对自己的项目,感觉好多地方都要改,但是已经有人在用了,怎么办?全都要改动吗?所以就上网找解决方案,然后就发现一精品贴,现转载过来,以备不时查阅. 原文地址:http://www.cnblogs.com/moonz-wu/p/4211626.htm

好RESTful API的设计原则

说在前面,这篇文章是无意中发现的,因为感觉写的很好,所以翻译了一下.由于英文水平有限,难免有出错的地方,请看官理解一下.翻译和校正文章花了我大约2周的业余时间,如有人愿意转载请注明出处,谢谢^_^ Principles of good RESTful API Design 好RESTful API的设计原则 Good API design is hard! An API represents a contract between you and those who Consume your da

springfox+swagger2生成API文档

1.建立一个spring mvc工程: 2.添加POM依赖: 1 <properties> 2 <springfoxversion>2.6.1</springfoxversion> 3 </properties> 4 <dependencies> 5 <dependency> 6 <groupId>io.springfox</groupId> 7 <artifactId>springfox-swag

java正则表达式汇总

core java volume 1:c The character c \unnnn, \xnn, \0n, \0nn, \0nnn The code unit with the given hex or octal value \t, \n, \r, \f, \a, \e The control characters tab, newline, return, form feed, alert, and escape \cc The control character correspondi

(转)SDL 1.2 to 2.0 Migration Guide--SDL1.2更新到SDL2.0指南

SDL 1.2 to 2.0 Migration Guide 目录 SDL 1.2 to 2.0 Migration Guide Translations Introduction Overview of new features Looking for more information Moving from SDL 1.2 to 2.0 Some general truths Video Setting up a game with the new video API If your gam

Core Java Volume I — 3.10. Arrays

3.10. ArraysAn array is a data structure that stores a collection of values of the same type. You access each individual value through an integer index. For example, if a is an array of integers, then a[i] is the ith integer in the array.Declare an a

【2】安卓学习之控件和布局

更新中... 控件: 一.button 拖一下,拉一下,图形化操作即可 按钮相应: 本次问题汇总: 一. android开发过程中突然发现的warning EditText 报出 "This text field does not specify an inputType or a hint" 原因: EditText需要指定默认输入类型 加入android:inputType="number|phone",表示指定为数字或电话 inputtype类型如下: and

Springfox与swagger的整合使用

一.前言 让我们先理一下springfox与swagger的关系. swagger是一个流行的API开发框架,这个框架以"开放API声明"(OpenAPI Specification,OAS)为基础,对整个API的开发周期都提供了相应的解决方案,是一个非常庞大的项目(包括设计.编码和测试,几乎支持所有语言). OAS本身是一个API规范,它用于描述一整套API接口,包括一个接口是GET还是POST请求啊,有哪些参数哪些header啊,都会被包括在这个文件中.它在设计的时候通常是YAML

P6 EPPM Installation and Configuration Guide 16 R1 April 2016

P6 EPPM Installation and Configuration Guide 16 R1         April 2016 Contents About Installing and Configuring P6 EPPM ........................................................ 6 Prerequisites for P6 EPPM Configuration ...............................