Merge pull request #16066 from dmatveev:dm/gapi_slides
authorDmitry Matveev <dmitry.matveev@intel.com>
Thu, 12 Dec 2019 15:48:38 +0000 (18:48 +0300)
committerAlexander Alekhin <alexander.a.alekhin@gmail.com>
Thu, 12 Dec 2019 15:48:38 +0000 (18:48 +0300)
* G-API: Added G-API Overview slides & its source code

- Sample code snippets are moved to separate files;
- Introduced a separate benchmark to measure Fluid/OpenCV
  performance;
- Added notes on API changes (it is still a 4.0, not a 4.2 talk!)
- Added a "Metropolis" beamer download-n-build script.

* G-API: Addressed review issues on G-API overview slides

modules/gapi/doc/slides/.gitignore [new file with mode: 0644]
modules/gapi/doc/slides/README.md [new file with mode: 0644]
modules/gapi/doc/slides/gapi_overview.org [new file with mode: 0644]
modules/gapi/doc/slides/get_sty.sh [new file with mode: 0755]
modules/gapi/doc/slides/ocv_logo.eps [new file with mode: 0644]
modules/gapi/perf/cpu/gapi_core_perf_tests_cpu.cpp
modules/gapi/perf/perf_bench.cpp [new file with mode: 0644]
modules/gapi/samples/slides_sobel_cv.cpp [new file with mode: 0644]
modules/gapi/samples/slides_sobel_gapi.cpp [new file with mode: 0644]

