From 74b77a4c9753be0fbee303bba615a1ed13a61142 Mon Sep 17 00:00:00 2001 From: Anton Potapov Date: Fri, 4 Sep 2020 15:24:36 +0300 Subject: [PATCH] [PP GAPI] - Generic precision conversion kernel (#1897) - U16toF32 conversion kernel converted to more generic ConvDepth one - U16 <-> F32 conversion only are supported for now - kernel is not used in the preprocessing graph yet - tests are extended --- .../preprocessing/ie_preprocess_gapi_kernels.cpp | 49 +++++++++++++++++----- .../preprocessing/ie_preprocess_gapi_kernels.hpp | 9 ++-- .../ie_preprocess_gapi_kernels_impl.hpp | 3 ++ .../fluid_preproc/common/fluid_tests.cpp | 18 ++++---- .../fluid_preproc/common/fluid_tests.hpp | 7 +++- .../fluid_preproc/cpu/fluid_tests_cpu.cpp | 8 ++-- .../fluid_test_computations.cpp | 14 +++---- .../fluid_test_computations.hpp | 4 +- 8 files changed, 78 insertions(+), 34 deletions(-) diff --git a/inference-engine/src/preprocessing/ie_preprocess_gapi_kernels.cpp b/inference-engine/src/preprocessing/ie_preprocess_gapi_kernels.cpp index 53c1fee..654b625 100644 --- a/inference-engine/src/preprocessing/ie_preprocess_gapi_kernels.cpp +++ b/inference-engine/src/preprocessing/ie_preprocess_gapi_kernels.cpp @@ -2231,23 +2231,52 @@ GAPI_FLUID_KERNEL(FI420toRGB, I420toRGB, false) { } }; -GAPI_FLUID_KERNEL(FU16toF32, U16toF32, false) { +namespace { + template + void convert_precision(const uint8_t* src, uint8_t* dst, const int width) { + const auto *in = reinterpret_cast(src); + auto *out = reinterpret_cast(dst); + + for (int i = 0; i < width; i++) { + out[i] = saturate_cast(in[i]); + } + } +} + +GAPI_FLUID_KERNEL(FConvertDepth, ConvertDepth, false) { static const int Window = 1; - static void run(const cv::gapi::fluid::View& src, cv::gapi::fluid::Buffer& dst) { - GAPI_Assert(src.meta().depth == CV_16U); - GAPI_Assert(dst.meta().depth == CV_32F); + static void run(const cv::gapi::fluid::View& src, int depth, cv::gapi::fluid::Buffer& dst) { + GAPI_Assert(src.meta().depth == CV_16U || src.meta().depth == CV_32F); + GAPI_Assert(dst.meta().depth == CV_32F || dst.meta().depth == CV_16U); GAPI_Assert(src.meta().chan == 1); GAPI_Assert(dst.meta().chan == 1); GAPI_Assert(src.length() == dst.length()); - const auto *in = src.InLine(0); - auto *out = dst.OutLine(); + constexpr unsigned supported_types_n = 2; + using p_f = void (*)( const uint8_t* src, uint8_t* dst, const int width); + using table_string_t = std::array; + + constexpr std::array func_table = { + table_string_t{convert_precision, convert_precision}, + table_string_t{convert_precision, convert_precision} + }; + + auto depth_to_index = [](int depth){ + switch (depth) { + case CV_16U: return 0; + case CV_32F: return 1; + default: GAPI_Assert(!"not supported depth"); return -1; + } + }; + const auto *in = src.InLineB(0); + auto *out = dst.OutLineB(); auto const width = dst.length(); - for (int i = 0; i < width; i++) { - out[i] = in[i]; - } + auto const src_index = depth_to_index(src.meta().depth); + auto const dst_index = depth_to_index(dst.meta().depth); + + (func_table[src_index][dst_index])(in, out, width); } }; @@ -2277,7 +2306,7 @@ cv::gapi::GKernelPackage preprocKernels() { , FSplit4 , FNV12toRGB , FI420toRGB - , FU16toF32 + , FConvertDepth >(); } diff --git a/inference-engine/src/preprocessing/ie_preprocess_gapi_kernels.hpp b/inference-engine/src/preprocessing/ie_preprocess_gapi_kernels.hpp index 8caacd2..7b6acdb 100644 --- a/inference-engine/src/preprocessing/ie_preprocess_gapi_kernels.hpp +++ b/inference-engine/src/preprocessing/ie_preprocess_gapi_kernels.hpp @@ -143,11 +143,12 @@ namespace gapi { } }; - G_TYPED_KERNEL(U16toF32, , "com.intel.ie.u16tof32") { - static cv::GMatDesc outMeta(const cv::GMatDesc& in) { - GAPI_Assert(in.depth == CV_16U); + G_TYPED_KERNEL(ConvertDepth, , "com.intel.ie.ConvertDepth") { + static cv::GMatDesc outMeta(const cv::GMatDesc& in, int depth) { + GAPI_Assert(in.depth == CV_16U || in.depth == CV_32F); + GAPI_Assert(depth == CV_32F || depth == CV_16U); - return in.withDepth(CV_32F); + return in.withDepth(depth); } }; diff --git a/inference-engine/src/preprocessing/ie_preprocess_gapi_kernels_impl.hpp b/inference-engine/src/preprocessing/ie_preprocess_gapi_kernels_impl.hpp index d34942e..6d5161f 100644 --- a/inference-engine/src/preprocessing/ie_preprocess_gapi_kernels_impl.hpp +++ b/inference-engine/src/preprocessing/ie_preprocess_gapi_kernels_impl.hpp @@ -38,7 +38,10 @@ template<> inline short saturate_cast(int x) { return (std::min)(SHRT_MAX, (std: template<> inline short saturate_cast(float x) { return saturate_cast(static_cast(std::rint(x))); } template<> inline float saturate_cast(float x) { return x; } template<> inline short saturate_cast(short x) { return x; } +template<> inline uint16_t saturate_cast(uint16_t x) { return x; } +template<> inline float saturate_cast(uint16_t x) { return x; } template<> inline uint16_t saturate_cast(int x) { return (std::min)(USHRT_MAX, (std::max)(0, x)); } +template<> inline uint16_t saturate_cast(float x) { return saturate_cast(static_cast(std::rint(x))); } template<> inline uchar saturate_cast(int v) { return (uchar)((unsigned)v <= UCHAR_MAX ? v : v > 0 ? UCHAR_MAX : 0); } //------------------------------------------------------------------------------ diff --git a/inference-engine/tests_deprecated/fluid_preproc/common/fluid_tests.cpp b/inference-engine/tests_deprecated/fluid_preproc/common/fluid_tests.cpp index 479c3e5..8f5a2f0 100644 --- a/inference-engine/tests_deprecated/fluid_preproc/common/fluid_tests.cpp +++ b/inference-engine/tests_deprecated/fluid_preproc/common/fluid_tests.cpp @@ -625,27 +625,31 @@ TEST_P(I420toRGBTestGAPI, AccuracyTest) } } -TEST_P(U16toF32TestGAPI, AccuracyTest) +TEST_P(ConvertDepthTestGAPI, AccuracyTest) { const auto params = GetParam(); - cv::Size sz = std::get<0>(params); - double tolerance = std::get<1>(params); + int in_depth = std::get<0>(params); + int out_depth = std::get<1>(params); + cv::Size sz = std::get<2>(params); + double tolerance = std::get<3>(params); + + const int out_type = CV_MAKETYPE(out_depth,1); - initMatrixRandU(CV_16UC1, sz, CV_32FC1); + initMatrixRandU(CV_MAKETYPE(in_depth,1), sz, out_type); // G-API code ////////////////////////////////////////////////////////////// - FluidU16ToF32Computation cc(to_test(in_mat1), to_test(out_mat_gapi)); + ConvertDepthComputation cc(to_test(in_mat1), to_test(out_mat_gapi), out_mat_gapi.depth()); cc.warmUp(); #if PERF_TEST // iterate testing, and print performance test_ms([&](){ cc.apply(); }, - 400, "U16ToF32 GAPI %s %dx%d", typeToString(CV_16UC1).c_str(), sz.width, sz.height); + 400, "ConvDepth GAPI %s to %s %dx%d", depthToString(in_mat1.depth()).c_str(), depthToString(out_mat_gapi.depth()).c_str(), sz.width, sz.height); #endif // OpenCV code ///////////////////////////////////////////////////////////// { - in_mat1.convertTo(out_mat_ocv, CV_32FC1); + in_mat1.convertTo(out_mat_ocv, out_type); } // Comparison ////////////////////////////////////////////////////////////// { diff --git a/inference-engine/tests_deprecated/fluid_preproc/common/fluid_tests.hpp b/inference-engine/tests_deprecated/fluid_preproc/common/fluid_tests.hpp index fb4535a..012a281 100644 --- a/inference-engine/tests_deprecated/fluid_preproc/common/fluid_tests.hpp +++ b/inference-engine/tests_deprecated/fluid_preproc/common/fluid_tests.hpp @@ -19,7 +19,12 @@ struct NV12toRGBTestGAPI: public TestParams> {}; struct I420toRGBTestGAPI: public TestParams> {}; struct ResizeRoiTestGAPI: public testing::TestWithParam, cv::Rect, double>> {}; struct ResizeRGB8URoiTestGAPI: public testing::TestWithParam, cv::Rect, double>> {}; -struct U16toF32TestGAPI: public TestParams> {}; +struct ConvertDepthTestGAPI: public TestParams> // tolerance +{}; //------------------------------------------------------------------------------ struct ResizeTestIE: public testing::TestWithParam, double>> {}; diff --git a/inference-engine/tests_deprecated/fluid_preproc/cpu/fluid_tests_cpu.cpp b/inference-engine/tests_deprecated/fluid_preproc/cpu/fluid_tests_cpu.cpp index 1a41fcc..954bff9 100644 --- a/inference-engine/tests_deprecated/fluid_preproc/cpu/fluid_tests_cpu.cpp +++ b/inference-engine/tests_deprecated/fluid_preproc/cpu/fluid_tests_cpu.cpp @@ -170,8 +170,10 @@ INSTANTIATE_TEST_CASE_P(I420toRGBTestFluid, I420toRGBTestGAPI, cv::Size( 320, 200)), Values(0))); -INSTANTIATE_TEST_CASE_P(U16toF32TestGAPIFluid, U16toF32TestGAPI, - Combine(Values(cv::Size(3840, 2160), +INSTANTIATE_TEST_CASE_P(ConvertDepthFluid, ConvertDepthTestGAPI, + Combine(Values(CV_16U, CV_32F), + Values(CV_32F, CV_16U), + Values(cv::Size(3840, 2160), cv::Size(1920, 1080), cv::Size(1280, 720), cv::Size(1280, 960), @@ -179,7 +181,7 @@ INSTANTIATE_TEST_CASE_P(U16toF32TestGAPIFluid, U16toF32TestGAPI, cv::Size( 640, 480), cv::Size( 300, 300), cv::Size( 320, 200)), - Values(0))); + Values(1))); INSTANTIATE_TEST_CASE_P(ResizeRoiTestFluid, ResizeRoiTestGAPI, Combine(Values(CV_8UC1, CV_8UC3), diff --git a/inference-engine/tests_deprecated/fluid_preproc/fluid_test_computations/fluid_test_computations.cpp b/inference-engine/tests_deprecated/fluid_preproc/fluid_test_computations/fluid_test_computations.cpp index f4afb49..5192cf0 100644 --- a/inference-engine/tests_deprecated/fluid_preproc/fluid_test_computations/fluid_test_computations.cpp +++ b/inference-engine/tests_deprecated/fluid_preproc/fluid_test_computations/fluid_test_computations.cpp @@ -214,14 +214,14 @@ FluidI420toRGBComputation::FluidI420toRGBComputation(test::Mat inMat_y, test::Ma }) {} -FluidU16ToF32Computation::FluidU16ToF32Computation(test::Mat inMatU16, test::Mat outMatF32) - : FluidComputation(new Priv{ []()-> cv::GComputation { - cv::GMat in_U16; - cv::GMat outf32 = InferenceEngine::gapi::U16toF32::on(in_U16); - return cv::GComputation(cv::GIn(in_U16), cv::GOut(outf32)); +ConvertDepthComputation::ConvertDepthComputation(test::Mat inMat, test::Mat outMat, int depth) + : FluidComputation(new Priv{ [depth]()-> cv::GComputation { + cv::GMat in; + cv::GMat out = InferenceEngine::gapi::ConvertDepth::on(in, depth); + return cv::GComputation(cv::GIn(in), cv::GOut(out)); }() - , {to_own(inMatU16)} - , {to_own(outMatF32)} + , {to_own(inMat)} + , {to_own(outMat)} }) {} diff --git a/inference-engine/tests_deprecated/fluid_preproc/fluid_test_computations/fluid_test_computations.hpp b/inference-engine/tests_deprecated/fluid_preproc/fluid_test_computations/fluid_test_computations.hpp index 39d06a3..e7d071e 100644 --- a/inference-engine/tests_deprecated/fluid_preproc/fluid_test_computations/fluid_test_computations.hpp +++ b/inference-engine/tests_deprecated/fluid_preproc/fluid_test_computations/fluid_test_computations.hpp @@ -98,10 +98,10 @@ public: FluidI420toRGBComputation(test::Mat inMat_y, test::Mat inMat_u, test::Mat inMat_v, test::Mat outMat); }; -class FLUID_COMPUTATION_VISIBILITY FluidU16ToF32Computation : public FluidComputation +class FLUID_COMPUTATION_VISIBILITY ConvertDepthComputation : public FluidComputation { public: - FluidU16ToF32Computation(test::Mat inMatU16, test::Mat outMatF32); + ConvertDepthComputation(test::Mat inMat, test::Mat outMat, int depth); }; #endif // FLUID_TEST_COMPUTATIONS_HPP -- 2.7.4