From: Sergey Ivanov Date: Tue, 25 May 2021 17:36:01 +0000 (+0300) Subject: Merge pull request #20107 from sivanov-work:gapi_transpose_op X-Git-Tag: accepted/tizen/unified/20220125.121719~1^2~68 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=2b06208bbd4c778f12241d51fac4e9f41fc1ad49;p=platform%2Fupstream%2Fopencv.git Merge pull request #20107 from sivanov-work:gapi_transpose_op G-API: Add transpose operation * Add kernels decl & def * Add draft for UT * Fix UT for Transpose * Add perf test * Fix docs * Apply comments --- diff --git a/modules/gapi/include/opencv2/gapi/core.hpp b/modules/gapi/include/opencv2/gapi/core.hpp index 5973151..cb8a612 100644 --- a/modules/gapi/include/opencv2/gapi/core.hpp +++ b/modules/gapi/include/opencv2/gapi/core.hpp @@ -575,6 +575,12 @@ namespace core { return std::make_tuple(empty_gopaque_desc(), empty_array_desc(), empty_array_desc()); } }; + + G_TYPED_KERNEL(GTranspose, , "org.opencv.core.transpose") { + static GMatDesc outMeta(GMatDesc in) { + return in.withSize({in.size.height, in.size.width}); + } + }; } // namespace core namespace streaming { @@ -1927,6 +1933,21 @@ GAPI_EXPORTS std::tuple,GArray,GArray> kmeans(const GArray& data, const int K, const GArray& bestLabels, const TermCriteria& criteria, const int attempts, const KmeansFlags flags); + +/** @brief Transposes a matrix. + +The function transposes the matrix: +\f[\texttt{dst} (i,j) = \texttt{src} (j,i)\f] + +@note + - Function textual ID is "org.opencv.core.transpose" + - No complex conjugation is done in case of a complex matrix. It should be done separately if needed. + +@param src input array. +*/ +GAPI_EXPORTS GMat transpose(const GMat& src); + + namespace streaming { /** @brief Gets dimensions from Mat. diff --git a/modules/gapi/perf/common/gapi_core_perf_tests.hpp b/modules/gapi/perf/common/gapi_core_perf_tests.hpp index be88e5a..3fd543b 100644 --- a/modules/gapi/perf/common/gapi_core_perf_tests.hpp +++ b/modules/gapi/perf/common/gapi_core_perf_tests.hpp @@ -79,6 +79,7 @@ namespace opencv_test cv::GCompileArgs>> {}; class KMeans3DPerfTest : public TestPerfParams> {}; + class TransposePerfTest : public TestPerfParams> {}; class ResizePerfTest : public TestPerfParams> {}; class ResizeFxFyPerfTest : public TestPerfParams> {}; class ParseSSDBLPerfTest : public TestPerfParams>, public ParserSSDTest {}; diff --git a/modules/gapi/perf/common/gapi_core_perf_tests_inl.hpp b/modules/gapi/perf/common/gapi_core_perf_tests_inl.hpp index 7fe0ec4..6dfc0b2 100644 --- a/modules/gapi/perf/common/gapi_core_perf_tests_inl.hpp +++ b/modules/gapi/perf/common/gapi_core_perf_tests_inl.hpp @@ -2036,6 +2036,42 @@ PERF_TEST_P_(KMeans3DPerfTest, TestPerformance) //------------------------------------------------------------------------------ +PERF_TEST_P_(TransposePerfTest, TestPerformance) +{ + compare_f cmpF; + cv::Size sz_in; + MatType type = -1; + cv::GCompileArgs compile_args; + std::tie(cmpF, sz_in, type, compile_args) = GetParam(); + + initMatrixRandU(type, sz_in, type, false); + + // OpenCV code /////////////////////////////////////////////////////////// + cv::transpose(in_mat1, out_mat_ocv); + + // G-API code //////////////////////////////////////////////////////////// + cv::GMat in; + auto out = cv::gapi::transpose(in); + cv::GComputation c(cv::GIn(in), cv::GOut(out)); + + // Warm-up graph engine: + c.apply(cv::gin(in_mat1), cv::gout(out_mat_gapi), std::move(compile_args)); + + TEST_CYCLE() + { + c.apply(cv::gin(in_mat1), cv::gout(out_mat_gapi)); + } + + // Comparison //////////////////////////////////////////////////////////// + { + EXPECT_TRUE(cmpF(out_mat_gapi, out_mat_ocv)); + } + + SANITY_CHECK_NOTHING(); +} + +//------------------------------------------------------------------------------ + PERF_TEST_P_(ResizePerfTest, TestPerformance) { compare_f cmpF = get<0>(GetParam()); diff --git a/modules/gapi/perf/cpu/gapi_core_perf_tests_cpu.cpp b/modules/gapi/perf/cpu/gapi_core_perf_tests_cpu.cpp index 8385169..871d417 100644 --- a/modules/gapi/perf/cpu/gapi_core_perf_tests_cpu.cpp +++ b/modules/gapi/perf/cpu/gapi_core_perf_tests_cpu.cpp @@ -311,6 +311,14 @@ INSTANTIATE_TEST_CASE_P(KMeans3DPerfTestCPU, KMeans3DPerfTest, cv::KMEANS_PP_CENTERS | cv::KMEANS_USE_INITIAL_LABELS), Values(cv::compile_args(CORE_CPU)))); +INSTANTIATE_TEST_CASE_P(TransposePerfTestCPU, TransposePerfTest, + Combine(Values(AbsExact().to_compare_f()), + Values(szSmall128, szVGA, sz720p, sz1080p), + Values(CV_8UC1, CV_16UC1, CV_16SC1, CV_32FC1, + CV_8UC2, CV_16UC2, CV_16SC2, CV_32FC2, + CV_8UC3, CV_16UC3, CV_16SC3, CV_32FC3), + Values(cv::compile_args(CORE_CPU)))); + INSTANTIATE_TEST_CASE_P(ResizePerfTestCPU, ResizePerfTest, Combine(Values(AbsExact().to_compare_f()), Values(CV_8UC1, CV_16UC1, CV_16SC1), diff --git a/modules/gapi/perf/gpu/gapi_core_perf_tests_gpu.cpp b/modules/gapi/perf/gpu/gapi_core_perf_tests_gpu.cpp index 9557996..4a38fdb 100644 --- a/modules/gapi/perf/gpu/gapi_core_perf_tests_gpu.cpp +++ b/modules/gapi/perf/gpu/gapi_core_perf_tests_gpu.cpp @@ -276,6 +276,14 @@ INSTANTIATE_TEST_CASE_P(ConvertToPerfTestGPU, ConvertToPerfTest, Values(0.0), Values(cv::compile_args(CORE_GPU)))); +INSTANTIATE_TEST_CASE_P(TransposePerfTestGPU, TransposePerfTest, + Combine(Values(AbsExact().to_compare_f()), + Values(szSmall128, szVGA, sz720p, sz1080p), + Values(CV_8UC1, CV_16UC1, CV_16SC1, CV_32FC1, + CV_8UC2, CV_16UC2, CV_16SC2, CV_32FC2, + CV_8UC3, CV_16UC3, CV_16SC3, CV_32FC3), + Values(cv::compile_args(CORE_GPU)))); + INSTANTIATE_TEST_CASE_P(ResizePerfTestGPU, ResizePerfTest, Combine(Values(AbsSimilarPoints(2, 0.05).to_compare_f()), Values(CV_8UC1, CV_16UC1, CV_16SC1), diff --git a/modules/gapi/src/api/kernels_core.cpp b/modules/gapi/src/api/kernels_core.cpp index 3196b5d..4485e36 100644 --- a/modules/gapi/src/api/kernels_core.cpp +++ b/modules/gapi/src/api/kernels_core.cpp @@ -417,6 +417,12 @@ std::tuple,GArray,GArray> kmeans(const GArray streaming::size(const GMat& src) { return streaming::GSize::on(src); diff --git a/modules/gapi/src/backends/cpu/gcpucore.cpp b/modules/gapi/src/backends/cpu/gcpucore.cpp index b0bce41..168a2f9 100644 --- a/modules/gapi/src/backends/cpu/gcpucore.cpp +++ b/modules/gapi/src/backends/cpu/gcpucore.cpp @@ -634,6 +634,15 @@ GAPI_OCV_KERNEL(GCPUKMeans3D, cv::gapi::core::GKMeans3D) } }; +GAPI_OCV_KERNEL(GCPUTranspose, cv::gapi::core::GTranspose) +{ + static void run(const cv::Mat& in, cv::Mat& out) + { + cv::transpose(in, out); + } +}; + + GAPI_OCV_KERNEL(GCPUParseSSDBL, cv::gapi::nn::parsers::GParseSSDBL) { static void run(const cv::Mat& in_ssd_result, @@ -774,6 +783,7 @@ cv::gapi::GKernelPackage cv::gapi::core::cpu::kernels() , GCPUKMeansNDNoInit , GCPUKMeans2D , GCPUKMeans3D + , GCPUTranspose , GCPUParseSSDBL , GOCVParseSSD , GCPUParseYolo diff --git a/modules/gapi/src/backends/ocl/goclcore.cpp b/modules/gapi/src/backends/ocl/goclcore.cpp index afe211d..d74d521 100644 --- a/modules/gapi/src/backends/ocl/goclcore.cpp +++ b/modules/gapi/src/backends/ocl/goclcore.cpp @@ -522,6 +522,15 @@ GAPI_OCL_KERNEL(GOCLConvertTo, cv::gapi::core::GConvertTo) } }; + +GAPI_OCL_KERNEL(GOCLTranspose, cv::gapi::core::GTranspose) +{ + static void run(const cv::UMat& in, cv::UMat& out) + { + cv::transpose(in, out); + } +}; + cv::gapi::GKernelPackage cv::gapi::core::ocl::kernels() { static auto pkg = cv::gapi::kernels @@ -586,6 +595,7 @@ cv::gapi::GKernelPackage cv::gapi::core::ocl::kernels() , GOCLConcatVert , GOCLLUT , GOCLConvertTo + , GOCLTranspose >(); return pkg; } diff --git a/modules/gapi/test/common/gapi_core_tests.hpp b/modules/gapi/test/common/gapi_core_tests.hpp index e878282..0d8015e 100644 --- a/modules/gapi/test/common/gapi_core_tests.hpp +++ b/modules/gapi/test/common/gapi_core_tests.hpp @@ -154,6 +154,8 @@ GAPI_TEST_FIXTURE(WarpAffineTest, initMatrixRandU, GAPI_TEST_FIXTURE(KMeansNDTest, initMatrixRandU, FIXTURE_API(CompareMats, int, cv::KmeansFlags), 3, cmpF, K, flags) GAPI_TEST_FIXTURE(KMeans2DTest, initNothing, FIXTURE_API(int, cv::KmeansFlags), 2, K, flags) GAPI_TEST_FIXTURE(KMeans3DTest, initNothing, FIXTURE_API(int, cv::KmeansFlags), 2, K, flags) +GAPI_TEST_FIXTURE(TransposeTest, initMatrixRandU, FIXTURE_API(CompareMats), 1, cmpF) + GAPI_TEST_EXT_BASE_FIXTURE(ParseSSDBLTest, ParserSSDTest, initNothing, FIXTURE_API(float, int), 2, confidence_threshold, filter_label) diff --git a/modules/gapi/test/common/gapi_core_tests_inl.hpp b/modules/gapi/test/common/gapi_core_tests_inl.hpp index d4760e8..d9287a1 100644 --- a/modules/gapi/test/common/gapi_core_tests_inl.hpp +++ b/modules/gapi/test/common/gapi_core_tests_inl.hpp @@ -1403,6 +1403,23 @@ TEST_P(KMeans3DTest, AccuracyTest) kmeansTestBody(in_vector, sz, type, K, flags, getCompileArgs()); } +TEST_P(TransposeTest, Test) +{ + // G-API code ////////////////////////////////////////////////////////////// + cv::GMat in; + auto out = cv::gapi::transpose(in); + + cv::GComputation c(in, out); + c.apply(in_mat1, out_mat_gapi, getCompileArgs()); + // OpenCV code ///////////////////////////////////////////////////////////// + { + cv::transpose(in_mat1, out_mat_ocv); + } + // Comparison ////////////////////////////////////////////////////////////// + { + EXPECT_TRUE(cmpF(out_mat_ocv, out_mat_gapi)); + } +} // PLEASE DO NOT PUT NEW ACCURACY TESTS BELOW THIS POINT! ////////////////////// TEST_P(BackendOutputAllocationTest, EmptyOutput) diff --git a/modules/gapi/test/common/gapi_tests_common.hpp b/modules/gapi/test/common/gapi_tests_common.hpp index 7775749..463e994 100644 --- a/modules/gapi/test/common/gapi_tests_common.hpp +++ b/modules/gapi/test/common/gapi_tests_common.hpp @@ -542,6 +542,7 @@ struct TestWithParamsSpecific : public TestWithParamsBase::value` #define GAPI_TEST_FIXTURE(Fixture, InitF, API, Number, ...) \ struct Fixture : public TestWithParams API { \ static_assert(Number == AllParams::specific_params_size, \ diff --git a/modules/gapi/test/cpu/gapi_core_tests_cpu.cpp b/modules/gapi/test/cpu/gapi_core_tests_cpu.cpp index 5a06671..424cf1b 100644 --- a/modules/gapi/test/cpu/gapi_core_tests_cpu.cpp +++ b/modules/gapi/test/cpu/gapi_core_tests_cpu.cpp @@ -551,6 +551,16 @@ INSTANTIATE_TEST_CASE_P(KMeans3DInitTestCPU, KMeans3DTest, Values(cv::KMEANS_RANDOM_CENTERS | cv::KMEANS_USE_INITIAL_LABELS, cv::KMEANS_PP_CENTERS | cv::KMEANS_USE_INITIAL_LABELS))); +INSTANTIATE_TEST_CASE_P(TransposeTestCPU, TransposeTest, + Combine(Values(CV_8UC1, CV_16UC1, CV_16SC1, CV_32FC1, + CV_8UC2, CV_16UC2, CV_16SC2, CV_32FC2, + CV_8UC3, CV_16UC3, CV_16SC3, CV_32FC3), + Values(cv::Size(1280, 720), + cv::Size(640, 480), + cv::Size(128, 128)), + Values(-1), + Values(CORE_CPU), + Values(AbsExact().to_compare_obj()))); // PLEASE DO NOT PUT NEW ACCURACY TESTS BELOW THIS POINT! ////////////////////// INSTANTIATE_TEST_CASE_P(BackendOutputAllocationTestCPU, BackendOutputAllocationTest, diff --git a/modules/gapi/test/gpu/gapi_core_tests_gpu.cpp b/modules/gapi/test/gpu/gapi_core_tests_gpu.cpp index 4e5efe6..2cc859c 100644 --- a/modules/gapi/test/gpu/gapi_core_tests_gpu.cpp +++ b/modules/gapi/test/gpu/gapi_core_tests_gpu.cpp @@ -402,6 +402,16 @@ INSTANTIATE_TEST_CASE_P(ConcatVertTestGPU, ConcatVertTest, Values(-1), Values(CORE_GPU))); +INSTANTIATE_TEST_CASE_P(TransposeTestGPU, TransposeTest, + Combine(Values(CV_8UC1, CV_16UC1, CV_16SC1, CV_32FC1, + CV_8UC2, CV_16UC2, CV_16SC2, CV_32FC2, + CV_8UC3, CV_16UC3, CV_16SC3, CV_32FC3), + Values(cv::Size(1280, 720), + cv::Size(640, 480), + cv::Size(128, 128)), + Values(-1), + Values(CORE_GPU), + Values(AbsExact().to_compare_obj()))); // PLEASE DO NOT PUT NEW ACCURACY TESTS BELOW THIS POINT! ////////////////////// INSTANTIATE_TEST_CASE_P(BackendOutputAllocationTestGPU, BackendOutputAllocationTest,