forked from opencv/opencv
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request opencv#18716 from dmatveev:dm/upstream_onnx
* G-API: Introduce ONNX backend for Inference - Basic operations are implemented (Infer, -ROI, -List, -List2); - Implemented automatic preprocessing for ONNX models; - Test suite is extended with `OPENCV_GAPI_ONNX_MODEL_PATH` env for test data (test data is an ONNX Model Zoo repo snapshot); - Fixed kernel lookup logic in core G-API: - Lookup NN kernels not in the default package, but in the associated backend's aux package. Now two NN backends can work in the same graph. - Added Infer SSD demo and a combined ONNX/IE demo; * G-API/ONNX: Fix some of CMake issues Co-authored-by: Pashchenkov, Maxim <maxim.pashchenkov@intel.com>
- Loading branch information
Showing
10 changed files
with
1,920 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
ocv_clear_vars(HAVE_ONNX) | ||
|
||
set(ONNXRT_ROOT_DIR "" CACHE PATH "ONNX Runtime install directory") | ||
|
||
# For now, check the old name ORT_INSTALL_DIR | ||
if(ORT_INSTALL_DIR AND NOT ONNXRT_ROOT_DIR) | ||
set(ONNXRT_ROOT_DIR ORT_INSTALL_DIR) | ||
endif() | ||
|
||
if(ONNXRT_ROOT_DIR) | ||
find_library(ORT_LIB onnxruntime | ||
${ONNXRT_ROOT_DIR}/lib | ||
CMAKE_FIND_ROOT_PATH_BOTH) | ||
find_path(ORT_INCLUDE onnxruntime_cxx_api.h | ||
${ONNXRT_ROOT_DIR}/include/onnxruntime/core/session | ||
CMAKE_FIND_ROOT_PATH_BOTH) | ||
endif() | ||
|
||
if(ORT_LIB AND ORT_INCLUDE) | ||
set(HAVE_ONNX TRUE) | ||
# For CMake output only | ||
set(ONNX_LIBRARIES "${ORT_LIB}" CACHE STRING "ONNX Runtime libraries") | ||
set(ONNX_INCLUDE_DIR "${ORT_INCLUDE}" CACHE STRING "ONNX Runtime include path") | ||
|
||
# Link target with associated interface headers | ||
set(ONNX_LIBRARY "onnxruntime" CACHE STRING "ONNX Link Target") | ||
ocv_add_library(${ONNX_LIBRARY} SHARED IMPORTED) | ||
set_target_properties(${ONNX_LIBRARY} PROPERTIES | ||
INTERFACE_INCLUDE_DIRECTORIES ${ORT_INCLUDE} | ||
IMPORTED_LOCATION ${ORT_LIB} | ||
IMPORTED_IMPLIB ${ORT_LIB}) | ||
endif() | ||
|
||
if(NOT HAVE_ONNX) | ||
ocv_clear_vars(HAVE_ONNX ORT_LIB ORT_INCLUDE_DIR) | ||
endif() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
// This file is part of OpenCV project. | ||
// It is subject to the license terms in the LICENSE file found in the top-level directory | ||
// of this distribution and at http://opencv.org/license.html. | ||
// | ||
// Copyright (C) 2020 Intel Corporation | ||
|
||
#ifndef OPENCV_GAPI_INFER_ONNX_HPP | ||
#define OPENCV_GAPI_INFER_ONNX_HPP | ||
|
||
#include <unordered_map> | ||
#include <string> | ||
#include <array> | ||
#include <tuple> // tuple, tuple_size | ||
|
||
#include <opencv2/gapi/opencv_includes.hpp> | ||
#include <opencv2/gapi/util/any.hpp> | ||
|
||
#include <opencv2/core/cvdef.h> // GAPI_EXPORTS | ||
#include <opencv2/gapi/gkernel.hpp> // GKernelPackage | ||
|
||
namespace cv { | ||
namespace gapi { | ||
namespace onnx { | ||
|
||
GAPI_EXPORTS cv::gapi::GBackend backend(); | ||
|
||
enum class TraitAs: int { | ||
TENSOR, //!< G-API traits an associated cv::Mat as a raw tensor | ||
// and passes dimensions as-is | ||
IMAGE //!< G-API traits an associated cv::Mat as an image so | ||
// creates an "image" blob (NCHW/NHWC, etc) | ||
}; | ||
|
||
using PostProc = std::function<void(const std::unordered_map<std::string, cv::Mat> &, | ||
std::unordered_map<std::string, cv::Mat> &)>; | ||
|
||
|
||
namespace detail { | ||
struct ParamDesc { | ||
std::string model_path; | ||
|
||
// NB: nun_* may differ from topology's real input/output port numbers | ||
// (e.g. topology's partial execution) | ||
std::size_t num_in; // How many inputs are defined in the operation | ||
std::size_t num_out; // How many outputs are defined in the operation | ||
|
||
// NB: Here order follows the `Net` API | ||
std::vector<std::string> input_names; | ||
std::vector<std::string> output_names; | ||
|
||
using ConstInput = std::pair<cv::Mat, TraitAs>; | ||
std::unordered_map<std::string, ConstInput> const_inputs; | ||
|
||
std::vector<cv::Scalar> mean; | ||
std::vector<cv::Scalar> stdev; | ||
|
||
std::vector<cv::GMatDesc> out_metas; | ||
PostProc custom_post_proc; | ||
|
||
std::vector<bool> normalize; | ||
}; | ||
} // namespace detail | ||
|
||
template<typename Net> | ||
struct PortCfg { | ||
using In = std::array | ||
< std::string | ||
, std::tuple_size<typename Net::InArgs>::value >; | ||
using Out = std::array | ||
< std::string | ||
, std::tuple_size<typename Net::OutArgs>::value >; | ||
using NormCoefs = std::array | ||
< cv::Scalar | ||
, std::tuple_size<typename Net::InArgs>::value >; | ||
using Normalize = std::array | ||
< bool | ||
, std::tuple_size<typename Net::InArgs>::value >; | ||
}; | ||
|
||
template<typename Net> class Params { | ||
public: | ||
Params(const std::string &model) { | ||
desc.model_path = model; | ||
desc.num_in = std::tuple_size<typename Net::InArgs>::value; | ||
desc.num_out = std::tuple_size<typename Net::OutArgs>::value; | ||
}; | ||
|
||
// BEGIN(G-API's network parametrization API) | ||
GBackend backend() const { return cv::gapi::onnx::backend(); } | ||
std::string tag() const { return Net::tag(); } | ||
cv::util::any params() const { return { desc }; } | ||
// END(G-API's network parametrization API) | ||
|
||
Params<Net>& cfgInputLayers(const typename PortCfg<Net>::In &ll) { | ||
desc.input_names.assign(ll.begin(), ll.end()); | ||
return *this; | ||
} | ||
|
||
Params<Net>& cfgOutputLayers(const typename PortCfg<Net>::Out &ll) { | ||
desc.output_names.assign(ll.begin(), ll.end()); | ||
return *this; | ||
} | ||
|
||
Params<Net>& constInput(const std::string &layer_name, | ||
const cv::Mat &data, | ||
TraitAs hint = TraitAs::TENSOR) { | ||
desc.const_inputs[layer_name] = {data, hint}; | ||
return *this; | ||
} | ||
|
||
Params<Net>& cfgMeanStd(const typename PortCfg<Net>::NormCoefs &m, | ||
const typename PortCfg<Net>::NormCoefs &s) { | ||
desc.mean.assign(m.begin(), m.end()); | ||
desc.stdev.assign(s.begin(), s.end()); | ||
return *this; | ||
} | ||
|
||
Params<Net>& cfgPostProc(const std::vector<cv::GMatDesc> &outs, | ||
const PostProc &pp) { | ||
desc.out_metas = outs; | ||
desc.custom_post_proc = pp; | ||
return *this; | ||
} | ||
|
||
Params<Net>& cfgNormalize(const typename PortCfg<Net>::Normalize &n) { | ||
desc.normalize.assign(n.begin(), n.end()); | ||
return *this; | ||
} | ||
|
||
protected: | ||
detail::ParamDesc desc; | ||
}; | ||
|
||
} // namespace onnx | ||
} // namespace gapi | ||
} // namespace cv | ||
|
||
#endif // OPENCV_GAPI_INFER_HPP |
Oops, something went wrong.