Merge pull request #19732 from aDanPin:danpin/gapi/stereo_operation_and_test

G-API Stereo operation and tests
This commit is contained in:
Alexander Alekhin 2021-03-31 23:22:29 +03:00 committed by GitHub
commit 9f13fdb840
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 362 additions and 1 deletions

View File

@ -23,7 +23,7 @@ ocv_add_module(gapi
REQUIRED
opencv_imgproc
OPTIONAL
opencv_video
opencv_video opencv_calib3d
WRAP
python
)
@ -77,6 +77,7 @@ set(gapi_srcs
src/api/kernels_video.cpp
src/api/kernels_nnparsers.cpp
src/api/kernels_streaming.cpp
src/api/kernels_stereo.cpp
src/api/render.cpp
src/api/render_ocv.cpp
src/api/ginfer.cpp
@ -112,6 +113,7 @@ set(gapi_srcs
src/backends/cpu/gcpubackend.cpp
src/backends/cpu/gcpukernel.cpp
src/backends/cpu/gcpuimgproc.cpp
src/backends/cpu/gcpustereo.cpp
src/backends/cpu/gcpuvideo.cpp
src/backends/cpu/gcpucore.cpp
src/backends/cpu/gnnparsers.cpp

View File

@ -0,0 +1,48 @@
// 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) 2021 Intel Corporation
#ifndef OPENCV_GAPI_CPU_STEREO_API_HPP
#define OPENCV_GAPI_CPU_STEREO_API_HPP
#include <opencv2/gapi/gkernel.hpp> // GKernelPackage
namespace cv {
namespace gapi {
namespace calib3d {
namespace cpu {
GAPI_EXPORTS GKernelPackage kernels();
/** @brief Structure for the Stereo operation initialization parameters.*/
struct GAPI_EXPORTS StereoInitParam {
StereoInitParam(int nD, int bS, double bL, double f):
numDisparities(nD), blockSize(bS), baseline(bL), focus(f) {}
StereoInitParam() = default;
int numDisparities = 0;
int blockSize = 21;
double baseline = 70.;
double focus = 1000.;
};
} // namespace cpu
} // namespace calib3d
} // namespace gapi
namespace detail {
template<> struct CompileArgTag<cv::gapi::calib3d::cpu::StereoInitParam> {
static const char* tag() {
return "org.opencv.stereoInit";
}
};
} // namespace detail
} // namespace cv
#endif // OPENCV_GAPI_CPU_STEREO_API_HPP

View File

@ -0,0 +1,64 @@
// 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 distereoibution and at http://opencv.org/license.html.
//
// Copyright (C) 2021 Intel Corporation
#ifndef OPENCV_GAPI_STEREO_HPP
#define OPENCV_GAPI_STEREO_HPP
#include <opencv2/gapi/gmat.hpp>
#include <opencv2/gapi/gscalar.hpp>
#include <opencv2/gapi/gkernel.hpp>
namespace cv {
namespace gapi {
enum class StereoOutputFormat {
DEPTH_FLOAT16,
DEPTH_FLOAT32,
DISPARITY_FIXED16_11_5,
DISPARITY_FIXED16_12_4
};
namespace calib3d {
G_TYPED_KERNEL(GStereo, <GMat(GMat, GMat, const StereoOutputFormat)>, "org.opencv.stereo") {
static GMatDesc outMeta(const GMatDesc &left, const GMatDesc &right, const StereoOutputFormat of) {
GAPI_Assert(left.chan == 1);
GAPI_Assert(left.depth == CV_8U);
GAPI_Assert(right.chan == 1);
GAPI_Assert(right.depth == CV_8U);
switch(of) {
case StereoOutputFormat::DEPTH_FLOAT16:
return left.withDepth(CV_16FC1);
case StereoOutputFormat::DEPTH_FLOAT32:
return left.withDepth(CV_32FC1);
case StereoOutputFormat::DISPARITY_FIXED16_11_5:
case StereoOutputFormat::DISPARITY_FIXED16_12_4:
return left.withDepth(CV_16SC1);
default:
GAPI_Assert(false && "Unknown output format!");
}
}
};
} // namespace calib3d
/** @brief Extract disparity/depth information depending on passed StereoOutputFormat argument.
The function extracts disparity/depth information depending on passed StereoOutputFormat argument from
given stereo-pair.
@param left left 8-bit unsigned 1-channel image of @ref CV_8UC1 type
@param right right 8-bit unsigned 1-channel image of @ref CV_8UC1 type
@param of enum to specify output kind: depth or disparity and corresponding type
*/
GAPI_EXPORTS GMat stereo(const GMat& left,
const GMat& right,
const StereoOutputFormat of = StereoOutputFormat::DEPTH_FLOAT32);
} // namespace gapi
} // namespace cv
#endif // OPENCV_GAPI_STEREO_HPP

View File

@ -0,0 +1,18 @@
// 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) 2021 Intel Corporation
#include <opencv2/gapi/stereo.hpp>
namespace cv { namespace gapi {
GMat stereo(const GMat& left, const GMat& right,
const cv::gapi::StereoOutputFormat of)
{
return calib3d::GStereo::on(left, right, of);
}
} // namespace cv
} // namespace gapi

View File

@ -0,0 +1,85 @@
// 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) 2021 Intel Corporation
#include <opencv2/gapi/stereo.hpp>
#include <opencv2/gapi/cpu/stereo.hpp>
#include <opencv2/gapi/cpu/gcpukernel.hpp>
#ifdef HAVE_OPENCV_CALIB3D
#include <opencv2/calib3d.hpp>
#endif // HAVE_OPENCV_CALIB3D
#ifdef HAVE_OPENCV_CALIB3D
/** @brief Structure for the Stereo operation setup parameters.*/
struct GAPI_EXPORTS StereoSetup {
double baseline;
double focus;
cv::Ptr<cv::StereoBM> stereoBM;
};
namespace {
cv::Mat calcDepth(const cv::Mat &left, const cv::Mat &right,
const StereoSetup &ss) {
constexpr int DISPARITY_SHIFT_16S = 4;
cv::Mat disp;
ss.stereoBM->compute(left, right, disp);
disp.convertTo(disp, CV_32FC1, 1./(1 << DISPARITY_SHIFT_16S), 0);
return (ss.focus * ss.baseline) / disp;
}
} // anonymous namespace
GAPI_OCV_KERNEL_ST(GCPUStereo, cv::gapi::calib3d::GStereo, StereoSetup)
{
static void setup(const cv::GMatDesc&, const cv::GMatDesc&,
const cv::gapi::StereoOutputFormat,
std::shared_ptr<StereoSetup> &stereoSetup,
const cv::GCompileArgs &compileArgs) {
auto stereoInit = cv::gapi::getCompileArg<cv::gapi::calib3d::cpu::StereoInitParam>(compileArgs)
.value_or(cv::gapi::calib3d::cpu::StereoInitParam{});
StereoSetup ss{stereoInit.baseline,
stereoInit.focus,
cv::StereoBM::create(stereoInit.numDisparities,
stereoInit.blockSize)};
stereoSetup = std::make_shared<StereoSetup>(ss);
}
static void run(const cv::Mat& left,
const cv::Mat& right,
const cv::gapi::StereoOutputFormat oF,
cv::Mat& out_mat,
const StereoSetup &stereoSetup) {
switch(oF){
case cv::gapi::StereoOutputFormat::DEPTH_FLOAT16:
calcDepth(left, right, stereoSetup).convertTo(out_mat, CV_16FC1);
break;
case cv::gapi::StereoOutputFormat::DEPTH_FLOAT32:
calcDepth(left, right, stereoSetup).copyTo(out_mat);
break;
case cv::gapi::StereoOutputFormat::DISPARITY_FIXED16_12_4:
stereoSetup.stereoBM->compute(left, right, out_mat);
break;
case cv::gapi::StereoOutputFormat::DISPARITY_FIXED16_11_5:
GAPI_Assert(false && "This case may be supported in future.");
default:
GAPI_Assert(false && "Unknown output format!");
}
}
};
cv::gapi::GKernelPackage cv::gapi::calib3d::cpu::kernels() {
static auto pkg = cv::gapi::kernels<GCPUStereo>();
return pkg;
}
#else
cv::gapi::GKernelPackage cv::gapi::calib3d::cpu::kernels()
{
return GKernelPackage();
}
#endif // HAVE_OPENCV_CALIB3D

View File

@ -0,0 +1,8 @@
// 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) 2021 Intel Corporation
#include "../test_precomp.hpp"
#include "gapi_stereo_tests_inl.hpp"

View File

@ -0,0 +1,26 @@
// 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) 2021 Intel Corporation
#ifndef OPENCV_GAPI_STEREO_TESTS_HPP
#define OPENCV_GAPI_STEREO_TESTS_HPP
#include <opencv2/gapi/stereo.hpp> // fore cv::gapi::StereoOutputFormat
#include "gapi_tests_common.hpp"
#include "gapi_parsers_tests_common.hpp"
namespace opencv_test
{
GAPI_TEST_FIXTURE(TestGAPIStereo, initMatsRandU, FIXTURE_API(cv::gapi::StereoOutputFormat, int, int, double, double, CompareMats), 6,
oF, numDisparities, blockSize, baseline,
focus, cmpF)
} // namespace opencv_test
#endif // OPENCV_GAPI_STEREO_TESTS_HPP

View File

@ -0,0 +1,74 @@
// 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) 2021 Intel Corporation
#ifndef OPENCV_GAPI_STEREO_TESTS_INL_HPP
#define OPENCV_GAPI_STEREO_TESTS_INL_HPP
#include <opencv2/gapi/stereo.hpp>
#include <opencv2/gapi/cpu/stereo.hpp>
#include "gapi_stereo_tests.hpp"
#ifdef HAVE_OPENCV_CALIB3D
#include <opencv2/calib3d.hpp>
namespace opencv_test {
TEST_P(TestGAPIStereo, DisparityDepthTest)
{
using format = cv::gapi::StereoOutputFormat;
switch(oF) {
case format::DEPTH_FLOAT16: dtype = CV_16FC1; break;
case format::DEPTH_FLOAT32: dtype = CV_32FC1; break;
case format::DISPARITY_FIXED16_12_4: dtype = CV_16SC1; break;
default: GAPI_Assert(false && "Unsupported format in test");
}
initOutMats(sz, dtype);
// G-API
cv::GMat inL, inR;
cv::GMat out = cv::gapi::stereo(inL, inR, oF);
cv::GComputation(cv::GIn(inL, inR), cv::GOut(out))
.apply(cv::gin(in_mat1, in_mat2), cv::gout(out_mat_gapi),
cv::compile_args(cv::gapi::calib3d::cpu::kernels(),
cv::gapi::calib3d::cpu::StereoInitParam {
numDisparities,
blockSize,
baseline,
focus}));
// OpenCV
cv::StereoBM::create(numDisparities, blockSize)->compute(in_mat1,
in_mat2,
out_mat_ocv);
static const int DISPARITY_SHIFT_16S = 4;
switch(oF) {
case format::DEPTH_FLOAT16:
out_mat_ocv.convertTo(out_mat_ocv, CV_32FC1, 1./(1 << DISPARITY_SHIFT_16S), 0);
out_mat_ocv = (focus * baseline) / out_mat_ocv;
out_mat_ocv.convertTo(out_mat_ocv, CV_16FC1);
break;
case format::DEPTH_FLOAT32:
out_mat_ocv.convertTo(out_mat_ocv, CV_32FC1, 1./(1 << DISPARITY_SHIFT_16S), 0);
out_mat_ocv = (focus * baseline) / out_mat_ocv;
break;
case format::DISPARITY_FIXED16_12_4:
break;
default:
GAPI_Assert(false && "Unsupported format in test");
}
EXPECT_TRUE(cmpF(out_mat_gapi, out_mat_ocv));
}
} // namespace opencv_test
#endif // HAVE_OPENCV_CALIB3D
#endif // OPENCV_GAPI_STEREO_TESTS_INL_HPP

View File

@ -0,0 +1,36 @@
// 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) 2021 Intel Corporation
#include "../test_precomp.hpp"
#include "../common/gapi_stereo_tests.hpp"
#include <opencv2/gapi/stereo.hpp> // For ::gapi::stereo::disparity/depth
#include <opencv2/gapi/cpu/stereo.hpp>
namespace
{
#define STEREO_CPU [] () { return cv::compile_args(cv::gapi::use_only{cv::gapi::calib3d::cpu::kernels()}); }
} // anonymous namespace
namespace opencv_test
{
INSTANTIATE_TEST_CASE_P(CPU_Tests, TestGAPIStereo,
Combine(Values(CV_8UC1),
Values(cv::Size(1280, 720)),
Values(CV_32FC1),
Values(STEREO_CPU),
Values(cv::gapi::StereoOutputFormat::DEPTH_FLOAT16,
cv::gapi::StereoOutputFormat::DEPTH_FLOAT32,
cv::gapi::StereoOutputFormat::DISPARITY_FIXED16_12_4),
Values(16),
Values(43),
Values(10.),
Values(100.),
Values(AbsExact().to_compare_obj())));
} // opencv_test