From 0e4b5b88dcc379259c5e6e530c25181916abbda9 Mon Sep 17 00:00:00 2001 From: Ruslan Garnov Date: Thu, 5 Nov 2020 02:27:32 +0300 Subject: [PATCH] Added support of 1x1x1xN input for parseYolo --- modules/gapi/src/backends/cpu/gnnparsers.cpp | 34 +++++++++++++++---- modules/gapi/test/common/gapi_core_tests.hpp | 2 +- .../gapi/test/common/gapi_core_tests_inl.hpp | 2 +- .../test/common/gapi_parsers_tests_common.hpp | 19 +++++++++-- modules/gapi/test/cpu/gapi_core_tests_cpu.cpp | 7 +++- 5 files changed, 52 insertions(+), 12 deletions(-) diff --git a/modules/gapi/src/backends/cpu/gnnparsers.cpp b/modules/gapi/src/backends/cpu/gnnparsers.cpp index 234382d530..a5e4bf5f85 100644 --- a/modules/gapi/src/backends/cpu/gnnparsers.cpp +++ b/modules/gapi/src/backends/cpu/gnnparsers.cpp @@ -246,6 +246,28 @@ void parseSSD(const cv::Mat& in_ssd_result, } } +static void checkYoloDims(const MatSize& dims) { + const auto d = dims.dims(); + // Accept 1x13x13xN and 13x13xN + GAPI_Assert(d >= 2); + if (d >= 3) { + if (dims[d-2] == 13) { + GAPI_Assert(dims[d-1]%5 == 0); + GAPI_Assert(dims[d-2] == 13); + GAPI_Assert(dims[d-3] == 13); + for (int i = 0; i < d-3; i++) { + GAPI_Assert(dims[i] == 1); + } + return; + } + } + // Accept 1x1x1xN, 1x1xN, 1xN + GAPI_Assert(dims[d-1]%(5*13*13) == 0); + for (int i = 0; i < d-1; i++) { + GAPI_Assert(dims[i] == 1); + } +} + void parseYolo(const cv::Mat& in_yolo_result, const cv::Size& in_size, const float confidence_threshold, @@ -255,12 +277,12 @@ void parseYolo(const cv::Mat& in_yolo_result, std::vector& out_labels) { const auto& dims = in_yolo_result.size; - GAPI_Assert(dims.dims() == 4); - GAPI_Assert(dims[0] == 1); - GAPI_Assert(dims[1] == 13); - GAPI_Assert(dims[2] == 13); - GAPI_Assert(dims[3] % 5 == 0); // 5 boxes - const auto num_classes = dims[3] / 5 - 5; + checkYoloDims(dims); + int acc = 1; + for (int i = 0; i < dims.dims(); i++) { + acc *= dims[i]; + } + const auto num_classes = acc/(5*13*13)-5; GAPI_Assert(num_classes > 0); GAPI_Assert(0 < nms_threshold && nms_threshold <= 1); out_boxes.clear(); diff --git a/modules/gapi/test/common/gapi_core_tests.hpp b/modules/gapi/test/common/gapi_core_tests.hpp index 4a0a7641f9..889e32f1c1 100644 --- a/modules/gapi/test/common/gapi_core_tests.hpp +++ b/modules/gapi/test/common/gapi_core_tests.hpp @@ -157,7 +157,7 @@ GAPI_TEST_EXT_BASE_FIXTURE(ParseSSDBLTest, ParserSSDTest, initNothing, GAPI_TEST_EXT_BASE_FIXTURE(ParseSSDTest, ParserSSDTest, initNothing, FIXTURE_API(float, bool, bool), 3, confidence_threshold, alignment_to_square, filter_out_of_bounds) GAPI_TEST_EXT_BASE_FIXTURE(ParseYoloTest, ParserYoloTest, initNothing, - FIXTURE_API(float, float, int), 3, confidence_threshold, nms_threshold, num_classes) + FIXTURE_API(float, float, int, std::pair), 4, confidence_threshold, nms_threshold, num_classes, dims_config) GAPI_TEST_FIXTURE(SizeTest, initMatrixRandU, <>, 0) GAPI_TEST_FIXTURE(SizeRTest, initNothing, <>, 0) } // opencv_test diff --git a/modules/gapi/test/common/gapi_core_tests_inl.hpp b/modules/gapi/test/common/gapi_core_tests_inl.hpp index 1a167ad5ea..045b556369 100644 --- a/modules/gapi/test/common/gapi_core_tests_inl.hpp +++ b/modules/gapi/test/common/gapi_core_tests_inl.hpp @@ -1666,7 +1666,7 @@ TEST_P(ParseSSDTest, ParseTest) TEST_P(ParseYoloTest, ParseTest) { - cv::Mat in_mat = generateYoloOutput(num_classes); + cv::Mat in_mat = generateYoloOutput(num_classes, dims_config); auto anchors = cv::gapi::nn::parsers::GParseYolo::defaultAnchors(); std::vector boxes_gapi, boxes_ref; std::vector labels_gapi, labels_ref; diff --git a/modules/gapi/test/common/gapi_parsers_tests_common.hpp b/modules/gapi/test/common/gapi_parsers_tests_common.hpp index 127a1c5a5e..91dcca7b3e 100644 --- a/modules/gapi/test/common/gapi_parsers_tests_common.hpp +++ b/modules/gapi/test/common/gapi_parsers_tests_common.hpp @@ -225,13 +225,26 @@ private: class ParserYoloTest { public: - cv::Mat generateYoloOutput(const int num_classes) + cv::Mat generateYoloOutput(const int num_classes, std::pair dims_config = {false, 4}) { - std::vector dims = { 1, 13, 13, (num_classes + 5) * 5 }; + bool one_dim = false; + int num_dims = 0; + std::tie(one_dim, num_dims) = dims_config; + GAPI_Assert(num_dims <= 4); + GAPI_Assert((!one_dim && num_dims >= 3) || + ( one_dim && num_dims >= 1)); + std::vector dims(num_dims, 1); + if (one_dim) { + dims.back() = (num_classes+5)*5*13*13; + } else { + dims.back() = (num_classes+5)*5; + dims[num_dims-2] = 13; + dims[num_dims-3] = 13; + } cv::Mat mat(dims, CV_32FC1); auto data = mat.ptr(); - const size_t range = dims[0] * dims[1] * dims[2] * dims[3]; + const size_t range = std::accumulate(dims.begin(), dims.end(), 1, std::multiplies()); for (size_t i = 0; i < range; ++i) { data[i] = static_cast(std::rand()) / RAND_MAX; diff --git a/modules/gapi/test/cpu/gapi_core_tests_cpu.cpp b/modules/gapi/test/cpu/gapi_core_tests_cpu.cpp index 53faa28178..595b63dd1f 100644 --- a/modules/gapi/test/cpu/gapi_core_tests_cpu.cpp +++ b/modules/gapi/test/cpu/gapi_core_tests_cpu.cpp @@ -531,7 +531,12 @@ INSTANTIATE_TEST_CASE_P(ParseTestCPU, ParseYoloTest, Values(CORE_CPU), Values(0.3f, 0.5f, 0.7f), Values(0.5f, 1.0f), - Values(80, 7))); + Values(80, 7), + Values(std::make_pair(false, 3), + std::make_pair(false, 4), + std::make_pair(true, 2), + std::make_pair(true, 3), + std::make_pair(true, 4)))); INSTANTIATE_TEST_CASE_P(SizeTestCPU, SizeTest, Combine(Values(CV_8UC1, CV_8UC3, CV_32FC1),