diff --git a/modules/gapi/doc/slides/.gitignore b/modules/gapi/doc/slides/.gitignore
new file mode 100644 (file)
index 0000000..309f68f
--- /dev/null
@@ -0,0 +1,6 @@
+*.bbl
+*.blg
+*.sty
+*.tex
+*-converted-to.pdf
+mtheme.sty/
diff --git a/modules/gapi/doc/slides/README.md b/modules/gapi/doc/slides/README.md
new file mode 100644 (file)
index 0000000..3c81e24
--- /dev/null
@@ -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
diff --git a/modules/gapi/doc/slides/gapi_overview.org b/modules/gapi/doc/slides/gapi_overview.org
new file mode 100644 (file)
index 0000000..97415ba
--- /dev/null
@@ -0,0 +1,398 @@
+#+TITLE:     OpenCV 4.0 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.0 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).
+
+** 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;
+  - Increasing 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/?
+
+** A 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
+
+** A 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 |
+
+~GScalar~ may be value-initialized at construction time to allow
+  expressions like ~GMat a = 2*(b + 1)~.
+
+** Customization example
+
+*** Tuning the execution
+
+- Graph execution model is defined by kernels which are used;
+- Kernels can be specified in graph compilation arguments:
+  #+LaTeX: {\footnotesize
+  #+BEGIN_SRC C++
+  #include <opencv2/gapi/fluid/core.hpp>
+  #include <opencv2/gapi/fluid/imgproc.hpp>
+  ...
+  auto pkg = gapi::combine(gapi::core::fluid::kernels(),
+                           gapi::imgproc::fluid::kernels(),
+                           cv::unite_policy::KEEP);
+  sobel.apply(in_mat, out_mat, compile_args(pkg));
+  #+END_SRC
+  #+LaTeX: }
+- OpenCL backend can be used in the same way;
+  #+LaTeX: {\footnotesize
+- *NOTE*: ~cv::unite_policy~ has been removed in OpenCV 4.1.1.
+  #+LaTeX: }
+
+** Operations and Kernels
+
+*** Specifying a kernel package
+
+- A *kernel* is an implementation of *operation* (= interface);
+- A *kernel package* hosts kernels that G-API should use;
+- Kernels are written for different *backends* and using their APIs;
+- Two kernel packages can be *merged* into a single one;
+- User can safely supply his *own kernels* to either /replace/ or
+  /augment/ the default package.
+  - Yes, even the standard kernels can be /overwritten/ by user from
+    the outside!
+- *Heterogeneous* kernel package hosts kernels of different backends.
+
+** Operations and Kernels (cont'd)
+# FIXME!!!
+
+*** Defining an operation
+
+- A type name (every operation is a C++ type);
+- Operation signature (similar to ~std::function<>~);
+- Operation identifier (a string);
+- Metadata callback -- desribe 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_TYPED_KERNEL(GSqrt,<GMat(GMat)>,"org.opencv.core.math.sqrt") {
+    static GMatDesc outMeta(GMatDesc in) { return in; }
+};
+#+END_SRC
+#+LaTeX: }
+
+** Operations and Kernels (cont'd)
+# FIXME!!!
+
+*** 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.
+
+* 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
+
+*** Repository
+
+- https://github.com/opencv/opencv (see ~modules/gapi~)
+- Integral part of OpenCV starting version 4.0;
+
+*** Documentation
+
+- https://docs.opencv.org/master/d0/d1e/gapi.html
+- A tutorial and a class reference are there as well.
+
+* Thank you!
diff --git a/modules/gapi/doc/slides/get_sty.sh b/modules/gapi/doc/slides/get_sty.sh
new file mode 100755 (executable)
index 0000000..0b97cf3
--- /dev/null
@@ -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
diff --git a/modules/gapi/doc/slides/ocv_logo.eps b/modules/gapi/doc/slides/ocv_logo.eps
new file mode 100644 (file)
index 0000000..67005bd
--- /dev/null
@@ -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
index 8275642..9f90d73 100644 (file)
@@ -288,4 +288,4 @@ INSTANTIATE_TEST_CASE_P(ResizeFxFyPerfTestCPU, ResizeFxFyPerfTest,
         Values(0.5, 0.1),
         Values(0.5, 0.1),
         Values(cv::compile_args(CORE_CPU))));
-}
+} // opencv_test
diff --git a/modules/gapi/perf/perf_bench.cpp b/modules/gapi/perf/perf_bench.cpp
new file mode 100644 (file)
index 0000000..5084245
--- /dev/null
@@ -0,0 +1,88 @@
+#include "perf_precomp.hpp"
+#include "../test/common/gapi_tests_common.hpp"
+
+namespace opencv_test
+{
+
+struct SobelEdgeDetector:  public TestPerfParams<cv::Size> {};
+PERF_TEST_P_(SobelEdgeDetector, Fluid)
+{
+    Size sz = GetParam();
+    initMatsRandU(CV_8UC3, sz, CV_8UC3, false);
+
+    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(in, out);
+    auto pkg = gapi::combine(gapi::core::fluid::kernels(),
+                             gapi::imgproc::fluid::kernels());
+    auto cc = sobel.compile(cv::descr_of(in_mat1),
+                            cv::compile_args(cv::gapi::use_only{pkg}));
+    cc(in_mat1, out_mat_gapi);
+
+    TEST_CYCLE()
+    {
+        cc(in_mat1, out_mat_gapi);
+    }
+    SANITY_CHECK_NOTHING();
+}
+PERF_TEST_P_(SobelEdgeDetector, OpenCV)
+{
+    Size sz = GetParam();
+    initMatsRandU(CV_8UC3, sz, CV_8UC3, false);
+
+    Mat gx, gy;
+    Mat mag;
+    auto cc = [&](const cv::Mat &in_mat, cv::Mat &out_mat) {
+        using namespace cv;
+
+        Sobel(in_mat, gx, CV_32F, 1, 0);
+        Sobel(in_mat, gy, CV_32F, 0, 1);
+        sqrt(gx.mul(gx) + gy.mul(gy), mag);
+        mag.convertTo(out_mat, CV_8U);
+    };
+    cc(in_mat1, out_mat_gapi);
+
+    TEST_CYCLE()
+    {
+        cc(in_mat1, out_mat_gapi);
+    }
+    SANITY_CHECK_NOTHING();
+}
+PERF_TEST_P_(SobelEdgeDetector, OpenCV_Smarter)
+{
+    Size sz = GetParam();
+    initMatsRandU(CV_8UC3, sz, CV_8UC3, false);
+
+    Mat gx, gy;
+    Mat ggx, ggy;
+    Mat sum;
+    Mat mag;
+
+    auto cc = [&](const cv::Mat &in_mat, cv::Mat &out_mat) {
+        cv::Sobel(in_mat, gx, CV_32F, 1, 0);
+        cv::Sobel(in_mat, gy, CV_32F, 0, 1);
+        cv::multiply(gx, gx, ggx);
+        cv::multiply(gy, gy, ggy);
+        cv::add(ggx, ggy, sum);
+        cv::sqrt(sum, mag);
+        mag.convertTo(out_mat, CV_8U);
+    };
+    cc(in_mat1, out_mat_gapi);
+
+    TEST_CYCLE()
+    {
+        cc(in_mat1, out_mat_gapi);
+    }
+    SANITY_CHECK_NOTHING();
+}
+INSTANTIATE_TEST_CASE_P(Benchmark, SobelEdgeDetector,
+                        Values(cv::Size(320, 240),
+                               cv::Size(640, 480),
+                               cv::Size(1280, 720),
+                               cv::Size(1920, 1080),
+                               cv::Size(3840, 2170)));
+
+} // opencv_test
diff --git a/modules/gapi/samples/slides_sobel_cv.cpp b/modules/gapi/samples/slides_sobel_cv.cpp
new file mode 100644 (file)
index 0000000..fd2f27c
--- /dev/null
@@ -0,0 +1,27 @@
+#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[])
+{
+    (void) argc;
+    (void) argv;
+
+    using namespace cv;
+    Mat in_mat = imread("lena.png");
+    Mat gx, gy;
+
+    Sobel(in_mat, gx, CV_32F, 1, 0);
+    Sobel(in_mat, gy, CV_32F, 0, 1);
+
+    Mat mag;
+    sqrt(gx.mul(gx) + gy.mul(gy), mag);
+
+    Mat out_mat;
+    mag.convertTo(out_mat, CV_8U);
+
+    imwrite("lena-out.png", out_mat);
+    return 0;
+}
diff --git a/modules/gapi/samples/slides_sobel_gapi.cpp b/modules/gapi/samples/slides_sobel_gapi.cpp
new file mode 100644 (file)
index 0000000..e928579
--- /dev/null
@@ -0,0 +1,28 @@
+#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[])
+{
+    (void) argc;
+    (void) argv;
+
+    using namespace cv;
+    Mat in_mat = imread("lena.png");
+    Mat out_mat;
+
+    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));
+    sobel.apply(in_mat, out_mat);
+
+    imwrite("lena-out.png", out_mat);
+    return 0;
+}