123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107 |
- // 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
- #include "../test_precomp.hpp"
- #ifdef HAVE_ONNX
- #include <stdexcept>
- #include <codecvt> // wstring_convert
- #include <onnxruntime_cxx_api.h>
- #include <ade/util/iota_range.hpp>
- #include <ade/util/algorithm.hpp>
- #include <opencv2/gapi/own/convert.hpp>
- #include <opencv2/gapi/infer/onnx.hpp>
- namespace {
- class TestMediaBGR final: public cv::MediaFrame::IAdapter {
- cv::Mat m_mat;
- using Cb = cv::MediaFrame::View::Callback;
- Cb m_cb;
- public:
- explicit TestMediaBGR(cv::Mat m, Cb cb = [](){})
- : m_mat(m), m_cb(cb) {
- }
- cv::GFrameDesc meta() const override {
- return cv::GFrameDesc{cv::MediaFormat::BGR, cv::Size(m_mat.cols, m_mat.rows)};
- }
- cv::MediaFrame::View access(cv::MediaFrame::Access) override {
- cv::MediaFrame::View::Ptrs pp = { m_mat.ptr(), nullptr, nullptr, nullptr };
- cv::MediaFrame::View::Strides ss = { m_mat.step, 0u, 0u, 0u };
- return cv::MediaFrame::View(std::move(pp), std::move(ss), Cb{m_cb});
- }
- };
- class TestMediaNV12 final: public cv::MediaFrame::IAdapter {
- cv::Mat m_y;
- cv::Mat m_uv;
- public:
- TestMediaNV12(cv::Mat y, cv::Mat uv) : m_y(y), m_uv(uv) {
- }
- cv::GFrameDesc meta() const override {
- return cv::GFrameDesc{cv::MediaFormat::NV12, cv::Size(m_y.cols, m_y.rows)};
- }
- cv::MediaFrame::View access(cv::MediaFrame::Access) override {
- cv::MediaFrame::View::Ptrs pp = {
- m_y.ptr(), m_uv.ptr(), nullptr, nullptr
- };
- cv::MediaFrame::View::Strides ss = {
- m_y.step, m_uv.step, 0u, 0u
- };
- return cv::MediaFrame::View(std::move(pp), std::move(ss));
- }
- };
- struct ONNXInitPath {
- ONNXInitPath() {
- const char* env_path = getenv("OPENCV_GAPI_ONNX_MODEL_PATH");
- if (env_path) {
- cvtest::addDataSearchPath(env_path);
- }
- }
- };
- static ONNXInitPath g_init_path;
- cv::Mat initMatrixRandU(const int type, const cv::Size& sz_in) {
- const cv::Mat in_mat = cv::Mat(sz_in, type);
- if (CV_MAT_DEPTH(type) < CV_32F) {
- cv::randu(in_mat, cv::Scalar::all(0), cv::Scalar::all(255));
- } else {
- const int fscale = 256; // avoid bits near ULP, generate stable test input
- cv::Mat in_mat32s(in_mat.size(), CV_MAKE_TYPE(CV_32S, CV_MAT_CN(type)));
- cv::randu(in_mat32s, cv::Scalar::all(0), cv::Scalar::all(255 * fscale));
- in_mat32s.convertTo(in_mat, type, 1.0f / fscale, 0);
- }
- return in_mat;
- }
- } // anonymous namespace
- namespace opencv_test
- {
- namespace {
- // FIXME: taken from the DNN module
- void normAssert(cv::InputArray& ref, cv::InputArray& test,
- const char *comment /*= ""*/,
- const double l1 = 0.00001, const double lInf = 0.0001) {
- const double normL1 = cvtest::norm(ref, test, cv::NORM_L1) / ref.getMat().total();
- EXPECT_LE(normL1, l1) << comment;
- const double normInf = cvtest::norm(ref, test, cv::NORM_INF);
- EXPECT_LE(normInf, lInf) << comment;
- }
- inline std::string findModel(const std::string &model_name) {
- return findDataFile("vision/" + model_name + ".onnx", false);
- }
- inline void toCHW(const cv::Mat& src, cv::Mat& dst) {
- dst.create(cv::Size(src.cols, src.rows * src.channels()), CV_32F);
- std::vector<cv::Mat> planes;
- for (int i = 0; i < src.channels(); ++i) {
- planes.push_back(dst.rowRange(i * src.rows, (i + 1) * src.rows));
- }
- cv::split(src, planes);
- }
- inline int toCV(ONNXTensorElementDataType prec) {
- switch (prec) {
- case ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT8: return CV_8U;
- case ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT: return CV_32F;
- case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT32: return CV_32S;
- case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT64: return CV_32S;
- default: GAPI_Assert(false && "Unsupported data type");
- }
- return -1;
- }
- void copyFromONNX(Ort::Value &v, cv::Mat& mat) {
- const auto info = v.GetTensorTypeAndShapeInfo();
- const auto prec = info.GetElementType();
- const auto shape = info.GetShape();
- const std::vector<int> dims(shape.begin(), shape.end());
- mat.create(dims, toCV(prec));
- switch (prec) {
- #define HANDLE(E,T) \
- case E: std::copy_n(v.GetTensorMutableData<T>(), \
- mat.total(), \
- reinterpret_cast<T*>(mat.data)); \
- break;
- HANDLE(ONNX_TENSOR_ELEMENT_DATA_TYPE_UINT8, uint8_t);
- HANDLE(ONNX_TENSOR_ELEMENT_DATA_TYPE_FLOAT, float);
- HANDLE(ONNX_TENSOR_ELEMENT_DATA_TYPE_INT32, int);
- #undef HANDLE
- case ONNX_TENSOR_ELEMENT_DATA_TYPE_INT64: {
- const auto o_ptr = v.GetTensorMutableData<int64_t>();
- const auto g_ptr = reinterpret_cast<int*>(mat.data);
- std::transform(o_ptr, o_ptr + mat.total(), g_ptr,
- [](int64_t el) { return static_cast<int>(el); });
- break;
- }
- default: GAPI_Assert(false && "ONNX. Unsupported data type");
- }
- }
- inline std::vector<int64_t> toORT(const cv::MatSize &sz) {
- return cv::to_own<int64_t>(sz);
- }
- inline std::vector<const char*> getCharNames(const std::vector<std::string>& names) {
- std::vector<const char*> out_ptrs;
- out_ptrs.reserve(names.size());
- ade::util::transform(names, std::back_inserter(out_ptrs),
- [](const std::string& name) { return name.c_str(); });
- return out_ptrs;
- }
- template<typename T>
- void copyToOut(const cv::Mat& onnx_out, const T end_mark, cv::Mat& gapi_out) {
- // This function is part of some remap__ function.
- // You can set graph output size (gapi_out) larger than real out from ONNX
- // so you have to add something for separate correct data and garbage.
- // For example, end of data can be marked with -1 (for positive values)
- // or you can put size of correct data at first/last element of output matrix.
- const size_t size = std::min(onnx_out.total(), gapi_out.total());
- std::copy(onnx_out.begin<T>(),
- onnx_out.begin<T>() + size,
- gapi_out.begin<T>());
- if (gapi_out.total() > onnx_out.total()) {
- T* gptr = gapi_out.ptr<T>();
- gptr[size] = end_mark;
- }
- }
- void remapYolo(const std::unordered_map<std::string, cv::Mat> &onnx,
- std::unordered_map<std::string, cv::Mat> &gapi) {
- GAPI_Assert(onnx.size() == 1u);
- GAPI_Assert(gapi.size() == 1u);
- // Result from Run method
- const cv::Mat& in = onnx.begin()->second;
- GAPI_Assert(in.depth() == CV_32F);
- // Configured output
- cv::Mat& out = gapi.begin()->second;
- // Simple copy
- copyToOut<float>(in, -1.f, out);
- }
- void remapYoloV3(const std::unordered_map<std::string, cv::Mat> &onnx,
- std::unordered_map<std::string, cv::Mat> &gapi) {
- // Simple copy for outputs
- const cv::Mat& in_boxes = onnx.at("yolonms_layer_1/ExpandDims_1:0");
- const cv::Mat& in_scores = onnx.at("yolonms_layer_1/ExpandDims_3:0");
- const cv::Mat& in_indices = onnx.at("yolonms_layer_1/concat_2:0");
- GAPI_Assert(in_boxes.depth() == CV_32F);
- GAPI_Assert(in_scores.depth() == CV_32F);
- GAPI_Assert(in_indices.depth() == CV_32S);
- cv::Mat& out_boxes = gapi.at("out1");
- cv::Mat& out_scores = gapi.at("out2");
- cv::Mat& out_indices = gapi.at("out3");
- copyToOut<float>(in_boxes, -1.f, out_boxes);
- copyToOut<float>(in_scores, -1.f, out_scores);
- copyToOut<int>(in_indices, -1, out_indices);
- }
- void remapToIESSDOut(const std::vector<cv::Mat> &detections,
- cv::Mat &ssd_output) {
- GAPI_Assert(detections.size() == 4u);
- for (const auto &det_el : detections) {
- GAPI_Assert(det_el.depth() == CV_32F);
- GAPI_Assert(!det_el.empty());
- }
- // SSD-MobilenetV1 structure check
- ASSERT_EQ(1u, detections[0].total());
- ASSERT_EQ(detections[2].total(), detections[0].total() * 100);
- ASSERT_EQ(detections[2].total(), detections[3].total());
- ASSERT_EQ((detections[2].total() * 4), detections[1].total());
- const int num_objects = static_cast<int>(detections[0].ptr<float>()[0]);
- GAPI_Assert(num_objects <= (ssd_output.size[2] - 1));
- const float *in_boxes = detections[1].ptr<float>();
- const float *in_scores = detections[2].ptr<float>();
- const float *in_classes = detections[3].ptr<float>();
- float *ptr = ssd_output.ptr<float>();
- for (int i = 0; i < num_objects; ++i) {
- ptr[0] = 0.f; // "image_id"
- ptr[1] = in_classes[i]; // "label"
- ptr[2] = in_scores[i]; // "confidence"
- ptr[3] = in_boxes[4 * i + 1]; // left
- ptr[4] = in_boxes[4 * i + 0]; // top
- ptr[5] = in_boxes[4 * i + 3]; // right
- ptr[6] = in_boxes[4 * i + 2]; // bottom
- ptr += 7;
- in_boxes += 4;
- }
- if (num_objects < ssd_output.size[2] - 1) {
- // put a -1 mark at the end of output blob if there is space left
- ptr[0] = -1.f;
- }
- }
- void remapSSDPorts(const std::unordered_map<std::string, cv::Mat> &onnx,
- std::unordered_map<std::string, cv::Mat> &gapi) {
- // Assemble ONNX-processed outputs back to a single 1x1x200x7 blob
- // to preserve compatibility with OpenVINO-based SSD pipeline
- const cv::Mat &num_detections = onnx.at("num_detections:0");
- const cv::Mat &detection_boxes = onnx.at("detection_boxes:0");
- const cv::Mat &detection_scores = onnx.at("detection_scores:0");
- const cv::Mat &detection_classes = onnx.at("detection_classes:0");
- cv::Mat &ssd_output = gapi.at("detection_output");
- remapToIESSDOut({num_detections, detection_boxes, detection_scores, detection_classes}, ssd_output);
- }
- void reallocSSDPort(const std::unordered_map<std::string, cv::Mat> &/*onnx*/,
- std::unordered_map<std::string, cv::Mat> &gapi) {
- gapi["detection_boxes"].create(1000, 3000, CV_32FC3);
- }
- void remapRCNNPortsC(const std::unordered_map<std::string, cv::Mat> &onnx,
- std::unordered_map<std::string, cv::Mat> &gapi) {
- // Simple copy for outputs
- const cv::Mat& in_boxes = onnx.at("6379");
- const cv::Mat& in_labels = onnx.at("6381");
- const cv::Mat& in_scores = onnx.at("6383");
- GAPI_Assert(in_boxes.depth() == CV_32F);
- GAPI_Assert(in_labels.depth() == CV_32S);
- GAPI_Assert(in_scores.depth() == CV_32F);
- cv::Mat& out_boxes = gapi.at("out1");
- cv::Mat& out_labels = gapi.at("out2");
- cv::Mat& out_scores = gapi.at("out3");
- copyToOut<float>(in_boxes, -1.f, out_boxes);
- copyToOut<int>(in_labels, -1, out_labels);
- copyToOut<float>(in_scores, -1.f, out_scores);
- }
- void remapRCNNPortsDO(const std::unordered_map<std::string, cv::Mat> &onnx,
- std::unordered_map<std::string, cv::Mat> &gapi) {
- // Simple copy for outputs
- const cv::Mat& in_boxes = onnx.at("6379");
- const cv::Mat& in_scores = onnx.at("6383");
- GAPI_Assert(in_boxes.depth() == CV_32F);
- GAPI_Assert(in_scores.depth() == CV_32F);
- cv::Mat& out_boxes = gapi.at("out1");
- cv::Mat& out_scores = gapi.at("out2");
- copyToOut<float>(in_boxes, -1.f, out_boxes);
- copyToOut<float>(in_scores, -1.f, out_scores);
- }
- class ONNXtest : public ::testing::Test {
- public:
- std::string model_path;
- size_t num_in, num_out;
- std::vector<cv::Mat> out_gapi;
- std::vector<cv::Mat> out_onnx;
- cv::Mat in_mat;
- ONNXtest() {
- env = Ort::Env(ORT_LOGGING_LEVEL_WARNING, "test");
- memory_info = Ort::MemoryInfo::CreateCpu(OrtArenaAllocator, OrtMemTypeDefault);
- out_gapi.resize(1);
- }
- template<typename T>
- void infer(const std::vector<cv::Mat>& ins,
- std::vector<cv::Mat>& outs,
- std::vector<std::string>&& custom_out_names = {}) {
- // Prepare session
- #ifndef _WIN32
- session = Ort::Session(env, model_path.c_str(), session_options);
- #else
- std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter;
- std::wstring w_model_path = converter.from_bytes(model_path.c_str());
- session = Ort::Session(env, w_model_path.c_str(), session_options);
- #endif
- num_in = session.GetInputCount();
- num_out = session.GetOutputCount();
- GAPI_Assert(num_in == ins.size());
- in_node_names.clear();
- out_node_names.clear();
- // Inputs Run params
- std::vector<Ort::Value> in_tensors;
- for(size_t i = 0; i < num_in; ++i) {
- char* in_node_name_p = session.GetInputName(i, allocator);
- in_node_names.emplace_back(in_node_name_p);
- allocator.Free(in_node_name_p);
- in_node_dims = toORT(ins[i].size);
- in_tensors.emplace_back(Ort::Value::CreateTensor<T>(memory_info,
- const_cast<T*>(ins[i].ptr<T>()),
- ins[i].total(),
- in_node_dims.data(),
- in_node_dims.size()));
- }
- // Outputs Run params
- if (custom_out_names.empty()) {
- for(size_t i = 0; i < num_out; ++i) {
- char* out_node_name_p = session.GetOutputName(i, allocator);
- out_node_names.emplace_back(out_node_name_p);
- allocator.Free(out_node_name_p);
- }
- } else {
- out_node_names = std::move(custom_out_names);
- }
- // Input/output order by names
- const auto in_run_names = getCharNames(in_node_names);
- const auto out_run_names = getCharNames(out_node_names);
- num_out = out_run_names.size();
- // Run
- auto result = session.Run(Ort::RunOptions{nullptr},
- in_run_names.data(),
- &in_tensors.front(),
- num_in,
- out_run_names.data(),
- num_out);
- // Copy outputs
- GAPI_Assert(result.size() == num_out);
- for (size_t i = 0; i < num_out; ++i) {
- const auto info = result[i].GetTensorTypeAndShapeInfo();
- const auto shape = info.GetShape();
- const auto type = toCV(info.GetElementType());
- const std::vector<int> dims(shape.begin(), shape.end());
- outs.emplace_back(dims, type);
- copyFromONNX(result[i], outs.back());
- }
- }
- // One input/output overload
- template<typename T>
- void infer(const cv::Mat& in, cv::Mat& out) {
- std::vector<cv::Mat> result;
- infer<T>(std::vector<cv::Mat>{in}, result);
- GAPI_Assert(result.size() == 1u);
- out = result.front();
- }
- // One input overload
- template<typename T>
- void infer(const cv::Mat& in,
- std::vector<cv::Mat>& outs,
- std::vector<std::string>&& custom_out_names = {}) {
- infer<T>(std::vector<cv::Mat>{in}, outs, std::move(custom_out_names));
- }
- void validate() {
- GAPI_Assert(!out_gapi.empty() && !out_onnx.empty());
- ASSERT_EQ(out_gapi.size(), out_onnx.size());
- const auto size = out_gapi.size();
- for (size_t i = 0; i < size; ++i) {
- normAssert(out_onnx[i], out_gapi[i], "Test outputs");
- }
- }
- void useModel(const std::string& model_name) {
- model_path = findModel(model_name);
- }
- private:
- Ort::Env env{nullptr};
- Ort::MemoryInfo memory_info{nullptr};
- Ort::AllocatorWithDefaultOptions allocator;
- Ort::SessionOptions session_options;
- Ort::Session session{nullptr};
- std::vector<int64_t> in_node_dims;
- std::vector<std::string> in_node_names;
- std::vector<std::string> out_node_names;
- };
- class ONNXClassification : public ONNXtest {
- public:
- const cv::Scalar mean = { 0.485, 0.456, 0.406 };
- const cv::Scalar std = { 0.229, 0.224, 0.225 };
- // Rois for InferList, InferList2
- const std::vector<cv::Rect> rois = {
- cv::Rect(cv::Point{ 0, 0}, cv::Size{80, 120}),
- cv::Rect(cv::Point{50, 100}, cv::Size{250, 360})
- };
- void preprocess(const cv::Mat& src, cv::Mat& dst) {
- const int new_h = 224;
- const int new_w = 224;
- cv::Mat tmp, cvt, rsz;
- cv::resize(src, rsz, cv::Size(new_w, new_h));
- rsz.convertTo(cvt, CV_32F, 1.f / 255);
- tmp = (cvt - mean) / std;
- toCHW(tmp, dst);
- dst = dst.reshape(1, {1, 3, new_h, new_w});
- }
- };
- class ONNXMediaFrame : public ONNXClassification {
- public:
- const std::vector<cv::Rect> rois = {
- cv::Rect(cv::Point{ 0, 0}, cv::Size{80, 120}),
- cv::Rect(cv::Point{50, 100}, cv::Size{250, 360}),
- cv::Rect(cv::Point{70, 10}, cv::Size{20, 260}),
- cv::Rect(cv::Point{5, 15}, cv::Size{200, 160}),
- };
- const cv::Size sz{640, 480};
- const cv::Mat m_in_y = initMatrixRandU(CV_8UC1, sz);
- const cv::Mat m_in_uv = initMatrixRandU(CV_8UC2, sz / 2);
- };
- class ONNXGRayScale : public ONNXtest {
- public:
- void preprocess(const cv::Mat& src, cv::Mat& dst) {
- const int new_h = 64;
- const int new_w = 64;
- cv::Mat cvc, rsz, cvt;
- cv::cvtColor(src, cvc, cv::COLOR_BGR2GRAY);
- cv::resize(cvc, rsz, cv::Size(new_w, new_h));
- rsz.convertTo(cvt, CV_32F);
- toCHW(cvt, dst);
- dst = dst.reshape(1, {1, 1, new_h, new_w});
- }
- };
- class ONNXWithRemap : public ONNXtest {
- private:
- size_t step_by_outs = 0;
- public:
- // This function checks each next cv::Mat in out_gapi vector for next call.
- // end_mark is edge of correct data
- template <typename T>
- void validate(const T end_mark) {
- GAPI_Assert(!out_gapi.empty() && !out_onnx.empty());
- ASSERT_EQ(out_gapi.size(), out_onnx.size());
- GAPI_Assert(step_by_outs < out_gapi.size());
- const T* op = out_onnx.at(step_by_outs).ptr<T>();
- const T* gp = out_gapi.at(step_by_outs).ptr<T>();
- // Checking that graph output larger than onnx output
- const auto out_size = std::min(out_onnx.at(step_by_outs).total(), out_gapi.at(step_by_outs).total());
- GAPI_Assert(out_size != 0u);
- for (size_t d_idx = 0; d_idx < out_size; ++d_idx) {
- if (gp[d_idx] == end_mark) break;
- ASSERT_EQ(op[d_idx], gp[d_idx]);
- }
- ++step_by_outs;
- }
- };
- class ONNXRCNN : public ONNXWithRemap {
- private:
- const cv::Scalar rcnn_mean = { 102.9801, 115.9465, 122.7717 };
- const float range_max = 1333;
- const float range_min = 800;
- public:
- void preprocess(const cv::Mat& src, cv::Mat& dst) {
- cv::Mat rsz, cvt, chw, mn;
- const auto get_ratio = [&](const int dim) -> float {
- return ((dim > range_max) || (dim < range_min))
- ? dim > range_max
- ? range_max / dim
- : range_min / dim
- : 1.f;
- };
- const auto ratio_h = get_ratio(src.rows);
- const auto ratio_w = get_ratio(src.cols);
- const auto new_h = static_cast<int>(ratio_h * src.rows);
- const auto new_w = static_cast<int>(ratio_w * src.cols);
- cv::resize(src, rsz, cv::Size(new_w, new_h));
- rsz.convertTo(cvt, CV_32F, 1.f);
- toCHW(cvt, chw);
- mn = chw - rcnn_mean;
- const int padded_h = std::ceil(new_h / 32.f) * 32;
- const int padded_w = std::ceil(new_w / 32.f) * 32;
- cv::Mat pad_im(cv::Size(padded_w, 3 * padded_h), CV_32F, 0.f);
- pad_im(cv::Rect(0, 0, mn.cols, mn.rows)) += mn;
- dst = pad_im.reshape(1, {3, padded_h, padded_w});
- }
- };
- class ONNXYoloV3 : public ONNXWithRemap {
- public:
- std::vector<cv::Mat> ins;
- void constructYoloInputs(const cv::Mat& src) {
- const int yolo_in_h = 416;
- const int yolo_in_w = 416;
- cv::Mat yolov3_input, shape, prep_mat;
- cv::resize(src, yolov3_input, cv::Size(yolo_in_w, yolo_in_h));
- shape.create(cv::Size(2, 1), CV_32F);
- float* ptr = shape.ptr<float>();
- ptr[0] = src.cols;
- ptr[1] = src.rows;
- preprocess(yolov3_input, prep_mat);
- ins = {prep_mat, shape};
- }
- private:
- void preprocess(const cv::Mat& src, cv::Mat& dst) {
- cv::Mat cvt;
- src.convertTo(cvt, CV_32F, 1.f / 255.f);
- toCHW(cvt, dst);
- dst = dst.reshape(1, {1, 3, 416, 416});
- }
- };
- } // anonymous namespace
- TEST_F(ONNXClassification, Infer)
- {
- useModel("classification/squeezenet/model/squeezenet1.0-9");
- in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false));
- // ONNX_API code
- cv::Mat processed_mat;
- preprocess(in_mat, processed_mat);
- infer<float>(processed_mat, out_onnx);
- // G_API code
- G_API_NET(SqueezNet, <cv::GMat(cv::GMat)>, "squeeznet");
- cv::GMat in;
- cv::GMat out = cv::gapi::infer<SqueezNet>(in);
- cv::GComputation comp(cv::GIn(in), cv::GOut(out));
- // NOTE: We have to normalize U8 tensor
- // so cfgMeanStd() is here
- auto net = cv::gapi::onnx::Params<SqueezNet> { model_path }.cfgMeanStd({ mean }, { std });
- comp.apply(cv::gin(in_mat),
- cv::gout(out_gapi.front()),
- cv::compile_args(cv::gapi::networks(net)));
- // Validate
- validate();
- }
- TEST_F(ONNXClassification, InferTensor)
- {
- useModel("classification/squeezenet/model/squeezenet1.0-9");
- in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false));
- // Create tensor
- cv::Mat tensor;
- preprocess(in_mat, tensor);
- // ONNX_API code
- infer<float>(tensor, out_onnx);
- // G_API code
- G_API_NET(SqueezNet, <cv::GMat(cv::GMat)>, "squeeznet");
- cv::GMat in;
- cv::GMat out = cv::gapi::infer<SqueezNet>(in);
- cv::GComputation comp(cv::GIn(in), cv::GOut(out));
- auto net = cv::gapi::onnx::Params<SqueezNet> { model_path };
- comp.apply(cv::gin(tensor),
- cv::gout(out_gapi.front()),
- cv::compile_args(cv::gapi::networks(net)));
- // Validate
- validate();
- }
- TEST_F(ONNXClassification, InferROI)
- {
- useModel("classification/squeezenet/model/squeezenet1.0-9");
- in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false));
- const auto ROI = rois.at(0);
- // ONNX_API code
- cv::Mat roi_mat;
- preprocess(in_mat(ROI), roi_mat);
- infer<float>(roi_mat, out_onnx);
- // G_API code
- G_API_NET(SqueezNet, <cv::GMat(cv::GMat)>, "squeeznet");
- cv::GMat in;
- cv::GOpaque<cv::Rect> rect;
- cv::GMat out = cv::gapi::infer<SqueezNet>(rect, in);
- cv::GComputation comp(cv::GIn(in, rect), cv::GOut(out));
- // NOTE: We have to normalize U8 tensor
- // so cfgMeanStd() is here
- auto net = cv::gapi::onnx::Params<SqueezNet> { model_path }.cfgMeanStd({ mean }, { std });
- comp.apply(cv::gin(in_mat, ROI),
- cv::gout(out_gapi.front()),
- cv::compile_args(cv::gapi::networks(net)));
- // Validate
- validate();
- }
- TEST_F(ONNXClassification, InferROIList)
- {
- useModel("classification/squeezenet/model/squeezenet1.0-9");
- in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false));
- // ONNX_API code
- for (size_t i = 0; i < rois.size(); ++i) {
- cv::Mat roi_mat;
- preprocess(in_mat(rois[i]), roi_mat);
- infer<float>(roi_mat, out_onnx);
- }
- // G_API code
- G_API_NET(SqueezNet, <cv::GMat(cv::GMat)>, "squeeznet");
- cv::GMat in;
- cv::GArray<cv::Rect> rr;
- cv::GArray<cv::GMat> out = cv::gapi::infer<SqueezNet>(rr, in);
- cv::GComputation comp(cv::GIn(in, rr), cv::GOut(out));
- // NOTE: We have to normalize U8 tensor
- // so cfgMeanStd() is here
- auto net = cv::gapi::onnx::Params<SqueezNet> { model_path }.cfgMeanStd({ mean }, { std });
- comp.apply(cv::gin(in_mat, rois),
- cv::gout(out_gapi),
- cv::compile_args(cv::gapi::networks(net)));
- // Validate
- validate();
- }
- TEST_F(ONNXClassification, Infer2ROIList)
- {
- useModel("classification/squeezenet/model/squeezenet1.0-9");
- in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false));
- // ONNX_API code
- for (size_t i = 0; i < rois.size(); ++i) {
- cv::Mat roi_mat;
- preprocess(in_mat(rois[i]), roi_mat);
- infer<float>(roi_mat, out_onnx);
- }
- // G_API code
- G_API_NET(SqueezNet, <cv::GMat(cv::GMat)>, "squeeznet");
- cv::GMat in;
- cv::GArray<cv::Rect> rr;
- cv::GArray<cv::GMat> out = cv::gapi::infer2<SqueezNet>(in, rr);
- cv::GComputation comp(cv::GIn(in, rr), cv::GOut(out));
- // NOTE: We have to normalize U8 tensor
- // so cfgMeanStd() is here
- auto net = cv::gapi::onnx::Params<SqueezNet> { model_path }.cfgMeanStd({ mean }, { std });
- comp.apply(cv::gin(in_mat, rois),
- cv::gout(out_gapi),
- cv::compile_args(cv::gapi::networks(net)));
- // Validate
- validate();
- }
- TEST_F(ONNXWithRemap, InferDynamicInputTensor)
- {
- useModel("object_detection_segmentation/tiny-yolov2/model/tinyyolov2-8");
- in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false));
- // Create tensor
- cv::Mat cvt, rsz, tensor;
- cv::resize(in_mat, rsz, cv::Size{416, 416});
- rsz.convertTo(cvt, CV_32F, 1.f / 255.f);
- toCHW(cvt, tensor);
- tensor = tensor.reshape(1, {1, 3, 416, 416});
- // ONNX_API code
- infer<float>(tensor, out_onnx);
- // G_API code
- G_API_NET(YoloNet, <cv::GMat(cv::GMat)>, "YoloNet");
- cv::GMat in;
- cv::GMat out = cv::gapi::infer<YoloNet>(in);
- cv::GComputation comp(cv::GIn(in), cv::GOut(out));
- auto net = cv::gapi::onnx::Params<YoloNet>{ model_path }
- .cfgPostProc({cv::GMatDesc{CV_32F, {1, 125, 13, 13}}}, remapYolo)
- .cfgOutputLayers({"out"});
- comp.apply(cv::gin(tensor),
- cv::gout(out_gapi.front()),
- cv::compile_args(cv::gapi::networks(net)));
- // Validate
- validate<float>(-1.f);
- }
- TEST_F(ONNXGRayScale, InferImage)
- {
- useModel("body_analysis/emotion_ferplus/model/emotion-ferplus-8");
- in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false));
- // ONNX_API code
- cv::Mat prep_mat;
- preprocess(in_mat, prep_mat);
- infer<float>(prep_mat, out_onnx);
- // G_API code
- G_API_NET(EmotionNet, <cv::GMat(cv::GMat)>, "emotion-ferplus");
- cv::GMat in;
- cv::GMat out = cv::gapi::infer<EmotionNet>(in);
- cv::GComputation comp(cv::GIn(in), cv::GOut(out));
- auto net = cv::gapi::onnx::Params<EmotionNet> { model_path }
- .cfgNormalize({ false }); // model accepts 0..255 range in FP32;
- comp.apply(cv::gin(in_mat),
- cv::gout(out_gapi.front()),
- cv::compile_args(cv::gapi::networks(net)));
- // Validate
- validate();
- }
- TEST_F(ONNXWithRemap, InferMultiOutput)
- {
- useModel("object_detection_segmentation/ssd-mobilenetv1/model/ssd_mobilenet_v1_10");
- in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false));
- // ONNX_API code
- const auto prep_mat = in_mat.reshape(1, {1, in_mat.rows, in_mat.cols, in_mat.channels()});
- infer<uint8_t>(prep_mat, out_onnx);
- cv::Mat onnx_conv_out({1, 1, 200, 7}, CV_32F);
- remapToIESSDOut({out_onnx[3], out_onnx[0], out_onnx[2], out_onnx[1]}, onnx_conv_out);
- out_onnx.clear();
- out_onnx.push_back(onnx_conv_out);
- // G_API code
- G_API_NET(MobileNet, <cv::GMat(cv::GMat)>, "ssd_mobilenet");
- cv::GMat in;
- cv::GMat out = cv::gapi::infer<MobileNet>(in);
- cv::GComputation comp(cv::GIn(in), cv::GOut(out));
- auto net = cv::gapi::onnx::Params<MobileNet>{ model_path }
- .cfgOutputLayers({"detection_output"})
- .cfgPostProc({cv::GMatDesc{CV_32F, {1, 1, 200, 7}}}, remapSSDPorts);
- comp.apply(cv::gin(in_mat),
- cv::gout(out_gapi.front()),
- cv::compile_args(cv::gapi::networks(net)));
- // Validate
- validate<float>(-1.f);
- }
- TEST_F(ONNXMediaFrame, InferBGR)
- {
- useModel("classification/squeezenet/model/squeezenet1.0-9");
- in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false));
- // ONNX_API code
- cv::Mat processed_mat;
- preprocess(in_mat, processed_mat);
- infer<float>(processed_mat, out_onnx);
- // G_API code
- auto frame = MediaFrame::Create<TestMediaBGR>(in_mat);
- G_API_NET(SqueezNet, <cv::GMat(cv::GMat)>, "squeeznet");
- cv::GFrame in;
- cv::GMat out = cv::gapi::infer<SqueezNet>(in);
- cv::GComputation comp(cv::GIn(in), cv::GOut(out));
- // NOTE: We have to normalize U8 tensor
- // so cfgMeanStd() is here
- auto net = cv::gapi::onnx::Params<SqueezNet> { model_path }.cfgMeanStd({ mean }, { std });
- comp.apply(cv::gin(frame),
- cv::gout(out_gapi.front()),
- cv::compile_args(cv::gapi::networks(net)));
- // Validate
- validate();
- }
- TEST_F(ONNXMediaFrame, InferYUV)
- {
- useModel("classification/squeezenet/model/squeezenet1.0-9");
- in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false));
- const auto frame = MediaFrame::Create<TestMediaNV12>(m_in_y, m_in_uv);
- // ONNX_API code
- cv::Mat pp;
- cvtColorTwoPlane(m_in_y, m_in_uv, pp, cv::COLOR_YUV2BGR_NV12);
- cv::Mat processed_mat;
- preprocess(pp, processed_mat);
- infer<float>(processed_mat, out_onnx);
- // G_API code
- G_API_NET(SqueezNet, <cv::GMat(cv::GMat)>, "squeeznet");
- cv::GFrame in;
- cv::GMat out = cv::gapi::infer<SqueezNet>(in);
- cv::GComputation comp(cv::GIn(in), cv::GOut(out));
- // NOTE: We have to normalize U8 tensor
- // so cfgMeanStd() is here
- auto net = cv::gapi::onnx::Params<SqueezNet> { model_path }.cfgMeanStd({ mean }, { std });
- comp.apply(cv::gin(frame),
- cv::gout(out_gapi.front()),
- cv::compile_args(cv::gapi::networks(net)));
- // Validate
- validate();
- }
- TEST_F(ONNXMediaFrame, InferROIBGR)
- {
- useModel("classification/squeezenet/model/squeezenet1.0-9");
- in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false));
- auto frame = MediaFrame::Create<TestMediaBGR>(in_mat);
- // ONNX_API code
- cv::Mat roi_mat;
- preprocess(in_mat(rois.front()), roi_mat);
- infer<float>(roi_mat, out_onnx);
- // G_API code
- G_API_NET(SqueezNet, <cv::GMat(cv::GMat)>, "squeeznet");
- cv::GFrame in;
- cv::GOpaque<cv::Rect> rect;
- cv::GMat out = cv::gapi::infer<SqueezNet>(rect, in);
- cv::GComputation comp(cv::GIn(in, rect), cv::GOut(out));
- // NOTE: We have to normalize U8 tensor
- // so cfgMeanStd() is here
- auto net = cv::gapi::onnx::Params<SqueezNet> { model_path }.cfgMeanStd({ mean }, { std });
- comp.apply(cv::gin(frame, rois.front()),
- cv::gout(out_gapi.front()),
- cv::compile_args(cv::gapi::networks(net)));
- // Validate
- validate();
- }
- TEST_F(ONNXMediaFrame, InferROIYUV)
- {
- useModel("classification/squeezenet/model/squeezenet1.0-9");
- in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false));
- const auto frame = MediaFrame::Create<TestMediaNV12>(m_in_y, m_in_uv);
- // ONNX_API code
- cv::Mat pp;
- cvtColorTwoPlane(m_in_y, m_in_uv, pp, cv::COLOR_YUV2BGR_NV12);
- cv::Mat roi_mat;
- preprocess(pp(rois.front()), roi_mat);
- infer<float>(roi_mat, out_onnx);
- // G_API code
- G_API_NET(SqueezNet, <cv::GMat(cv::GMat)>, "squeeznet");
- cv::GFrame in;
- cv::GOpaque<cv::Rect> rect;
- cv::GMat out = cv::gapi::infer<SqueezNet>(rect, in);
- cv::GComputation comp(cv::GIn(in, rect), cv::GOut(out));
- // NOTE: We have to normalize U8 tensor
- // so cfgMeanStd() is here
- auto net = cv::gapi::onnx::Params<SqueezNet> { model_path }.cfgMeanStd({ mean }, { std });
- comp.apply(cv::gin(frame, rois.front()),
- cv::gout(out_gapi.front()),
- cv::compile_args(cv::gapi::networks(net)));
- // Validate
- validate();
- }
- TEST_F(ONNXMediaFrame, InferListBGR)
- {
- useModel("classification/squeezenet/model/squeezenet1.0-9");
- in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false));
- const auto frame = MediaFrame::Create<TestMediaBGR>(in_mat);
- // ONNX_API code
- for (size_t i = 0; i < rois.size(); ++i) {
- cv::Mat roi_mat;
- preprocess(in_mat(rois[i]), roi_mat);
- infer<float>(roi_mat, out_onnx);
- }
- // G_API code
- G_API_NET(SqueezNet, <cv::GMat(cv::GMat)>, "squeeznet");
- cv::GFrame in;
- cv::GArray<cv::Rect> rr;
- cv::GArray<cv::GMat> out = cv::gapi::infer<SqueezNet>(rr, in);
- cv::GComputation comp(cv::GIn(in, rr), cv::GOut(out));
- // NOTE: We have to normalize U8 tensor
- // so cfgMeanStd() is here
- auto net = cv::gapi::onnx::Params<SqueezNet> { model_path }.cfgMeanStd({ mean }, { std });
- comp.apply(cv::gin(frame, rois),
- cv::gout(out_gapi),
- cv::compile_args(cv::gapi::networks(net)));
- // Validate
- validate();
- }
- TEST_F(ONNXMediaFrame, InferListYUV)
- {
- useModel("classification/squeezenet/model/squeezenet1.0-9");
- in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false));
- const auto frame = MediaFrame::Create<TestMediaNV12>(m_in_y, m_in_uv);
- // ONNX_API code
- cv::Mat pp;
- cvtColorTwoPlane(m_in_y, m_in_uv, pp, cv::COLOR_YUV2BGR_NV12);
- for (size_t i = 0; i < rois.size(); ++i) {
- cv::Mat roi_mat;
- preprocess(pp(rois[i]), roi_mat);
- infer<float>(roi_mat, out_onnx);
- }
- // G_API code
- G_API_NET(SqueezNet, <cv::GMat(cv::GMat)>, "squeeznet");
- cv::GFrame in;
- cv::GArray<cv::Rect> rr;
- cv::GArray<cv::GMat> out = cv::gapi::infer<SqueezNet>(rr, in);
- cv::GComputation comp(cv::GIn(in, rr), cv::GOut(out));
- // NOTE: We have to normalize U8 tensor
- // so cfgMeanStd() is here
- auto net = cv::gapi::onnx::Params<SqueezNet> { model_path }.cfgMeanStd({ mean }, { std });
- comp.apply(cv::gin(frame, rois),
- cv::gout(out_gapi),
- cv::compile_args(cv::gapi::networks(net)));
- // Validate
- validate();
- }
- TEST_F(ONNXRCNN, InferWithDisabledOut)
- {
- useModel("object_detection_segmentation/faster-rcnn/model/FasterRCNN-10");
- in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false));
- cv::Mat pp;
- preprocess(in_mat, pp);
- // ONNX_API code
- infer<float>(pp, out_onnx, {"6379", "6383"});
- // G_API code
- using FRCNNOUT = std::tuple<cv::GMat, cv::GMat>;
- G_API_NET(FasterRCNN, <FRCNNOUT(cv::GMat)>, "FasterRCNN");
- auto net = cv::gapi::onnx::Params<FasterRCNN>{model_path}
- .cfgOutputLayers({"out1", "out2"})
- .cfgPostProc({cv::GMatDesc{CV_32F, {7,4}},
- cv::GMatDesc{CV_32F, {7}}}, remapRCNNPortsDO, {"6383", "6379"});
- cv::GMat in, out1, out2;
- std::tie(out1, out2) = cv::gapi::infer<FasterRCNN>(in);
- cv::GComputation comp(cv::GIn(in), cv::GOut(out1, out2));
- out_gapi.resize(num_out);
- comp.apply(cv::gin(pp),
- cv::gout(out_gapi[0], out_gapi[1]),
- cv::compile_args(cv::gapi::networks(net)));
- // Validate
- validate<float>(-1.f);
- validate<float>(-1.f);
- }
- TEST_F(ONNXMediaFrame, InferList2BGR)
- {
- useModel("classification/squeezenet/model/squeezenet1.0-9");
- in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false));
- const auto frame = MediaFrame::Create<TestMediaBGR>(in_mat);
- // ONNX_API code
- for (size_t i = 0; i < rois.size(); ++i) {
- cv::Mat roi_mat;
- preprocess(in_mat(rois[i]), roi_mat);
- infer<float>(roi_mat, out_onnx);
- }
- // G_API code
- G_API_NET(SqueezNet, <cv::GMat(cv::GMat)>, "squeeznet");
- cv::GFrame in;
- cv::GArray<cv::Rect> rr;
- cv::GArray<cv::GMat> out = cv::gapi::infer2<SqueezNet>(in, rr);
- cv::GComputation comp(cv::GIn(in, rr), cv::GOut(out));
- // NOTE: We have to normalize U8 tensor
- // so cfgMeanStd() is here
- auto net = cv::gapi::onnx::Params<SqueezNet> { model_path }.cfgMeanStd({ mean }, { std });
- comp.apply(cv::gin(frame, rois),
- cv::gout(out_gapi),
- cv::compile_args(cv::gapi::networks(net)));
- // Validate
- validate();
- }
- TEST_F(ONNXMediaFrame, InferList2YUV)
- {
- useModel("classification/squeezenet/model/squeezenet1.0-9");
- in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false));
- const auto frame = MediaFrame::Create<TestMediaNV12>(m_in_y, m_in_uv);
- // ONNX_API code
- cv::Mat pp;
- cvtColorTwoPlane(m_in_y, m_in_uv, pp, cv::COLOR_YUV2BGR_NV12);
- for (size_t i = 0; i < rois.size(); ++i) {
- cv::Mat roi_mat;
- preprocess(pp(rois[i]), roi_mat);
- infer<float>(roi_mat, out_onnx);
- }
- // G_API code
- G_API_NET(SqueezNet, <cv::GMat(cv::GMat)>, "squeeznet");
- cv::GFrame in;
- cv::GArray<cv::Rect> rr;
- cv::GArray<cv::GMat> out = cv::gapi::infer2<SqueezNet>(in, rr);
- cv::GComputation comp(cv::GIn(in, rr), cv::GOut(out));
- // NOTE: We have to normalize U8 tensor
- // so cfgMeanStd() is here
- auto net = cv::gapi::onnx::Params<SqueezNet> { model_path }.cfgMeanStd({ mean }, { std });
- comp.apply(cv::gin(frame, rois),
- cv::gout(out_gapi),
- cv::compile_args(cv::gapi::networks(net)));
- // Validate
- validate();
- }
- TEST_F(ONNXYoloV3, InferConstInput)
- {
- useModel("object_detection_segmentation/yolov3/model/yolov3-10");
- in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false));
- constructYoloInputs(in_mat);
- // ONNX_API code
- infer<float>(ins, out_onnx);
- // G_API code
- using OUT = std::tuple<cv::GMat, cv::GMat, cv::GMat>;
- G_API_NET(YoloNet, <OUT(cv::GMat)>, "yolov3");
- auto net = cv::gapi::onnx::Params<YoloNet>{model_path}
- .constInput("image_shape", ins[1])
- .cfgInputLayers({"input_1"})
- .cfgOutputLayers({"out1", "out2", "out3"})
- .cfgPostProc({cv::GMatDesc{CV_32F, {1, 10000, 4}},
- cv::GMatDesc{CV_32F, {1, 80, 10000}},
- cv::GMatDesc{CV_32S, {5, 3}}}, remapYoloV3);
- cv::GMat in, out1, out2, out3;
- std::tie(out1, out2, out3) = cv::gapi::infer<YoloNet>(in);
- cv::GComputation comp(cv::GIn(in), cv::GOut(out1, out2, out3));
- out_gapi.resize(num_out);
- comp.apply(cv::gin(ins[0]),
- cv::gout(out_gapi[0], out_gapi[1], out_gapi[2]),
- cv::compile_args(cv::gapi::networks(net)));
- // Validate
- validate<float>(-1.f);
- validate<float>(-1.f);
- validate<int>(-1);
- }
- TEST_F(ONNXYoloV3, InferBSConstInput)
- {
- // This test checks the case when a const input is used
- // and all input layer names are specified.
- // Const input has the advantage. It is expected behavior.
- useModel("object_detection_segmentation/yolov3/model/yolov3-10");
- in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false));
- constructYoloInputs(in_mat);
- // Tensor with incorrect image size
- // is used for check case when InputLayers and constInput have same names
- cv::Mat bad_shape;
- bad_shape.create(cv::Size(2, 1), CV_32F);
- float* ptr = bad_shape.ptr<float>();
- ptr[0] = 590;
- ptr[1] = 12;
- // ONNX_API code
- infer<float>(ins, out_onnx);
- // G_API code
- using OUT = std::tuple<cv::GMat, cv::GMat, cv::GMat>;
- G_API_NET(YoloNet, <OUT(cv::GMat, cv::GMat)>, "yolov3");
- auto net = cv::gapi::onnx::Params<YoloNet>{model_path}
- // Data from const input will be used to infer
- .constInput("image_shape", ins[1])
- // image_shape - const_input has same name
- .cfgInputLayers({"input_1", "image_shape"})
- .cfgOutputLayers({"out1", "out2", "out3"})
- .cfgPostProc({cv::GMatDesc{CV_32F, {1, 10000, 4}},
- cv::GMatDesc{CV_32F, {1, 80, 10000}},
- cv::GMatDesc{CV_32S, {5, 3}}}, remapYoloV3);
- cv::GMat in1, in2, out1, out2, out3;
- std::tie(out1, out2, out3) = cv::gapi::infer<YoloNet>(in1, in2);
- cv::GComputation comp(cv::GIn(in1, in2), cv::GOut(out1, out2, out3));
- out_gapi.resize(num_out);
- comp.apply(cv::gin(ins[0], bad_shape),
- cv::gout(out_gapi[0], out_gapi[1], out_gapi[2]),
- cv::compile_args(cv::gapi::networks(net)));
- // Validate
- validate<float>(-1.f);
- validate<float>(-1.f);
- validate<int>(-1);
- }
- TEST_F(ONNXRCNN, ConversionInt64to32)
- {
- useModel("object_detection_segmentation/faster-rcnn/model/FasterRCNN-10");
- in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false));
- cv::Mat dst;
- preprocess(in_mat, dst);
- // ONNX_API code
- infer<float>(dst, out_onnx);
- // G_API code
- using FRCNNOUT = std::tuple<cv::GMat,cv::GMat,cv::GMat>;
- G_API_NET(FasterRCNN, <FRCNNOUT(cv::GMat)>, "FasterRCNN");
- auto net = cv::gapi::onnx::Params<FasterRCNN>{model_path}
- .cfgOutputLayers({"out1", "out2", "out3"})
- .cfgPostProc({cv::GMatDesc{CV_32F, {7,4}},
- cv::GMatDesc{CV_32S, {7}},
- cv::GMatDesc{CV_32F, {7}}}, remapRCNNPortsC);
- cv::GMat in, out1, out2, out3;
- std::tie(out1, out2, out3) = cv::gapi::infer<FasterRCNN>(in);
- cv::GComputation comp(cv::GIn(in), cv::GOut(out1, out2, out3));
- out_gapi.resize(num_out);
- comp.apply(cv::gin(dst),
- cv::gout(out_gapi[0], out_gapi[1], out_gapi[2]),
- cv::compile_args(cv::gapi::networks(net)));
- // Validate
- validate<float>(-1.f);
- validate<int>(-1);
- validate<float>(-1.f);
- }
- TEST_F(ONNXWithRemap, InferOutReallocation)
- {
- useModel("object_detection_segmentation/ssd-mobilenetv1/model/ssd_mobilenet_v1_10");
- in_mat = cv::imread(findDataFile("cv/dpm/cat.png", false));
- // G_API code
- G_API_NET(MobileNet, <cv::GMat(cv::GMat)>, "ssd_mobilenet");
- auto net = cv::gapi::onnx::Params<MobileNet>{model_path}
- .cfgOutputLayers({"detection_boxes"})
- .cfgPostProc({cv::GMatDesc{CV_32F, {1,100,4}}}, reallocSSDPort);
- cv::GMat in;
- cv::GMat out1;
- out1 = cv::gapi::infer<MobileNet>(in);
- cv::GComputation comp(cv::GIn(in), cv::GOut(out1));
- EXPECT_THROW(comp.apply(cv::gin(in_mat),
- cv::gout(out_gapi[0]),
- cv::compile_args(cv::gapi::networks(net))), std::exception);
- }
- } // namespace opencv_test
- #endif // HAVE_ONNX
|