feat: 切换后端至PaddleOCR-NCNN,切换工程为CMake
1.项目后端整体迁移至PaddleOCR-NCNN算法,已通过基本的兼容性测试 2.工程改为使用CMake组织,后续为了更好地兼容第三方库,不再提供QMake工程 3.重整权利声明文件,重整代码工程,确保最小化侵权风险 Log: 切换后端至PaddleOCR-NCNN,切换工程为CMake Change-Id: I4d5d2c5d37505a4a24b389b1a4c5d12f17bfa38c
This commit is contained in:
27
3rdparty/opencv-4.5.4/modules/gapi/doc/slides/README.md
vendored
Normal file
27
3rdparty/opencv-4.5.4/modules/gapi/doc/slides/README.md
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
# G-API Overview
|
||||
|
||||
This is the latest overview slide deck on G-API.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- [Emacs] v24 or higher;
|
||||
- [Org]-mode 8.2.10;
|
||||
- `pdflatex`;
|
||||
- `texlive-latex-recommended` ([Beamer] package);
|
||||
- `texlive-font-utils` (`epstopdf`);
|
||||
- `wget` (for `get_sty.sh`).
|
||||
|
||||
## Building
|
||||
|
||||
1. Download and build the [Metropolis] theme with the script:
|
||||
|
||||
```
|
||||
$ ./get_sty.sh
|
||||
```
|
||||
|
||||
2. Now open `gapi_overview.org` with Emacs and press `C-c C-e l P`.
|
||||
|
||||
[Emacs]: https://www.gnu.org/software/emacs/
|
||||
[Org]: https://orgmode.org/
|
||||
[Beamer]: https://ctan.org/pkg/beamer
|
||||
[Metropolis]: https://github.com/matze/mtheme
|
961
3rdparty/opencv-4.5.4/modules/gapi/doc/slides/gapi_overview.org
vendored
Normal file
961
3rdparty/opencv-4.5.4/modules/gapi/doc/slides/gapi_overview.org
vendored
Normal file
@ -0,0 +1,961 @@
|
||||
#+TITLE: OpenCV 4.4 Graph API
|
||||
#+AUTHOR: Dmitry Matveev\newline Intel Corporation
|
||||
#+OPTIONS: H:2 toc:t num:t
|
||||
#+LATEX_CLASS: beamer
|
||||
#+LATEX_CLASS_OPTIONS: [presentation]
|
||||
#+LATEX_HEADER: \usepackage{transparent} \usepackage{listings} \usepackage{pgfplots} \usepackage{mtheme.sty/beamerthememetropolis}
|
||||
#+LATEX_HEADER: \setbeamertemplate{frame footer}{OpenCV 4.4 G-API: Overview and programming by example}
|
||||
#+BEAMER_HEADER: \subtitle{Overview and programming by example}
|
||||
#+BEAMER_HEADER: \titlegraphic{ \vspace*{3cm}\hspace*{5cm} {\transparent{0.2}\includegraphics[height=\textheight]{ocv_logo.eps}}}
|
||||
#+COLUMNS: %45ITEM %10BEAMER_ENV(Env) %10BEAMER_ACT(Act) %4BEAMER_COL(Col) %8BEAMER_OPT(Opt)
|
||||
|
||||
* G-API: What is, why, what's for?
|
||||
|
||||
** OpenCV evolution in one slide
|
||||
|
||||
*** Version 1.x -- Library inception
|
||||
|
||||
- Just a set of CV functions + helpers around (visualization, IO);
|
||||
|
||||
*** Version 2.x -- Library rewrite
|
||||
|
||||
- OpenCV meets C++, ~cv::Mat~ replaces ~IplImage*~;
|
||||
|
||||
*** Version 3.0 -- Welcome Transparent API (T-API)
|
||||
|
||||
- ~cv::UMat~ is introduced as a /transparent/ addition to
|
||||
~cv::Mat~;
|
||||
- With ~cv::UMat~, an OpenCL kernel can be enqeueud instead of
|
||||
immediately running C code;
|
||||
- ~cv::UMat~ data is kept on a /device/ until explicitly queried.
|
||||
|
||||
** OpenCV evolution in one slide (cont'd)
|
||||
# FIXME: Learn proper page-breaking!
|
||||
|
||||
*** Version 4.0 -- Welcome Graph API (G-API)
|
||||
|
||||
- A new separate module (not a full library rewrite);
|
||||
- A framework (or even a /meta/-framework);
|
||||
- Usage model:
|
||||
- /Express/ an image/vision processing graph and then /execute/ it;
|
||||
- Fine-tune execution without changes in the graph;
|
||||
- Similar to Halide -- separates logic from
|
||||
platform details.
|
||||
- More than Halide:
|
||||
- Kernels can be written in unconstrained platform-native code;
|
||||
- Halide can serve as a backend (one of many).
|
||||
|
||||
** OpenCV evolution in one slide (cont'd)
|
||||
# FIXME: Learn proper page-breaking!
|
||||
|
||||
*** Version 4.2 -- New horizons
|
||||
|
||||
- Introduced in-graph inference via OpenVINO™ Toolkit;
|
||||
- Introduced video-oriented Streaming execution mode;
|
||||
- Extended focus from individual image processing to the full
|
||||
application pipeline optimization.
|
||||
|
||||
*** Version 4.4 -- More on video
|
||||
|
||||
- Introduced a notion of stateful kernels;
|
||||
- The road to object tracking, background subtraction, etc. in the
|
||||
graph;
|
||||
- Added more video-oriented operations (feature detection, Optical
|
||||
flow).
|
||||
|
||||
** Why G-API?
|
||||
|
||||
*** Why introduce a new execution model?
|
||||
|
||||
- Ultimately it is all about optimizations;
|
||||
- or at least about a /possibility/ to optimize;
|
||||
- A CV algorithm is usually not a single function call, but a
|
||||
composition of functions;
|
||||
- Different models operate at different levels of knowledge on the
|
||||
algorithm (problem) we run.
|
||||
|
||||
** Why G-API? (cont'd)
|
||||
# FIXME: Learn proper page-breaking!
|
||||
|
||||
*** Why introduce a new execution model?
|
||||
|
||||
- *Traditional* -- every function can be optimized (e.g. vectorized)
|
||||
and parallelized, the rest is up to programmer to care about.
|
||||
- *Queue-based* -- kernels are enqueued dynamically with no guarantee
|
||||
where the end is or what is called next;
|
||||
- *Graph-based* -- nearly all information is there, some compiler
|
||||
magic can be done!
|
||||
|
||||
** What is G-API for?
|
||||
|
||||
*** Bring the value of graph model with OpenCV where it makes sense:
|
||||
|
||||
- *Memory consumption* can be reduced dramatically;
|
||||
- *Memory access* can be optimized to maximize cache reuse;
|
||||
- *Parallelism* can be applied automatically where it is hard to do
|
||||
it manually;
|
||||
- It also becomes more efficient when working with graphs;
|
||||
- *Heterogeneity* gets extra benefits like:
|
||||
- Avoiding unnecessary data transfers;
|
||||
- Shadowing transfer costs with parallel host co-execution;
|
||||
- Improving system throughput with frame-level pipelining.
|
||||
|
||||
* Programming with G-API
|
||||
|
||||
** G-API Basics
|
||||
|
||||
*** G-API Concepts
|
||||
|
||||
- *Graphs* are built by applying /operations/ to /data objects/;
|
||||
- API itself has no "graphs", it is expression-based instead;
|
||||
- *Data objects* do not hold actual data, only capture /dependencies/;
|
||||
- *Operations* consume and produce data objects.
|
||||
- A graph is defined by specifying its /boundaries/ with data objects:
|
||||
- What data objects are /inputs/ to the graph?
|
||||
- What are its /outputs/?
|
||||
|
||||
** The code is worth a thousand words
|
||||
:PROPERTIES:
|
||||
:BEAMER_opt: shrink=42
|
||||
:END:
|
||||
|
||||
#+BEGIN_SRC C++
|
||||
#include <opencv2/gapi.hpp> // G-API framework header
|
||||
#include <opencv2/gapi/imgproc.hpp> // cv::gapi::blur()
|
||||
#include <opencv2/highgui.hpp> // cv::imread/imwrite
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc < 3) return 1;
|
||||
|
||||
cv::GMat in; // Express the graph:
|
||||
cv::GMat out = cv::gapi::blur(in, cv::Size(3,3)); // `out` is a result of `blur` of `in`
|
||||
|
||||
cv::Mat in_mat = cv::imread(argv[1]); // Get the real data
|
||||
cv::Mat out_mat; // Output buffer (may be empty)
|
||||
|
||||
cv::GComputation(cv::GIn(in), cv::GOut(out)) // Declare a graph from `in` to `out`
|
||||
.apply(cv::gin(in_mat), cv::gout(out_mat)); // ...and run it immediately
|
||||
|
||||
cv::imwrite(argv[2], out_mat); // Save the result
|
||||
return 0;
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
** The code is worth a thousand words
|
||||
:PROPERTIES:
|
||||
:BEAMER_opt: shrink=42
|
||||
:END:
|
||||
|
||||
*** Traditional OpenCV :B_block:BMCOL:
|
||||
:PROPERTIES:
|
||||
:BEAMER_env: block
|
||||
:BEAMER_col: 0.45
|
||||
:END:
|
||||
#+BEGIN_SRC C++
|
||||
#include <opencv2/core.hpp>
|
||||
#include <opencv2/imgproc.hpp>
|
||||
|
||||
#include <opencv2/highgui.hpp>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
using namespace cv;
|
||||
if (argc != 3) return 1;
|
||||
|
||||
Mat in_mat = imread(argv[1]);
|
||||
Mat gx, gy;
|
||||
|
||||
Sobel(in_mat, gx, CV_32F, 1, 0);
|
||||
Sobel(in_mat, gy, CV_32F, 0, 1);
|
||||
|
||||
Mat mag, out_mat;
|
||||
sqrt(gx.mul(gx) + gy.mul(gy), mag);
|
||||
mag.convertTo(out_mat, CV_8U);
|
||||
|
||||
imwrite(argv[2], out_mat);
|
||||
return 0;
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
*** OpenCV G-API :B_block:BMCOL:
|
||||
:PROPERTIES:
|
||||
:BEAMER_env: block
|
||||
:BEAMER_col: 0.5
|
||||
:END:
|
||||
#+BEGIN_SRC C++
|
||||
#include <opencv2/gapi.hpp>
|
||||
#include <opencv2/gapi/core.hpp>
|
||||
#include <opencv2/gapi/imgproc.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
using namespace cv;
|
||||
if (argc != 3) return 1;
|
||||
|
||||
GMat in;
|
||||
GMat gx = gapi::Sobel(in, CV_32F, 1, 0);
|
||||
GMat gy = gapi::Sobel(in, CV_32F, 0, 1);
|
||||
GMat mag = gapi::sqrt( gapi::mul(gx, gx)
|
||||
+ gapi::mul(gy, gy));
|
||||
GMat out = gapi::convertTo(mag, CV_8U);
|
||||
GComputation sobel(GIn(in), GOut(out));
|
||||
|
||||
Mat in_mat = imread(argv[1]), out_mat;
|
||||
sobel.apply(in_mat, out_mat);
|
||||
imwrite(argv[2], out_mat);
|
||||
return 0;
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
** The code is worth a thousand words (cont'd)
|
||||
# FIXME: sections!!!
|
||||
|
||||
*** What we have just learned?
|
||||
|
||||
- G-API functions mimic their traditional OpenCV ancestors;
|
||||
- No real data is required to construct a graph;
|
||||
- Graph construction and graph execution are separate steps.
|
||||
|
||||
*** What else?
|
||||
|
||||
- Graph is first /expressed/ and then /captured/ in an object;
|
||||
- Graph constructor defines /protocol/; user can pass vectors of
|
||||
inputs/outputs like
|
||||
#+BEGIN_SRC C++
|
||||
cv::GComputation(cv::GIn(...), cv::GOut(...))
|
||||
#+END_SRC
|
||||
- Calls to ~.apply()~ must conform to graph's protocol
|
||||
|
||||
** On data objects
|
||||
|
||||
Graph *protocol* defines what arguments a computation was defined on
|
||||
(both inputs and outputs), and what are the *shapes* (or types) of
|
||||
those arguments:
|
||||
|
||||
| *Shape* | *Argument* | Size |
|
||||
|--------------+------------------+-----------------------------|
|
||||
| ~GMat~ | ~Mat~ | Static; defined during |
|
||||
| | | graph compilation |
|
||||
|--------------+------------------+-----------------------------|
|
||||
| ~GScalar~ | ~Scalar~ | 4 x ~double~ |
|
||||
|--------------+------------------+-----------------------------|
|
||||
| ~GArray<T>~ | ~std::vector<T>~ | Dynamic; defined in runtime |
|
||||
|--------------+------------------+-----------------------------|
|
||||
| ~GOpaque<T>~ | ~T~ | Static, ~sizeof(T)~ |
|
||||
|
||||
~GScalar~ may be value-initialized at construction time to allow
|
||||
expressions like ~GMat a = 2*(b + 1)~.
|
||||
|
||||
** On operations and kernels
|
||||
:PROPERTIES:
|
||||
:BEAMER_opt: shrink=22
|
||||
:END:
|
||||
|
||||
*** :B_block:BMCOL:
|
||||
:PROPERTIES:
|
||||
:BEAMER_env: block
|
||||
:BEAMER_col: 0.45
|
||||
:END:
|
||||
|
||||
- Graphs are built with *Operations* over virtual *Data*;
|
||||
- *Operations* define interfaces (literally);
|
||||
- *Kernels* are implementations to *Operations* (like in OOP);
|
||||
- An *Operation* is platform-agnostic, a *kernel* is not;
|
||||
- *Kernels* are implemented for *Backends*, the latter provide
|
||||
APIs to write kernels;
|
||||
- Users can /add/ their *own* operations and kernels,
|
||||
and also /redefine/ "standard" kernels their *own* way.
|
||||
|
||||
*** :B_block:BMCOL:
|
||||
:PROPERTIES:
|
||||
:BEAMER_env: block
|
||||
:BEAMER_col: 0.45
|
||||
:END:
|
||||
|
||||
#+BEGIN_SRC dot :file "000-ops-kernels.eps" :cmdline "-Kdot -Teps"
|
||||
digraph G {
|
||||
node [shape=box];
|
||||
rankdir=BT;
|
||||
|
||||
Gr [label="Graph"];
|
||||
Op [label="Operation\nA"];
|
||||
{rank=same
|
||||
Impl1 [label="Kernel\nA:2"];
|
||||
Impl2 [label="Kernel\nA:1"];
|
||||
}
|
||||
|
||||
Op -> Gr [dir=back, label="'consists of'"];
|
||||
Impl1 -> Op [];
|
||||
Impl2 -> Op [label="'is implemented by'"];
|
||||
|
||||
node [shape=note,style=dashed];
|
||||
{rank=same
|
||||
Op;
|
||||
CommentOp [label="Abstract:\ndeclared via\nG_API_OP()"];
|
||||
}
|
||||
{rank=same
|
||||
Comment1 [label="Platform:\ndefined with\nOpenCL backend"];
|
||||
Comment2 [label="Platform:\ndefined with\nOpenCV backend"];
|
||||
}
|
||||
|
||||
CommentOp -> Op [constraint=false, style=dashed, arrowhead=none];
|
||||
Comment1 -> Impl1 [style=dashed, arrowhead=none];
|
||||
Comment2 -> Impl2 [style=dashed, arrowhead=none];
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
** On operations and kernels (cont'd)
|
||||
|
||||
*** Defining an operation
|
||||
|
||||
- A type name (every operation is a C++ type);
|
||||
- Operation signature (similar to ~std::function<>~);
|
||||
- Operation identifier (a string);
|
||||
- Metadata callback -- describe what is the output value format(s),
|
||||
given the input and arguments.
|
||||
- Use ~OpType::on(...)~ to use a new kernel ~OpType~ to construct graphs.
|
||||
|
||||
#+LaTeX: {\footnotesize
|
||||
#+BEGIN_SRC C++
|
||||
G_API_OP(GSqrt,<GMat(GMat)>,"org.opencv.core.math.sqrt") {
|
||||
static GMatDesc outMeta(GMatDesc in) { return in; }
|
||||
};
|
||||
#+END_SRC
|
||||
#+LaTeX: }
|
||||
|
||||
** On operations and kernels (cont'd)
|
||||
|
||||
*** ~GSqrt~ vs. ~cv::gapi::sqrt()~
|
||||
|
||||
- How a *type* relates to a *functions* from the example?
|
||||
- These functions are just wrappers over ~::on~:
|
||||
#+LaTeX: {\scriptsize
|
||||
#+BEGIN_SRC C++
|
||||
G_API_OP(GSqrt,<GMat(GMat)>,"org.opencv.core.math.sqrt") {
|
||||
static GMatDesc outMeta(GMatDesc in) { return in; }
|
||||
};
|
||||
GMat gapi::sqrt(const GMat& src) { return GSqrt::on(src); }
|
||||
#+END_SRC
|
||||
#+LaTeX: }
|
||||
- Why -- Doxygen, default parameters, 1:n mapping:
|
||||
#+LaTeX: {\scriptsize
|
||||
#+BEGIN_SRC C++
|
||||
cv::GMat custom::unsharpMask(const cv::GMat &src,
|
||||
const int sigma,
|
||||
const float strength) {
|
||||
cv::GMat blurred = cv::gapi::medianBlur(src, sigma);
|
||||
cv::GMat laplacian = cv::gapi::Laplacian(blurred, CV_8U);
|
||||
return (src - (laplacian * strength));
|
||||
}
|
||||
#+END_SRC
|
||||
#+LaTeX: }
|
||||
|
||||
** On operations and kernels (cont'd)
|
||||
|
||||
*** Implementing an operation
|
||||
|
||||
- Depends on the backend and its API;
|
||||
- Common part for all backends: refer to operation being implemented
|
||||
using its /type/.
|
||||
|
||||
*** OpenCV backend
|
||||
- OpenCV backend is the default one: OpenCV kernel is a wrapped OpenCV
|
||||
function:
|
||||
#+LaTeX: {\footnotesize
|
||||
#+BEGIN_SRC C++
|
||||
GAPI_OCV_KERNEL(GCPUSqrt, cv::gapi::core::GSqrt) {
|
||||
static void run(const cv::Mat& in, cv::Mat &out) {
|
||||
cv::sqrt(in, out);
|
||||
}
|
||||
};
|
||||
#+END_SRC
|
||||
#+LaTeX: }
|
||||
|
||||
** Operations and Kernels (cont'd)
|
||||
# FIXME!!!
|
||||
|
||||
*** Fluid backend
|
||||
|
||||
- Fluid backend operates with row-by-row kernels and schedules its
|
||||
execution to optimize data locality:
|
||||
#+LaTeX: {\footnotesize
|
||||
#+BEGIN_SRC C++
|
||||
GAPI_FLUID_KERNEL(GFluidSqrt, cv::gapi::core::GSqrt, false) {
|
||||
static const int Window = 1;
|
||||
static void run(const View &in, Buffer &out) {
|
||||
hal::sqrt32f(in .InLine <float>(0)
|
||||
out.OutLine<float>(0),
|
||||
out.length());
|
||||
}
|
||||
};
|
||||
#+END_SRC
|
||||
#+LaTeX: }
|
||||
- Note ~run~ changes signature but still is derived from the operation
|
||||
signature.
|
||||
|
||||
** Operations and Kernels (cont'd)
|
||||
|
||||
*** Specifying which kernels to use
|
||||
|
||||
- Graph execution model is defined by kernels which are available/used;
|
||||
- Kernels can be specified via the graph compilation arguments:
|
||||
#+LaTeX: {\footnotesize
|
||||
#+BEGIN_SRC C++
|
||||
#include <opencv2/gapi/fluid/core.hpp>
|
||||
#include <opencv2/gapi/fluid/imgproc.hpp>
|
||||
...
|
||||
auto pkg = cv::gapi::combine(cv::gapi::core::fluid::kernels(),
|
||||
cv::gapi::imgproc::fluid::kernels());
|
||||
sobel.apply(in_mat, out_mat, cv::compile_args(pkg));
|
||||
#+END_SRC
|
||||
#+LaTeX: }
|
||||
- Users can combine kernels of different backends and G-API will partition
|
||||
the execution among those automatically.
|
||||
|
||||
** Heterogeneity in G-API
|
||||
:PROPERTIES:
|
||||
:BEAMER_opt: shrink=35
|
||||
:END:
|
||||
*** Automatic subgraph partitioning in G-API
|
||||
*** :B_block:BMCOL:
|
||||
:PROPERTIES:
|
||||
:BEAMER_env: block
|
||||
:BEAMER_col: 0.18
|
||||
:END:
|
||||
|
||||
#+BEGIN_SRC dot :file "010-hetero-init.eps" :cmdline "-Kdot -Teps"
|
||||
digraph G {
|
||||
rankdir=TB;
|
||||
ranksep=0.3;
|
||||
|
||||
node [shape=box margin=0 height=0.25];
|
||||
A; B; C;
|
||||
|
||||
node [shape=ellipse];
|
||||
GMat0;
|
||||
GMat1;
|
||||
GMat2;
|
||||
GMat3;
|
||||
|
||||
GMat0 -> A -> GMat1 -> B -> GMat2;
|
||||
GMat2 -> C;
|
||||
GMat0 -> C -> GMat3
|
||||
|
||||
subgraph cluster {style=invis; A; GMat1; B; GMat2; C};
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
The initial graph: operations are not resolved yet.
|
||||
|
||||
*** :B_block:BMCOL:
|
||||
:PROPERTIES:
|
||||
:BEAMER_env: block
|
||||
:BEAMER_col: 0.18
|
||||
:END:
|
||||
|
||||
#+BEGIN_SRC dot :file "011-hetero-homo.eps" :cmdline "-Kdot -Teps"
|
||||
digraph G {
|
||||
rankdir=TB;
|
||||
ranksep=0.3;
|
||||
|
||||
node [shape=box margin=0 height=0.25];
|
||||
A; B; C;
|
||||
|
||||
node [shape=ellipse];
|
||||
GMat0;
|
||||
GMat1;
|
||||
GMat2;
|
||||
GMat3;
|
||||
|
||||
GMat0 -> A -> GMat1 -> B -> GMat2;
|
||||
GMat2 -> C;
|
||||
GMat0 -> C -> GMat3
|
||||
|
||||
subgraph cluster {style=filled;color=azure2; A; GMat1; B; GMat2; C};
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
All operations are handled by the same backend.
|
||||
|
||||
*** :B_block:BMCOL:
|
||||
:PROPERTIES:
|
||||
:BEAMER_env: block
|
||||
:BEAMER_col: 0.18
|
||||
:END:
|
||||
|
||||
#+BEGIN_SRC dot :file "012-hetero-a.eps" :cmdline "-Kdot -Teps"
|
||||
digraph G {
|
||||
rankdir=TB;
|
||||
ranksep=0.3;
|
||||
|
||||
node [shape=box margin=0 height=0.25];
|
||||
A; B; C;
|
||||
|
||||
node [shape=ellipse];
|
||||
GMat0;
|
||||
GMat1;
|
||||
GMat2;
|
||||
GMat3;
|
||||
|
||||
GMat0 -> A -> GMat1 -> B -> GMat2;
|
||||
GMat2 -> C;
|
||||
GMat0 -> C -> GMat3
|
||||
|
||||
subgraph cluster_1 {style=filled;color=azure2; A; GMat1; B; }
|
||||
subgraph cluster_2 {style=filled;color=ivory2; C};
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
~A~ & ~B~ are of backend ~1~, ~C~ is of backend ~2~.
|
||||
|
||||
*** :B_block:BMCOL:
|
||||
:PROPERTIES:
|
||||
:BEAMER_env: block
|
||||
:BEAMER_col: 0.18
|
||||
:END:
|
||||
|
||||
#+BEGIN_SRC dot :file "013-hetero-b.eps" :cmdline "-Kdot -Teps"
|
||||
digraph G {
|
||||
rankdir=TB;
|
||||
ranksep=0.3;
|
||||
|
||||
node [shape=box margin=0 height=0.25];
|
||||
A; B; C;
|
||||
|
||||
node [shape=ellipse];
|
||||
GMat0;
|
||||
GMat1;
|
||||
GMat2;
|
||||
GMat3;
|
||||
|
||||
GMat0 -> A -> GMat1 -> B -> GMat2;
|
||||
GMat2 -> C;
|
||||
GMat0 -> C -> GMat3
|
||||
|
||||
subgraph cluster_1 {style=filled;color=azure2; A};
|
||||
subgraph cluster_2 {style=filled;color=ivory2; B};
|
||||
subgraph cluster_3 {style=filled;color=azure2; C};
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
~A~ & ~C~ are of backend ~1~, ~B~ is of backend ~2~.
|
||||
|
||||
** Heterogeneity in G-API
|
||||
|
||||
*** Heterogeneity summary
|
||||
|
||||
- G-API automatically partitions its graph in subgraphs (called "islands")
|
||||
based on the available kernels;
|
||||
- Adjacent kernels taken from the same backend are "fused" into the same
|
||||
"island";
|
||||
- G-API implements a two-level execution model:
|
||||
- Islands are executed at the top level by a G-API's *Executor*;
|
||||
- Island internals are run at the bottom level by its *Backend*;
|
||||
- G-API fully delegates the low-level execution and memory management to backends.
|
||||
|
||||
* Inference and Streaming
|
||||
|
||||
** Inference with G-API
|
||||
|
||||
*** In-graph inference example
|
||||
|
||||
- Starting with OpencV 4.2 (2019), G-API allows to integrate ~infer~
|
||||
operations into the graph:
|
||||
#+LaTeX: {\scriptsize
|
||||
#+BEGIN_SRC C++
|
||||
G_API_NET(ObjDetect, <cv::GMat(cv::GMat)>, "pdf.example.od");
|
||||
|
||||
cv::GMat in;
|
||||
cv::GMat blob = cv::gapi::infer<ObjDetect>(bgr);
|
||||
cv::GOpaque<cv::Size> size = cv::gapi::streaming::size(bgr);
|
||||
cv::GArray<cv::Rect> objs = cv::gapi::streaming::parseSSD(blob, size);
|
||||
cv::GComputation pipelne(cv::GIn(in), cv::GOut(objs));
|
||||
#+END_SRC
|
||||
#+LaTeX: }
|
||||
- Starting with OpenCV 4.5 (2020), G-API will provide more streaming-
|
||||
and NN-oriented operations out of the box.
|
||||
|
||||
** Inference with G-API
|
||||
|
||||
*** What is the difference?
|
||||
|
||||
- ~ObjDetect~ is not an operation, ~cv::gapi::infer<T>~ is;
|
||||
- ~cv::gapi::infer<T>~ is a *generic* operation, where ~T=ObjDetect~ describes
|
||||
the calling convention:
|
||||
- How many inputs the network consumes,
|
||||
- How many outputs the network produces.
|
||||
- Inference data types are ~GMat~ only:
|
||||
- Representing an image, then preprocessed automatically;
|
||||
- Representing a blob (n-dimensional ~Mat~), then passed as-is.
|
||||
- Inference *backends* only need to implement a single generic operation ~infer~.
|
||||
|
||||
** Inference with G-API
|
||||
|
||||
*** But how does it run?
|
||||
|
||||
- Since ~infer~ is an *Operation*, backends may provide *Kernels* implenting it;
|
||||
- The only publicly available inference backend now is *OpenVINO™*:
|
||||
- Brings its ~infer~ kernel atop of the Inference Engine;
|
||||
- NN model data is passed through G-API compile arguments (like kernels);
|
||||
- Every NN backend provides its own structure to configure the network (like
|
||||
a kernel API).
|
||||
|
||||
** Inference with G-API
|
||||
|
||||
*** Passing OpenVINO™ parameters to G-API
|
||||
|
||||
- ~ObjDetect~ example:
|
||||
#+LaTeX: {\footnotesize
|
||||
#+BEGIN_SRC C++
|
||||
auto face_net = cv::gapi::ie::Params<ObjDetect> {
|
||||
face_xml_path, // path to the topology IR
|
||||
face_bin_path, // path to the topology weights
|
||||
face_device_string, // OpenVINO plugin (device) string
|
||||
};
|
||||
auto networks = cv::gapi::networks(face_net);
|
||||
pipeline.compile(.., cv::compile_args(..., networks));
|
||||
#+END_SRC
|
||||
#+LaTeX: }
|
||||
- ~AgeGender~ requires binding Op's outputs to NN layers:
|
||||
#+LaTeX: {\footnotesize
|
||||
#+BEGIN_SRC C++
|
||||
auto age_net = cv::gapi::ie::Params<AgeGender> {
|
||||
...
|
||||
}.cfgOutputLayers({"age_conv3", "prob"}); // array<string,2> !
|
||||
#+END_SRC
|
||||
#+LaTeX: }
|
||||
|
||||
** Streaming with G-API
|
||||
|
||||
#+BEGIN_SRC dot :file 020-fd-demo.eps :cmdline "-Kdot -Teps"
|
||||
digraph {
|
||||
rankdir=LR;
|
||||
node [shape=box];
|
||||
|
||||
cap [label=Capture];
|
||||
dec [label=Decode];
|
||||
res [label=Resize];
|
||||
cnn [label=Infer];
|
||||
vis [label=Visualize];
|
||||
|
||||
cap -> dec;
|
||||
dec -> res;
|
||||
res -> cnn;
|
||||
cnn -> vis;
|
||||
}
|
||||
#+END_SRC
|
||||
Anatomy of a regular video analytics application
|
||||
|
||||
** Streaming with G-API
|
||||
|
||||
#+BEGIN_SRC dot :file 021-fd-serial.eps :cmdline "-Kdot -Teps"
|
||||
digraph {
|
||||
node [shape=box margin=0 width=0.3 height=0.4]
|
||||
nodesep=0.2;
|
||||
rankdir=LR;
|
||||
|
||||
subgraph cluster0 {
|
||||
colorscheme=blues9
|
||||
pp [label="..." shape=plaintext];
|
||||
v0 [label=V];
|
||||
label="Frame N-1";
|
||||
color=7;
|
||||
}
|
||||
|
||||
subgraph cluster1 {
|
||||
colorscheme=blues9
|
||||
c1 [label=C];
|
||||
d1 [label=D];
|
||||
r1 [label=R];
|
||||
i1 [label=I];
|
||||
v1 [label=V];
|
||||
label="Frame N";
|
||||
color=6;
|
||||
}
|
||||
|
||||
subgraph cluster2 {
|
||||
colorscheme=blues9
|
||||
c2 [label=C];
|
||||
nn [label="..." shape=plaintext];
|
||||
label="Frame N+1";
|
||||
color=5;
|
||||
}
|
||||
|
||||
c1 -> d1 -> r1 -> i1 -> v1;
|
||||
|
||||
pp-> v0;
|
||||
v0 -> c1 [style=invis];
|
||||
v1 -> c2 [style=invis];
|
||||
c2 -> nn;
|
||||
}
|
||||
#+END_SRC
|
||||
Serial execution of the sample video analytics application
|
||||
|
||||
** Streaming with G-API
|
||||
:PROPERTIES:
|
||||
:BEAMER_opt: shrink
|
||||
:END:
|
||||
|
||||
#+BEGIN_SRC dot :file 022-fd-pipelined.eps :cmdline "-Kdot -Teps"
|
||||
digraph {
|
||||
nodesep=0.2;
|
||||
ranksep=0.2;
|
||||
node [margin=0 width=0.4 height=0.2];
|
||||
node [shape=plaintext]
|
||||
Camera [label="Camera:"];
|
||||
GPU [label="GPU:"];
|
||||
FPGA [label="FPGA:"];
|
||||
CPU [label="CPU:"];
|
||||
Time [label="Time:"];
|
||||
t6 [label="T6"];
|
||||
t7 [label="T7"];
|
||||
t8 [label="T8"];
|
||||
t9 [label="T9"];
|
||||
t10 [label="T10"];
|
||||
tnn [label="..."];
|
||||
|
||||
node [shape=box margin=0 width=0.4 height=0.4 colorscheme=blues9]
|
||||
node [color=9] V3;
|
||||
node [color=8] F4; V4;
|
||||
node [color=7] DR5; F5; V5;
|
||||
node [color=6] C6; DR6; F6; V6;
|
||||
node [color=5] C7; DR7; F7; V7;
|
||||
node [color=4] C8; DR8; F8;
|
||||
node [color=3] C9; DR9;
|
||||
node [color=2] C10;
|
||||
|
||||
{rank=same; rankdir=LR; Camera C6 C7 C8 C9 C10}
|
||||
Camera -> C6 -> C7 -> C8 -> C9 -> C10 [style=invis];
|
||||
|
||||
{rank=same; rankdir=LR; GPU DR5 DR6 DR7 DR8 DR9}
|
||||
GPU -> DR5 -> DR6 -> DR7 -> DR8 -> DR9 [style=invis];
|
||||
|
||||
C6 -> DR5 [style=invis];
|
||||
C6 -> DR6 [constraint=false];
|
||||
C7 -> DR7 [constraint=false];
|
||||
C8 -> DR8 [constraint=false];
|
||||
C9 -> DR9 [constraint=false];
|
||||
|
||||
{rank=same; rankdir=LR; FPGA F4 F5 F6 F7 F8}
|
||||
FPGA -> F4 -> F5 -> F6 -> F7 -> F8 [style=invis];
|
||||
|
||||
DR5 -> F4 [style=invis];
|
||||
DR5 -> F5 [constraint=false];
|
||||
DR6 -> F6 [constraint=false];
|
||||
DR7 -> F7 [constraint=false];
|
||||
DR8 -> F8 [constraint=false];
|
||||
|
||||
{rank=same; rankdir=LR; CPU V3 V4 V5 V6 V7}
|
||||
CPU -> V3 -> V4 -> V5 -> V6 -> V7 [style=invis];
|
||||
|
||||
F4 -> V3 [style=invis];
|
||||
F4 -> V4 [constraint=false];
|
||||
F5 -> V5 [constraint=false];
|
||||
F6 -> V6 [constraint=false];
|
||||
F7 -> V7 [constraint=false];
|
||||
|
||||
{rank=same; rankdir=LR; Time t6 t7 t8 t9 t10 tnn}
|
||||
Time -> t6 -> t7 -> t8 -> t9 -> t10 -> tnn [style=invis];
|
||||
|
||||
CPU -> Time [style=invis];
|
||||
V3 -> t6 [style=invis];
|
||||
V4 -> t7 [style=invis];
|
||||
V5 -> t8 [style=invis];
|
||||
V6 -> t9 [style=invis];
|
||||
V7 -> t10 [style=invis];
|
||||
}
|
||||
#+END_SRC
|
||||
Pipelined execution for the video analytics application
|
||||
|
||||
** Streaming with G-API: Example
|
||||
|
||||
**** Serial mode (4.0) :B_block:BMCOL:
|
||||
:PROPERTIES:
|
||||
:BEAMER_env: block
|
||||
:BEAMER_col: 0.45
|
||||
:END:
|
||||
#+LaTeX: {\tiny
|
||||
#+BEGIN_SRC C++
|
||||
pipeline = cv::GComputation(...);
|
||||
|
||||
cv::VideoCapture cap(input);
|
||||
cv::Mat in_frame;
|
||||
std::vector<cv::Rect> out_faces;
|
||||
|
||||
while (cap.read(in_frame)) {
|
||||
pipeline.apply(cv::gin(in_frame),
|
||||
cv::gout(out_faces),
|
||||
cv::compile_args(kernels,
|
||||
networks));
|
||||
// Process results
|
||||
...
|
||||
}
|
||||
#+END_SRC
|
||||
#+LaTeX: }
|
||||
|
||||
**** Streaming mode (since 4.2) :B_block:BMCOL:
|
||||
:PROPERTIES:
|
||||
:BEAMER_env: block
|
||||
:BEAMER_col: 0.45
|
||||
:END:
|
||||
#+LaTeX: {\tiny
|
||||
#+BEGIN_SRC C++
|
||||
pipeline = cv::GComputation(...);
|
||||
|
||||
auto in_src = cv::gapi::wip::make_src
|
||||
<cv::gapi::wip::GCaptureSource>(input)
|
||||
auto cc = pipeline.compileStreaming
|
||||
(cv::compile_args(kernels, networks))
|
||||
cc.setSource(cv::gin(in_src));
|
||||
cc.start();
|
||||
|
||||
std::vector<cv::Rect> out_faces;
|
||||
while (cc.pull(cv::gout(out_faces))) {
|
||||
// Process results
|
||||
...
|
||||
}
|
||||
#+END_SRC
|
||||
#+LaTeX: }
|
||||
|
||||
**** More information
|
||||
|
||||
#+LaTeX: {\footnotesize
|
||||
https://opencv.org/hybrid-cv-dl-pipelines-with-opencv-4-4-g-api/
|
||||
#+LaTeX: }
|
||||
|
||||
* Latest features
|
||||
** Latest features
|
||||
*** Python API
|
||||
|
||||
- Initial Python3 binding is available now in ~master~ (future 4.5);
|
||||
- Only basic CV functionality is supported (~core~ & ~imgproc~ namespaces,
|
||||
selecting backends);
|
||||
- Adding more programmability, inference, and streaming is next.
|
||||
|
||||
** Latest features
|
||||
*** Python API
|
||||
|
||||
#+LaTeX: {\footnotesize
|
||||
#+BEGIN_SRC Python
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
sz = (1280, 720)
|
||||
in1 = np.random.randint(0, 100, sz).astype(np.uint8)
|
||||
in2 = np.random.randint(0, 100, sz).astype(np.uint8)
|
||||
|
||||
g_in1 = cv.GMat()
|
||||
g_in2 = cv.GMat()
|
||||
g_out = cv.gapi.add(g_in1, g_in2)
|
||||
gr = cv.GComputation(g_in1, g_in2, g_out)
|
||||
|
||||
pkg = cv.gapi.core.fluid.kernels()
|
||||
out = gr.apply(in1, in2, args=cv.compile_args(pkg))
|
||||
#+END_SRC
|
||||
#+LaTeX: }
|
||||
|
||||
* Understanding the "G-Effect"
|
||||
|
||||
** Understanding the "G-Effect"
|
||||
|
||||
*** What is "G-Effect"?
|
||||
|
||||
- G-API is not only an API, but also an /implementation/;
|
||||
- i.e. it does some work already!
|
||||
- We call "G-Effect" any measurable improvement which G-API demonstrates
|
||||
against traditional methods;
|
||||
- So far the list is:
|
||||
- Memory consumption;
|
||||
- Performance;
|
||||
- Programmer efforts.
|
||||
|
||||
Note: in the following slides, all measurements are taken on
|
||||
Intel\textregistered{} Core\texttrademark-i5 6600 CPU.
|
||||
|
||||
** Understanding the "G-Effect"
|
||||
# FIXME
|
||||
|
||||
*** Memory consumption: Sobel Edge Detector
|
||||
|
||||
- G-API/Fluid backend is designed to minimize footprint:
|
||||
#+LaTeX: {\footnotesize
|
||||
| Input | OpenCV | G-API/Fluid | Factor |
|
||||
| | MiB | MiB | Times |
|
||||
|-------------+--------+-------------+--------|
|
||||
| 512 x 512 | 17.33 | 0.59 | 28.9x |
|
||||
| 640 x 480 | 20.29 | 0.62 | 32.8x |
|
||||
| 1280 x 720 | 60.73 | 0.72 | 83.9x |
|
||||
| 1920 x 1080 | 136.53 | 0.83 | 164.7x |
|
||||
| 3840 x 2160 | 545.88 | 1.22 | 447.4x |
|
||||
#+LaTeX: }
|
||||
- The detector itself can be written manually in two ~for~
|
||||
loops, but G-API covers cases more complex than that;
|
||||
- OpenCV code requires changes to shrink footprint.
|
||||
|
||||
** Understanding the "G-Effect"
|
||||
|
||||
*** Performance: Sobel Edge Detector
|
||||
|
||||
- G-API/Fluid backend also optimizes cache reuse:
|
||||
|
||||
#+LaTeX: {\footnotesize
|
||||
| Input | OpenCV | G-API/Fluid | Factor |
|
||||
| | ms | ms | Times |
|
||||
|-------------+--------+-------------+--------|
|
||||
| 320 x 240 | 1.16 | 0.53 | 2.17x |
|
||||
| 640 x 480 | 5.66 | 1.89 | 2.99x |
|
||||
| 1280 x 720 | 17.24 | 5.26 | 3.28x |
|
||||
| 1920 x 1080 | 39.04 | 12.29 | 3.18x |
|
||||
| 3840 x 2160 | 219.57 | 51.22 | 4.29x |
|
||||
#+LaTeX: }
|
||||
|
||||
- The more data is processed, the bigger "G-Effect" is.
|
||||
|
||||
** Understanding the "G-Effect"
|
||||
|
||||
*** Relative speed-up based on cache efficiency
|
||||
|
||||
#+BEGIN_LATEX
|
||||
\begin{figure}
|
||||
\begin{tikzpicture}
|
||||
\begin{axis}[
|
||||
xlabel={Image size},
|
||||
ylabel={Relative speed-up},
|
||||
nodes near coords,
|
||||
width=0.8\textwidth,
|
||||
xtick=data,
|
||||
xticklabels={QVGA, VGA, HD, FHD, UHD},
|
||||
height=4.5cm,
|
||||
]
|
||||
|
||||
\addplot plot coordinates {(1, 1.0) (2, 1.38) (3, 1.51) (4, 1.46) (5, 1.97)};
|
||||
|
||||
\end{axis}
|
||||
\end{tikzpicture}
|
||||
\end{figure}
|
||||
#+END_LATEX
|
||||
|
||||
The higher resolution is, the higher relative speed-up is (with
|
||||
speed-up on QVGA taken as 1.0).
|
||||
|
||||
* Resources on G-API
|
||||
|
||||
** Resources on G-API
|
||||
:PROPERTIES:
|
||||
:BEAMER_opt: shrink
|
||||
:END:
|
||||
*** Repository
|
||||
|
||||
- https://github.com/opencv/opencv (see ~modules/gapi~)
|
||||
|
||||
*** Article
|
||||
|
||||
- https://opencv.org/hybrid-cv-dl-pipelines-with-opencv-4-4-g-api/
|
||||
|
||||
*** Documentation
|
||||
|
||||
- https://docs.opencv.org/4.4.0/d0/d1e/gapi.html
|
||||
|
||||
*** Tutorials
|
||||
- https://docs.opencv.org/4.4.0/df/d7e/tutorial_table_of_content_gapi.html
|
||||
|
||||
* Thank you!
|
25
3rdparty/opencv-4.5.4/modules/gapi/doc/slides/get_sty.sh
vendored
Executable file
25
3rdparty/opencv-4.5.4/modules/gapi/doc/slides/get_sty.sh
vendored
Executable file
@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
set -e
|
||||
|
||||
MTHEME_VER=2fa6084b9d34fec9d2d5470eb9a17d0bf712b6c8
|
||||
MTHEME_DIR=mtheme.sty
|
||||
|
||||
function make_sty {
|
||||
if [ -d "$MTHEME_DIR" ]; then rm -rf "$MTHEME_DIR"; fi
|
||||
mkdir "$MTHEME_DIR"
|
||||
|
||||
# Download template from Github
|
||||
tmp_dir=$(mktemp -d)
|
||||
wget -P "$tmp_dir" -c https://github.com/matze/mtheme/archive/${MTHEME_VER}.tar.gz
|
||||
pushd "$tmp_dir"
|
||||
tar -xzvf "$MTHEME_VER.tar.gz"
|
||||
popd
|
||||
make -C "$tmp_dir"/mtheme-"$MTHEME_VER"
|
||||
cp -v "$tmp_dir"/mtheme-"$MTHEME_VER"/*.sty "$MTHEME_DIR"
|
||||
rm -r "$tmp_dir"
|
||||
# Put our own .gitignore to ignore this directory completely
|
||||
echo "*" > "$MTHEME_DIR/.gitignore"
|
||||
}
|
||||
|
||||
make_sty
|
181
3rdparty/opencv-4.5.4/modules/gapi/doc/slides/ocv_logo.eps
vendored
Normal file
181
3rdparty/opencv-4.5.4/modules/gapi/doc/slides/ocv_logo.eps
vendored
Normal file
@ -0,0 +1,181 @@
|
||||
%!PS-Adobe-3.0 EPSF-3.0
|
||||
%%Creator: cairo 1.14.6 (http://cairographics.org)
|
||||
%%CreationDate: Wed Dec 12 17:03:17 2018
|
||||
%%Pages: 1
|
||||
%%DocumentData: Clean7Bit
|
||||
%%LanguageLevel: 2
|
||||
%%BoundingBox: 0 -1 598 739
|
||||
%%EndComments
|
||||
%%BeginProlog
|
||||
save
|
||||
50 dict begin
|
||||
/q { gsave } bind def
|
||||
/Q { grestore } bind def
|
||||
/cm { 6 array astore concat } bind def
|
||||
/w { setlinewidth } bind def
|
||||
/J { setlinecap } bind def
|
||||
/j { setlinejoin } bind def
|
||||
/M { setmiterlimit } bind def
|
||||
/d { setdash } bind def
|
||||
/m { moveto } bind def
|
||||
/l { lineto } bind def
|
||||
/c { curveto } bind def
|
||||
/h { closepath } bind def
|
||||
/re { exch dup neg 3 1 roll 5 3 roll moveto 0 rlineto
|
||||
0 exch rlineto 0 rlineto closepath } bind def
|
||||
/S { stroke } bind def
|
||||
/f { fill } bind def
|
||||
/f* { eofill } bind def
|
||||
/n { newpath } bind def
|
||||
/W { clip } bind def
|
||||
/W* { eoclip } bind def
|
||||
/BT { } bind def
|
||||
/ET { } bind def
|
||||
/pdfmark where { pop globaldict /?pdfmark /exec load put }
|
||||
{ globaldict begin /?pdfmark /pop load def /pdfmark
|
||||
/cleartomark load def end } ifelse
|
||||
/BDC { mark 3 1 roll /BDC pdfmark } bind def
|
||||
/EMC { mark /EMC pdfmark } bind def
|
||||
/cairo_store_point { /cairo_point_y exch def /cairo_point_x exch def } def
|
||||
/Tj { show currentpoint cairo_store_point } bind def
|
||||
/TJ {
|
||||
{
|
||||
dup
|
||||
type /stringtype eq
|
||||
{ show } { -0.001 mul 0 cairo_font_matrix dtransform rmoveto } ifelse
|
||||
} forall
|
||||
currentpoint cairo_store_point
|
||||
} bind def
|
||||
/cairo_selectfont { cairo_font_matrix aload pop pop pop 0 0 6 array astore
|
||||
cairo_font exch selectfont cairo_point_x cairo_point_y moveto } bind def
|
||||
/Tf { pop /cairo_font exch def /cairo_font_matrix where
|
||||
{ pop cairo_selectfont } if } bind def
|
||||
/Td { matrix translate cairo_font_matrix matrix concatmatrix dup
|
||||
/cairo_font_matrix exch def dup 4 get exch 5 get cairo_store_point
|
||||
/cairo_font where { pop cairo_selectfont } if } bind def
|
||||
/Tm { 2 copy 8 2 roll 6 array astore /cairo_font_matrix exch def
|
||||
cairo_store_point /cairo_font where { pop cairo_selectfont } if } bind def
|
||||
/g { setgray } bind def
|
||||
/rg { setrgbcolor } bind def
|
||||
/d1 { setcachedevice } bind def
|
||||
%%EndProlog
|
||||
%%BeginSetup
|
||||
%%EndSetup
|
||||
%%Page: 1 1
|
||||
%%BeginPageSetup
|
||||
%%PageBoundingBox: 0 -1 598 739
|
||||
%%EndPageSetup
|
||||
q 0 -1 598 740 rectclip q
|
||||
1 0.00392157 0.00392157 rg
|
||||
225.648 478.363 m 171.051 509.887 144.43 574.156 160.746 635.051 c 177.066
|
||||
695.945 232.254 738.277 295.301 738.277 c 358.348 738.277 413.535 695.945
|
||||
429.855 635.051 c 446.172 574.156 419.551 509.887 364.949 478.363 c 323.008
|
||||
551.008 l 344.73 563.547 355.324 589.117 348.832 613.34 c 342.34 637.566
|
||||
320.383 654.41 295.301 654.41 c 270.219 654.41 248.262 637.566 241.77 613.34
|
||||
c 235.277 589.117 245.871 563.547 267.59 551.008 c h
|
||||
225.648 478.363 m f
|
||||
0.00392157 0.00392157 1 rg
|
||||
523.949 444.637 m 578.551 413.113 605.172 348.844 588.855 287.949 c 572.535
|
||||
227.055 517.348 184.723 454.301 184.723 c 391.254 184.723 336.066 227.055
|
||||
319.746 287.949 c 303.43 348.844 330.051 413.113 384.648 444.637 c 426.59
|
||||
371.992 l 404.871 359.453 394.277 333.883 400.77 309.66 c 407.262 285.434
|
||||
429.219 268.59 454.301 268.59 c 479.383 268.59 501.34 285.434 507.832 309.66
|
||||
c 514.324 333.883 503.73 359.453 482.008 371.992 c h
|
||||
523.949 444.637 m f
|
||||
0.00392157 1 0.00392157 rg
|
||||
278.602 324 m 278.602 260.953 236.254 205.762 175.359 189.449 c 114.461
|
||||
173.133 50.207 199.762 18.684 254.363 c -12.84 308.961 -3.773 377.922 40.805
|
||||
422.504 c 85.383 467.082 154.352 476.164 208.949 444.637 c 167.008 371.992
|
||||
l 145.289 384.535 117.852 380.922 100.117 363.188 c 82.383 345.453 78.773
|
||||
318.016 91.316 296.297 c 103.855 274.574 129.418 263.98 153.645 270.473
|
||||
c 177.871 276.961 194.719 298.918 194.719 324 c h
|
||||
278.602 324 m f
|
||||
0.0196078 g
|
||||
39.781 151.301 m 51.57 152.359 63.492 152.352 75.223 150.672 c 82.449 149.391
|
||||
90.121 147.52 95.551 142.25 c 101.242 135.898 102.641 127.078 103.891 118.949
|
||||
c 105.941 102.078 105.699 84.969 103.891 68.09 c 102.68 59.852 101.492
|
||||
50.949 96.09 44.25 c 90.199 38.27 81.5 36.57 73.52 35.309 c 61.742 33.84
|
||||
49.789 33.5 37.961 34.68 c 29.949 35.5 21.59 36.91 14.77 41.48 c 10.359
|
||||
44.281 7.992 49.219 6.379 54.012 c 3.152 63.988 2.742 74.59 2.301 84.988
|
||||
c 2.25 98.73 2.512 112.609 5.191 126.129 c 6.641 132.441 8.402 139.379
|
||||
13.73 143.59 c 21.242 149.039 30.789 150.359 39.781 151.301 c h
|
||||
41.73 132.469 m 51.723 133.27 61.922 133.512 71.801 131.57 c 75.629 130.801
|
||||
80.152 128.941 80.871 124.578 c 83.871 112.309 83.172 99.531 83.289 86.988
|
||||
c 82.922 78.07 83.129 68.852 80.141 60.309 c 77.531 54.699 70.422 54.238
|
||||
65.062 53.422 c 54.312 52.809 43.152 52.27 32.723 55.461 c 27.91 56.73
|
||||
26.391 61.891 25.652 66.219 c 23.652 79.051 24.301 92.102 24.551 105.031
|
||||
c 25.082 112.281 24.992 119.801 27.602 126.691 c 30.59 131.309 36.77 131.719
|
||||
41.73 132.469 c h
|
||||
41.73 132.469 m f*
|
||||
147.07 112.219 m 154.23 116.77 163.121 117.512 171.379 116.762 c 179.09
|
||||
116.102 187.652 113.48 191.781 106.379 c 196.711 97.469 196.992 86.941
|
||||
197.332 77 c 197.109 66.781 196.922 56.109 192.699 46.609 c 190.289 40.84
|
||||
184.75 37.059 178.82 35.57 c 169.742 33.34 159.762 33.102 151.012 36.719
|
||||
c 146.281 38.57 143.012 42.59 140.301 46.711 c 140.301 0 l 120.301 0 l
|
||||
120.312 38.66 120.281 77.328 120.312 115.988 c 126.781 116.02 133.25 116.02
|
||||
139.711 115.988 c 139.492 112.012 139.27 108.039 139.16 104.051 c 141.562
|
||||
106.98 143.789 110.199 147.07 112.219 c h
|
||||
153.582 101.781 m 159.18 102.211 165.102 102.328 170.34 100.02 c 173.66
|
||||
98.59 175.41 95.078 176 91.68 c 177.742 82.91 177.52 73.852 176.902 64.969
|
||||
c 176.281 59.609 175.422 52.672 169.52 50.59 c 162.699 48.359 154.922 48.219
|
||||
148.18 50.828 c 141.91 53.469 141.18 61.059 140.562 66.949 c 140.191 75.988
|
||||
139.742 85.289 142.289 94.07 c 143.641 99.051 148.82 101.41 153.582 101.781
|
||||
c h
|
||||
153.582 101.781 m f*
|
||||
221.262 112.07 m 231.09 117.121 242.602 117.301 253.391 116.789 c 262.371
|
||||
116.039 273.27 114.539 278.223 105.949 c 283.801 95.578 282.891 83.379
|
||||
283.672 72 c 228.961 72 l 229.602 66.129 228.84 59.801 231.801 54.422 c
|
||||
234.332 50.172 239.699 49.301 244.242 49.051 c 249.852 49.012 255.891 48.551
|
||||
261.062 51.16 c 264.02 53.48 264.039 57.602 264.422 61 c 270.82 61.012
|
||||
277.223 61.012 283.621 61 c 283.379 54.32 282.52 46.84 277.16 42.141 c 269.109
|
||||
34.922 257.59 34.172 247.289 33.969 c 238.199 34.238 228.602 34.699 220.461
|
||||
39.18 c 213.871 43.07 211.77 51.059 210.609 58.102 c 209.141 68.559 208.77
|
||||
79.219 210.02 89.719 c 211.039 98.012 213.27 107.762 221.262 112.07 c h
|
||||
232.949 99.34 m 238.41 102.66 245.172 101.988 251.301 101.898 c 255.102
|
||||
101.488 259.73 101.27 262.199 97.91 c 264.723 93.762 264.27 88.68 264.289
|
||||
84.02 c 252.52 84 240.762 83.969 229 84.031 c 229.18 89.211 228.77 95.531
|
||||
232.949 99.34 c h
|
||||
232.949 99.34 m f*
|
||||
326.262 112.121 m 333.18 116.922 342.121 117.59 350.262 116.648 c 357.191
|
||||
115.922 364.531 113.281 368.621 107.301 c 372.25 102.34 373.262 96.02 373.312
|
||||
90.012 c 373.281 71.672 373.32 53.34 373.301 35 c 366.961 34.988 360.629
|
||||
34.988 354.312 35 c 354.281 52.352 354.332 69.691 354.281 87.031 c 354.09
|
||||
90.82 354.242 95.199 351.391 98.121 c 348.352 101.41 343.582 102.051 339.332
|
||||
102.02 c 334.191 102.051 328.629 101.172 324.672 97.621 c 320.801 94.32
|
||||
319.332 89 319.312 84.078 c 319.281 67.719 319.32 51.359 319.289 35.012
|
||||
c 312.961 34.988 306.629 34.988 300.312 35 c 300.301 62 300.301 89 300.312
|
||||
116 c 306.531 116.02 312.762 116.012 318.98 116 c 318.949 111.262 318.48
|
||||
106.551 318.34 101.809 c 320.379 105.641 322.52 109.68 326.262 112.121
|
||||
c h
|
||||
326.262 112.121 m f*
|
||||
407.691 147.602 m 418.172 151.121 429.34 151.621 440.301 152.012 c 450.922
|
||||
151.961 462.02 151.859 471.941 147.578 c 476.98 145.48 480.473 140.879
|
||||
482.172 135.801 c 484.941 128.211 485.02 119.988 485.082 112 c 477.77 112
|
||||
470.461 111.98 463.16 112.012 c 463.039 117.629 463.473 123.93 459.992
|
||||
128.711 c 456.473 132.309 450.973 132.301 446.301 132.852 c 436.801 133.031
|
||||
426.91 133.641 417.812 130.359 c 414.531 129.32 412.832 126.039 412.172
|
||||
122.879 c 410.301 114.398 410.289 105.648 410.301 97 c 410.41 85.441 410.23
|
||||
73.711 412.699 62.34 c 413.352 58.18 417.18 55.621 421.02 54.699 c 429.902
|
||||
52.488 439.172 52.809 448.242 53.352 c 452.973 53.969 458.73 54.281 461.699
|
||||
58.621 c 464.871 63.801 464.34 70.172 464.172 75.988 c 471.551 76.02 478.922
|
||||
76.012 486.301 75.988 c 486.211 66.801 486.051 57.309 482.711 48.609 c
|
||||
480.992 44.059 477.441 40.199 472.84 38.461 c 463.812 34.84 453.91 34.609
|
||||
444.332 34.031 c 433.223 33.84 421.973 34.109 411.109 36.699 c 404.742
|
||||
38.359 397.781 41.281 394.832 47.609 c 391.062 55.98 390.371 65.289 389.402
|
||||
74.301 c 388.59 86.199 388.07 98.121 388.359 110.039 c 388.93 119.691 389.812
|
||||
129.859 395.02 138.27 c 397.789 142.949 402.652 145.879 407.691 147.602
|
||||
c h
|
||||
407.691 147.602 m f*
|
||||
489.902 150.969 m 497.52 150.961 505.141 151.18 512.75 150.859 c 520.16
|
||||
127.352 528.301 104.078 535.781 80.602 c 538.691 71.578 540.75 62.301 543.762
|
||||
53.309 c 547.129 63.012 549.289 73.09 552.59 82.809 c 559.902 105.52 567.41
|
||||
128.16 574.711 150.871 c 582.23 151.191 589.77 150.91 597.301 151.012 c
|
||||
597.301 148.52 l 584.922 110.789 572.832 72.961 560.699 35.141 c 549.379
|
||||
34.91 538.039 34.879 526.723 35.16 c 514.66 73.828 502.02 112.32 489.902
|
||||
150.969 c h
|
||||
489.902 150.969 m f*
|
||||
Q Q
|
||||
showpage
|
||||
%%Trailer
|
||||
end restore
|
||||
%%EOF
|
Reference in New Issue
Block a user