Skip to content

Commit 2d69dd1

Browse files
authored
Merge pull request #3827 from asmorkalov:as/gapi_migration
Migrate G-API module from main repo to opencv_contrib #3827 Related to opencv/opencv#26469 Required opencv/opencv#26527 CI: opencv/ci-gha-workflow#201 TODO: - [x] Python types generator fix - [x] CI update ### Pull Request Readiness Checklist See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request - [x] I agree to contribute to the project under Apache 2 License. - [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV - [ ] The PR is proposed to the proper branch - [ ] There is a reference to the original bug report and related work - [ ] There is accuracy test, performance test and test data in opencv_extra repository, if applicable Patch to opencv_extra has the same branch name. - [ ] The feature is well documented and sample code can be built with the project CMake
1 parent af0b94e commit 2d69dd1

File tree

588 files changed

+153065
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

588 files changed

+153065
-0
lines changed

modules/gapi/CMakeLists.txt

Lines changed: 440 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
set(ade_src_dir "${OpenCV_BINARY_DIR}/3rdparty/ade")
2+
set(ade_filename "v0.1.2e.zip")
3+
set(ade_subdir "ade-0.1.2e")
4+
set(ade_md5 "962ce79e0b95591f226431f7b5f152cd")
5+
ocv_download(FILENAME ${ade_filename}
6+
HASH ${ade_md5}
7+
URL
8+
"${OPENCV_ADE_URL}"
9+
"$ENV{OPENCV_ADE_URL}"
10+
"https://github.com/opencv/ade/archive/"
11+
DESTINATION_DIR ${ade_src_dir}
12+
ID ADE
13+
STATUS res
14+
UNPACK RELATIVE_URL)
15+
16+
if (NOT res)
17+
return()
18+
endif()
19+
20+
set(ADE_root "${ade_src_dir}/${ade_subdir}/sources/ade")
21+
file(GLOB_RECURSE ADE_sources "${ADE_root}/source/*.cpp")
22+
file(GLOB_RECURSE ADE_include "${ADE_root}/include/ade/*.hpp")
23+
add_library(ade STATIC ${OPENCV_3RDPARTY_EXCLUDE_FROM_ALL}
24+
${ADE_include}
25+
${ADE_sources}
26+
)
27+
28+
# https://github.com/opencv/ade/issues/32
29+
if(CV_CLANG AND CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang" AND NOT CMAKE_CXX_COMPILER_VERSION VERSION_LESS 13.1)
30+
ocv_warnings_disable(CMAKE_CXX_FLAGS -Wdeprecated-copy)
31+
endif()
32+
33+
target_include_directories(ade PUBLIC $<BUILD_INTERFACE:${ADE_root}/include>)
34+
set_target_properties(ade PROPERTIES
35+
POSITION_INDEPENDENT_CODE True
36+
OUTPUT_NAME ade
37+
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
38+
COMPILE_PDB_NAME ade
39+
COMPILE_PDB_NAME_DEBUG "ade${OPENCV_DEBUG_POSTFIX}"
40+
ARCHIVE_OUTPUT_DIRECTORY ${3P_LIBRARY_OUTPUT_PATH}
41+
)
42+
43+
if(ENABLE_SOLUTION_FOLDERS)
44+
set_target_properties(ade PROPERTIES FOLDER "3rdparty")
45+
endif()
46+
47+
if(NOT BUILD_SHARED_LIBS)
48+
ocv_install_target(ade EXPORT OpenCVModules ARCHIVE DESTINATION ${OPENCV_3P_LIB_INSTALL_PATH} COMPONENT dev OPTIONAL)
49+
endif()
50+
51+
ocv_install_3rdparty_licenses(ade "${ade_src_dir}/${ade_subdir}/LICENSE")

modules/gapi/cmake/init.cmake

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
OCV_OPTION(WITH_ADE "Enable ADE framework (required for Graph API module)" ON)
2+
3+
OCV_OPTION(WITH_FREETYPE "Enable FreeType framework" OFF)
4+
OCV_OPTION(WITH_PLAIDML "Include PlaidML2 support" OFF)
5+
OCV_OPTION(WITH_OAK "Include OpenCV AI Kit support" OFF)
6+
7+
if(NOT WITH_ADE)
8+
return()
9+
endif()
10+
11+
if(ade_DIR)
12+
# if ade_DIR is set, use ADE-supplied CMake script
13+
# to set up variables to the prebuilt ADE
14+
find_package(ade 0.1.0)
15+
endif()
16+
17+
if(NOT TARGET ade)
18+
# if ade_DIR is not set, try to use automatically
19+
# downloaded one (if there any)
20+
include("${CMAKE_CURRENT_LIST_DIR}/DownloadADE.cmake")
21+
endif()
22+
23+
if(WITH_FREETYPE)
24+
ocv_check_modules(FREETYPE freetype2)
25+
if (FREETYPE_FOUND)
26+
set(HAVE_FREETYPE TRUE)
27+
endif()
28+
endif()
29+
30+
if(WITH_PLAIDML)
31+
find_package(PlaidML2 CONFIG QUIET)
32+
if (PLAIDML_FOUND)
33+
set(HAVE_PLAIDML TRUE)
34+
endif()
35+
endif()
36+
37+
if(WITH_GAPI_ONEVPL)
38+
find_package(VPL)
39+
if(VPL_FOUND)
40+
set(HAVE_GAPI_ONEVPL TRUE)
41+
endif()
42+
endif()
43+
44+
if(WITH_OAK)
45+
find_package(depthai QUIET)
46+
if(depthai_FOUND)
47+
set(HAVE_OAK TRUE)
48+
endif()
49+
endif()
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
if("${CMAKE_BUILD_TYPE}" STREQUAL "")
2+
set(CMAKE_BUILD_TYPE "Release")
3+
endif()
4+
5+
if (NOT TARGET ade )
6+
find_package(ade 0.1.0 REQUIRED)
7+
endif()
8+
9+
if (WITH_GAPI_ONEVPL)
10+
find_package(VPL)
11+
if(VPL_FOUND)
12+
set(HAVE_GAPI_ONEVPL TRUE)
13+
endif()
14+
endif()
15+
16+
set(FLUID_TARGET fluid)
17+
set(FLUID_ROOT "${CMAKE_CURRENT_LIST_DIR}/../")
18+
19+
file(GLOB FLUID_includes "${FLUID_ROOT}/include/opencv2/*.hpp"
20+
"${FLUID_ROOT}/include/opencv2/gapi/g*.hpp"
21+
"${FLUID_ROOT}/include/opencv2/gapi/util/*.hpp"
22+
"${FLUID_ROOT}/include/opencv2/gapi/own/*.hpp"
23+
"${FLUID_ROOT}/include/opencv2/gapi/fluid/*.hpp")
24+
file(GLOB FLUID_sources "${FLUID_ROOT}/src/api/g*.cpp"
25+
"${FLUID_ROOT}/src/api/rmat.cpp"
26+
"${FLUID_ROOT}/src/api/media.cpp"
27+
"${FLUID_ROOT}/src/compiler/*.cpp"
28+
"${FLUID_ROOT}/src/compiler/passes/*.cpp"
29+
"${FLUID_ROOT}/src/executor/*.cpp"
30+
"${FLUID_ROOT}/src/backends/fluid/*.cpp"
31+
"${FLUID_ROOT}/src/backends/streaming/*.cpp"
32+
"${FLUID_ROOT}/src/backends/common/*.cpp")
33+
34+
add_library(${FLUID_TARGET} STATIC ${FLUID_includes} ${FLUID_sources})
35+
36+
target_include_directories(${FLUID_TARGET}
37+
PUBLIC $<BUILD_INTERFACE:${FLUID_ROOT}/include>
38+
PRIVATE ${FLUID_ROOT}/src)
39+
40+
target_compile_definitions(${FLUID_TARGET} PUBLIC GAPI_STANDALONE
41+
# This preprocessor definition resolves symbol clash when
42+
# standalone fluid meets gapi ocv module in one application
43+
PUBLIC cv=fluidcv)
44+
45+
set_target_properties(${FLUID_TARGET} PROPERTIES POSITION_INDEPENDENT_CODE True)
46+
set_property(TARGET ${FLUID_TARGET} PROPERTY CXX_STANDARD 11)
47+
48+
if(MSVC)
49+
target_compile_options(${FLUID_TARGET} PUBLIC "/wd4251")
50+
target_compile_options(${FLUID_TARGET} PUBLIC "/wd4275")
51+
target_compile_definitions(${FLUID_TARGET} PRIVATE _CRT_SECURE_NO_DEPRECATE)
52+
# Disable obsollete warning C4503 popping up on MSVC <<2017
53+
# https://docs.microsoft.com/en-us/cpp/error-messages/compiler-warnings/compiler-warning-level-1-c4503?view=vs-2019
54+
set_target_properties(${FLUID_TARGET} PROPERTIES COMPILE_FLAGS "/wd4503")
55+
endif()
56+
57+
target_link_libraries(${FLUID_TARGET} PRIVATE ade)
58+
59+
if(WIN32)
60+
# Required for htonl/ntohl on Windows
61+
target_link_libraries(${FLUID_TARGET} PRIVATE wsock32 ws2_32)
62+
endif()

modules/gapi/doc/00-root.markdown

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
# Graph API {#gapi}
2+
3+
# Introduction {#gapi_root_intro}
4+
5+
OpenCV Graph API (or G-API) is a new OpenCV module targeted to make
6+
regular image processing fast and portable. These two goals are
7+
achieved by introducing a new graph-based model of execution.
8+
9+
G-API is a special module in OpenCV -- in contrast with the majority
10+
of other main modules, this one acts as a framework rather than some
11+
specific CV algorithm. G-API provides means to define CV operations,
12+
construct graphs (in form of expressions) using it, and finally
13+
implement and run the operations for a particular backend.
14+
15+
@note G-API is a new module and now is in active development. It's API
16+
is volatile at the moment and there may be minor but
17+
compatibility-breaking changes in the future.
18+
19+
# Contents
20+
21+
G-API documentation is organized into the following chapters:
22+
23+
- @subpage gapi_purposes
24+
25+
The motivation behind G-API and its goals.
26+
27+
- @subpage gapi_hld
28+
29+
General overview of G-API architecture and its major internal
30+
components.
31+
32+
- @subpage gapi_kernel_api
33+
34+
Learn how to introduce new operations in G-API and implement it for
35+
various backends.
36+
37+
- @subpage gapi_impl
38+
39+
Low-level implementation details of G-API, for those who want to
40+
contribute.
41+
42+
- API Reference: functions and classes
43+
44+
- @subpage gapi_ref
45+
46+
Core G-API classes, data types, backends, etc.
47+
48+
- @subpage gapi_core
49+
50+
Core G-API operations - arithmetic, boolean, and other matrix
51+
operations;
52+
53+
- @subpage gapi_imgproc
54+
55+
Image processing functions: color space conversions, various
56+
filters, etc.
57+
58+
- @subpage gapi_video
59+
60+
Video processing functionality.
61+
62+
- @subpage gapi_draw
63+
64+
Drawing and composition functionality
65+
66+
# API Example {#gapi_example}
67+
68+
A very basic example of G-API pipeline is shown below:
69+
70+
@include modules/gapi/samples/api_example.cpp
71+
72+
<!-- TODO align this code with text using marks and itemized list -->
73+
74+
G-API is a separate OpenCV module so its header files have to be
75+
included explicitly. The first four lines of `main()` create and
76+
initialize OpenCV's standard video capture object, which fetches
77+
video frames from either an attached camera or a specified file.
78+
79+
G-API pipeline is constructed next. In fact, it is a series of G-API
80+
operation calls on cv::GMat data. The important aspect of G-API is
81+
that this code block is just a declaration of actions, but not the
82+
actions themselves. No processing happens at this point, G-API only
83+
tracks which operations form pipeline and how it is connected. G-API
84+
_Data objects_ (here it is cv::GMat) are used to connect operations
85+
each other. `in` is an _empty_ cv::GMat signalling that it is a
86+
beginning of computation.
87+
88+
After G-API code is written, it is captured into a call graph with
89+
instantiation of cv::GComputation object. This object takes
90+
input/output data references (in this example, `in` and `out`
91+
cv::GMat objects, respectively) as parameters and reconstructs the
92+
call graph based on all the data flow between `in` and `out`.
93+
94+
cv::GComputation is a thin object in sense that it just captures which
95+
operations form up a computation. However, it can be used to execute
96+
computations -- in the following processing loop, every captured frame (a
97+
cv::Mat `input_frame`) is passed to cv::GComputation::apply().
98+
99+
![Example pipeline running on sample video 'vtest.avi'](pics/demo.jpg)
100+
101+
cv::GComputation::apply() is a polimorphic method which accepts a
102+
variadic number of arguments. Since this computation is defined on one
103+
input, one output, a special overload of cv::GComputation::apply() is
104+
used to pass input data and get output data.
105+
106+
Internally, cv::GComputation::apply() compiles the captured graph for
107+
the given input parameters and executes the compiled graph on data
108+
immediately.
109+
110+
There is a number important concepts can be outlines with this example:
111+
* Graph declaration and graph execution are distinct steps;
112+
* Graph is built implicitly from a sequence of G-API expressions;
113+
* G-API supports function-like calls -- e.g. cv::gapi::resize(), and
114+
operators, e.g operator|() which is used to compute bitwise OR;
115+
* G-API syntax aims to look pure: every operation call within a graph
116+
yields a new result, thus forming a directed acyclic graph (DAG);
117+
* Graph declaration is not bound to any data -- real data objects
118+
(cv::Mat) come into picture after the graph is already declared.
119+
120+
<!-- FIXME: The above operator|() link links to MatExpr not GAPI -->
121+
122+
See [tutorials and porting examples](@ref tutorial_table_of_content_gapi)
123+
to learn more on various G-API features and concepts.
124+
125+
<!-- TODO Add chapter on declaration, compilation, execution -->
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# Why Graph API? {#gapi_purposes}
2+
3+
# Motivation behind G-API {#gapi_intro_why}
4+
5+
G-API module brings graph-based model of execution to OpenCV. This
6+
chapter briefly describes how this new model can help software
7+
developers in two aspects: optimizing and porting image processing
8+
algorithms.
9+
10+
## Optimizing with Graph API {#gapi_intro_opt}
11+
12+
Traditionally OpenCV provided a lot of stand-alone image processing
13+
functions (see modules `core` and `imgproc`). Many of that functions
14+
are well-optimized (e.g. vectorized for specific CPUs, parallel, etc)
15+
but still the out-of-box optimization scope has been limited to a
16+
single function only -- optimizing the whole algorithm built atop of that
17+
functions was a responsibility of a programmer.
18+
19+
OpenCV 3.0 introduced _Transparent API_ (or _T-API_) which allowed to
20+
offload OpenCV function calls transparently to OpenCL devices and save
21+
on Host/Device data transfers with cv::UMat -- and it was a great step
22+
forward. However, T-API is a dynamic API -- user code still remains
23+
unconstrained and OpenCL kernels are enqueued in arbitrary order, thus
24+
eliminating further pipeline-level optimization potential.
25+
26+
G-API brings implicit graph model to OpenCV 4.0. Graph model captures
27+
all operations and its data dependencies in a pipeline and so provides
28+
G-API framework with extra information to do pipeline-level
29+
optimizations.
30+
31+
The cornerstone of graph-based optimizations is _Tiling_. Tiling
32+
allows to break the processing into smaller parts and reorganize
33+
operations to enable data parallelism, improve data locality, and save
34+
memory footprint. Data locality is an especially important aspect of
35+
software optimization due to diffent costs of memory access on modern
36+
computer architectures -- the more data is reused in the first level
37+
cache, the more efficient pipeline is.
38+
39+
Definitely the aforementioned techniques can be applied manually --
40+
but it requires extra skills and knowledge of the target platform and
41+
the algorithm implementation changes irrevocably -- becoming more
42+
specific, less flexible, and harder to extend and maintain.
43+
44+
G-API takes this responsibility and complexity from user and does the
45+
majority of the work by itself, keeping the algorithm code clean from
46+
device or optimization details. This approach has its own limitations,
47+
though, as graph model is a _constrained_ model and not every
48+
algorithm can be represented as a graph, so the G-API scope is limited
49+
only to regular image processing -- various filters, arithmetic,
50+
binary operations, and well-defined geometrical transformations.
51+
52+
## Porting with Graph API {#gapi_intro_port}
53+
54+
The essence of G-API is declaring a sequence of operations to run, and
55+
then executing that sequence. G-API is a constrained API, so it puts a
56+
number of limitations on which operations can form a pipeline and
57+
which data these operations may exchange each other.
58+
59+
This formalization in fact helps to make an algorithm portable. G-API
60+
clearly separates operation _interfaces_ from its _implementations_.
61+
62+
One operation (_kernel_) may have multiple implementations even for a
63+
single device (e.g., OpenCV-based "reference" implementation and a
64+
tiled optimized implementation, both running on CPU). Graphs (or
65+
_Computations_ in G-API terms) are built only using operation
66+
interfaces, not implementations -- thus the same graph can be executed
67+
on different devices (and, of course, using different optimization
68+
techniques) with little-to-no changes in the graph itself.
69+
70+
G-API supports plugins (_Backends_) which aggregate logic and
71+
intelligence on what is the best way to execute on a particular
72+
platform. Once a pipeline is built with G-API, it can be parametrized
73+
to use either of the backends (or a combination of it) and so a graph
74+
can be ported easily to a new platform.
75+
76+
@sa @ref gapi_hld

0 commit comments

Comments
 (0)