1
0
mirror of https://github.com/opencv/opencv.git synced 2026-07-30 07:43:03 +04:00

Merge branch 4.x

This commit is contained in:
Alexander Alekhin
2021-04-09 10:30:38 +00:00
1114 changed files with 64039 additions and 14611 deletions
+5 -1
View File
@@ -2,7 +2,7 @@
// 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) 2018-2020 Intel Corporation
// Copyright (C) 2018-2021 Intel Corporation
#ifndef OPENCV_GAPI_CORE_TESTS_HPP
@@ -151,6 +151,9 @@ GAPI_TEST_FIXTURE(WarpPerspectiveTest, initMatrixRandU,
GAPI_TEST_FIXTURE(WarpAffineTest, initMatrixRandU,
FIXTURE_API(CompareMats, double , double, int, int, cv::Scalar),
6, cmpF, angle, scale, flags, border_mode, border_value)
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_EXT_BASE_FIXTURE(ParseSSDBLTest, ParserSSDTest, initNothing,
FIXTURE_API(float, int), 2, confidence_threshold, filter_label)
@@ -160,6 +163,7 @@ GAPI_TEST_EXT_BASE_FIXTURE(ParseYoloTest, ParserYoloTest, initNothing,
FIXTURE_API(float, float, int, std::pair<bool,int>), 4, confidence_threshold, nms_threshold, num_classes, dims_config)
GAPI_TEST_FIXTURE(SizeTest, initMatrixRandU, <>, 0)
GAPI_TEST_FIXTURE(SizeRTest, initNothing, <>, 0)
GAPI_TEST_FIXTURE(SizeMFTest, initNothing, <>, 0)
} // opencv_test
#endif //OPENCV_GAPI_CORE_TESTS_HPP
@@ -0,0 +1,180 @@
// 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_CORE_TESTS_COMMON_HPP
#define OPENCV_GAPI_CORE_TESTS_COMMON_HPP
#include "gapi_tests_common.hpp"
#include "../../include/opencv2/gapi/core.hpp"
#include <opencv2/core.hpp>
namespace opencv_test
{
namespace
{
template <typename Elem, typename CmpF>
inline bool compareKMeansOutputs(const std::vector<Elem>& outGAPI,
const std::vector<Elem>& outOCV,
const CmpF& = AbsExact().to_compare_obj())
{
return AbsExactVector<Elem>().to_compare_f()(outGAPI, outOCV);
}
inline bool compareKMeansOutputs(const cv::Mat& outGAPI,
const cv::Mat& outOCV,
const CompareMats& cmpF)
{
return cmpF(outGAPI, outOCV);
}
}
// Overload with initializing the labels
template<typename Labels, typename In>
cv::GComputation kmeansTestGAPI(const In& in, const Labels& bestLabels, const int K,
const cv::KmeansFlags flags, cv::GCompileArgs&& args,
double& compact_gapi, Labels& labels_gapi, In& centers_gapi)
{
const cv::TermCriteria criteria(cv::TermCriteria::MAX_ITER + cv::TermCriteria::EPS, 30, 0);
const int attempts = 1;
cv::detail::g_type_of_t<In> gIn, centers;
cv::GOpaque<double> compactness;
cv::detail::g_type_of_t<Labels> inLabels, outLabels;
std::tie(compactness, outLabels, centers) =
cv::gapi::kmeans(gIn, K, inLabels, criteria, attempts, flags);
cv::GComputation c(cv::GIn(gIn, inLabels), cv::GOut(compactness, outLabels, centers));
c.apply(cv::gin(in, bestLabels), cv::gout(compact_gapi, labels_gapi, centers_gapi),
std::move(args));
return c;
}
// Overload for vector<Point> tests w/o initializing the labels
template<typename Pt>
cv::GComputation kmeansTestGAPI(const std::vector<Pt>& in, const int K,
const cv::KmeansFlags flags, cv::GCompileArgs&& args,
double& compact_gapi, std::vector<int>& labels_gapi,
std::vector<Pt>& centers_gapi)
{
const cv::TermCriteria criteria(cv::TermCriteria::MAX_ITER + cv::TermCriteria::EPS, 30, 0);
const int attempts = 1;
cv::GArray<Pt> gIn, centers;
cv::GOpaque<double> compactness;
cv::GArray<int> inLabels(std::vector<int>{}), outLabels;
std::tie(compactness, outLabels, centers) =
cv::gapi::kmeans(gIn, K, inLabels, criteria, attempts, flags);
cv::GComputation c(cv::GIn(gIn), cv::GOut(compactness, outLabels, centers));
c.apply(cv::gin(in), cv::gout(compact_gapi, labels_gapi, centers_gapi), std::move(args));
return c;
}
// Overload for Mat tests w/o initializing the labels
static cv::GComputation kmeansTestGAPI(const cv::Mat& in, const int K,
const cv::KmeansFlags flags, cv::GCompileArgs&& args,
double& compact_gapi, cv::Mat& labels_gapi,
cv::Mat& centers_gapi)
{
const cv::TermCriteria criteria(cv::TermCriteria::MAX_ITER + cv::TermCriteria::EPS, 30, 0);
const int attempts = 1;
cv::GMat gIn, centers, labels;
cv::GOpaque<double> compactness;
std::tie(compactness, labels, centers) = cv::gapi::kmeans(gIn, K, criteria, attempts, flags);
cv::GComputation c(cv::GIn(gIn), cv::GOut(compactness, labels, centers));
c.apply(cv::gin(in), cv::gout(compact_gapi, labels_gapi, centers_gapi), std::move(args));
return c;
}
template<typename Pt>
void kmeansTestValidate(const cv::Size& sz, const MatType2&, const int K,
const double compact_gapi, const std::vector<int>& labels_gapi,
const std::vector<Pt>& centers_gapi)
{
const int amount = sz.height;
// Validation
EXPECT_GE(compact_gapi, 0.);
EXPECT_EQ(labels_gapi.size(), static_cast<size_t>(amount));
EXPECT_EQ(centers_gapi.size(), static_cast<size_t>(K));
}
static void kmeansTestValidate(const cv::Size& sz, const MatType2& type, const int K,
const double compact_gapi, const cv::Mat& labels_gapi,
const cv::Mat& centers_gapi)
{
const int chan = (type >> CV_CN_SHIFT) + 1;
const int amount = sz.height != 1 ? sz.height : sz.width;
const int dim = sz.height != 1 ? sz.width * chan : chan;
// Validation
EXPECT_GE(compact_gapi, 0.);
EXPECT_FALSE(labels_gapi.empty());
EXPECT_FALSE(centers_gapi.empty());
EXPECT_EQ(labels_gapi.rows, amount);
EXPECT_EQ(labels_gapi.cols, 1);
EXPECT_EQ(centers_gapi.rows, K);
EXPECT_EQ(centers_gapi.cols, dim);
}
template<typename Labels, typename In>
void kmeansTestOpenCVCompare(const In& in, const Labels& bestLabels, const int K,
const cv::KmeansFlags flags, const double compact_gapi,
const Labels& labels_gapi, const In& centers_gapi,
const CompareMats& cmpF = AbsExact().to_compare_obj())
{
const cv::TermCriteria criteria(cv::TermCriteria::MAX_ITER + cv::TermCriteria::EPS, 30, 0);
const int attempts = 1;
Labels labels_ocv;
In centers_ocv;
{ // step to generalize cv::Mat & std::vector cases of bestLabels' types
cv::Mat bestLabelsMat(bestLabels);
bestLabelsMat.copyTo(labels_ocv);
}
// OpenCV code /////////////////////////////////////////////////////////////
double compact_ocv = cv::kmeans(in, K, labels_ocv, criteria, attempts, flags, centers_ocv);
// Comparison //////////////////////////////////////////////////////////////
EXPECT_TRUE(compact_gapi == compact_ocv);
EXPECT_TRUE(compareKMeansOutputs(labels_gapi, labels_ocv, cmpF));
EXPECT_TRUE(compareKMeansOutputs(centers_gapi, centers_ocv, cmpF));
}
// If an input type is cv::Mat, labels' type is also cv::Mat;
// in other cases, their type has to be std::vector<int>
template<typename In>
using KMeansLabelType = typename std::conditional<std::is_same<In, cv::Mat>::value,
cv::Mat,
std::vector<int>
>::type;
template<typename In, typename Labels = KMeansLabelType<In> >
void kmeansTestBody(const In& in, const cv::Size& sz, const MatType2& type, const int K,
const cv::KmeansFlags flags, cv::GCompileArgs&& args,
const CompareMats& cmpF = AbsExact().to_compare_obj())
{
double compact_gapi = -1.;
Labels labels_gapi;
In centers_gapi;
if (flags & cv::KMEANS_USE_INITIAL_LABELS)
{
Labels bestLabels;
{ // step to generalize cv::Mat & std::vector cases of bestLabels' types
const int amount = (sz.height != 1 || sz.width == -1) ? sz.height : sz.width;
cv::Mat bestLabelsMat(cv::Size{1, amount}, CV_32SC1);
cv::randu(bestLabelsMat, 0, K);
bestLabelsMat.copyTo(bestLabels);
}
kmeansTestGAPI(in, bestLabels, K, flags, std::move(args), compact_gapi, labels_gapi,
centers_gapi);
kmeansTestOpenCVCompare(in, bestLabels, K, flags, compact_gapi, labels_gapi,
centers_gapi, cmpF);
}
else
{
kmeansTestGAPI(in, K, flags, std::move(args), compact_gapi, labels_gapi, centers_gapi);
kmeansTestValidate(sz, type, K, compact_gapi, labels_gapi, centers_gapi);
}
}
} // namespace opencv_test
#endif // OPENCV_GAPI_CORE_TESTS_COMMON_HPP
@@ -2,7 +2,7 @@
// 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) 2018-2020 Intel Corporation
// Copyright (C) 2018-2021 Intel Corporation
#ifndef OPENCV_GAPI_CORE_TESTS_INL_HPP
@@ -12,9 +12,10 @@
#include <opencv2/gapi/infer/parsers.hpp>
#include "gapi_core_tests.hpp"
#include "gapi_core_tests_common.hpp"
namespace opencv_test
{
TEST_P(MathOpTest, MatricesAccuracyTest)
{
// G-API code & corresponding OpenCV code ////////////////////////////////
@@ -1287,7 +1288,11 @@ TEST_P(PhaseTest, AccuracyTest)
// Comparison //////////////////////////////////////////////////////////////
// FIXME: use a comparison functor instead (after enabling OpenCL)
{
#if defined(__aarch64__) || defined(__arm__)
EXPECT_NEAR(0, cvtest::norm(out_mat_ocv, out_mat_gapi, NORM_INF), 4e-6);
#else
EXPECT_EQ(0, cvtest::norm(out_mat_ocv, out_mat_gapi, NORM_INF));
#endif
}
}
@@ -1377,6 +1382,27 @@ TEST_P(NormalizeTest, Test)
}
}
TEST_P(KMeansNDTest, AccuracyTest)
{
kmeansTestBody(in_mat1, sz, type, K, flags, getCompileArgs(), cmpF);
}
TEST_P(KMeans2DTest, AccuracyTest)
{
const int amount = sz.height;
std::vector<cv::Point2f> in_vector{};
initPointsVectorRandU(amount, in_vector);
kmeansTestBody(in_vector, sz, type, K, flags, getCompileArgs());
}
TEST_P(KMeans3DTest, AccuracyTest)
{
const int amount = sz.height;
std::vector<cv::Point3f> in_vector{};
initPointsVectorRandU(amount, in_vector);
kmeansTestBody(in_vector, sz, type, K, flags, getCompileArgs());
}
// PLEASE DO NOT PUT NEW ACCURACY TESTS BELOW THIS POINT! //////////////////////
TEST_P(BackendOutputAllocationTest, EmptyOutput)
@@ -1711,6 +1737,39 @@ TEST_P(SizeRTest, ParseTest)
EXPECT_EQ(out_sz, sz);
}
namespace {
class TestMediaBGR final : public cv::MediaFrame::IAdapter {
cv::Mat m_mat;
public:
explicit TestMediaBGR(cv::Mat m)
: m_mat(m) {
}
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));
}
};
};
TEST_P(SizeMFTest, ParseTest)
{
cv::Size out_sz;
cv::Mat bgr = cv::Mat::eye(sz.height, sz.width, CV_8UC3);
cv::MediaFrame frame = cv::MediaFrame::Create<TestMediaBGR>(bgr);
cv::GFrame in;
auto out = cv::gapi::streaming::size(in);
cv::GComputation c(cv::GIn(in), cv::GOut(out));
c.apply(cv::gin(frame), cv::gout(out_sz), getCompileArgs());
EXPECT_EQ(out_sz, sz);
}
} // opencv_test
#endif //OPENCV_GAPI_CORE_TESTS_INL_HPP
@@ -46,7 +46,7 @@ GAPI_TEST_FIXTURE(Erode3x3Test, initMatrixRandN, FIXTURE_API(CompareMats,int), 2
GAPI_TEST_FIXTURE(DilateTest, initMatrixRandN, FIXTURE_API(CompareMats,int,int), 3,
cmpF, kernSize, kernType)
GAPI_TEST_FIXTURE(Dilate3x3Test, initMatrixRandN, FIXTURE_API(CompareMats,int), 2, cmpF, numIters)
GAPI_TEST_FIXTURE(MorphologyExTest, initMatrixRandN, FIXTURE_API(CompareMats,MorphTypes),
GAPI_TEST_FIXTURE(MorphologyExTest, initMatrixRandN, FIXTURE_API(CompareMats,cv::MorphTypes),
2, cmpF, op)
GAPI_TEST_FIXTURE(SobelTest, initMatrixRandN, FIXTURE_API(CompareMats,int,int,int), 4,
cmpF, kernSize, dx, dy)
@@ -68,21 +68,18 @@ GAPI_TEST_FIXTURE_SPEC_PARAMS(GoodFeaturesTest,
blockSize, useHarrisDetector)
GAPI_TEST_FIXTURE_SPEC_PARAMS(FindContoursNoOffsetTest,
FIXTURE_API(cv::Size,MatType2,cv::RetrievalModes,
cv::ContourApproximationModes),
4, sz, type, mode, method)
cv::ContourApproximationModes, CompareMats),
5, sz, type, mode, method, cmpF)
GAPI_TEST_FIXTURE_SPEC_PARAMS(FindContoursOffsetTest, <>, 0)
GAPI_TEST_FIXTURE_SPEC_PARAMS(FindContoursHNoOffsetTest,
FIXTURE_API(cv::Size,MatType2,cv::RetrievalModes,
cv::ContourApproximationModes),
4, sz, type, mode, method)
cv::ContourApproximationModes, CompareMats),
5, sz, type, mode, method, cmpF)
GAPI_TEST_FIXTURE_SPEC_PARAMS(FindContoursHOffsetTest, <>, 0)
GAPI_TEST_FIXTURE(BoundingRectMatTest, initMatrixRandU, FIXTURE_API(CompareRects), 1, cmpF)
GAPI_TEST_FIXTURE(BoundingRectMatVector32STest, initNothing, FIXTURE_API(CompareRects), 1, cmpF)
GAPI_TEST_FIXTURE(BoundingRectMatVector32FTest, initNothing, FIXTURE_API(CompareRects), 1, cmpF)
GAPI_TEST_FIXTURE(BoundingRectMatTest, initNothing, FIXTURE_API(CompareRects,bool),
2, cmpF, initByVector)
GAPI_TEST_FIXTURE(BoundingRectVector32STest, initNothing, FIXTURE_API(CompareRects), 1, cmpF)
GAPI_TEST_FIXTURE(BoundingRectVector32FTest, initNothing, FIXTURE_API(CompareRects), 1, cmpF)
GAPI_TEST_FIXTURE(BGR2RGBTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
GAPI_TEST_FIXTURE(RGB2GrayTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
GAPI_TEST_FIXTURE(FitLine2DMatVectorTest, initMatByPointsVectorRandU<cv::Point_>,
FIXTURE_API(CompareVecs<float, 4>,cv::DistanceTypes), 2, cmpF, distType)
GAPI_TEST_FIXTURE(FitLine2DVector32STest, initNothing,
@@ -99,6 +96,8 @@ GAPI_TEST_FIXTURE(FitLine3DVector32FTest, initNothing,
FIXTURE_API(CompareVecs<float, 6>,cv::DistanceTypes), 2, cmpF, distType)
GAPI_TEST_FIXTURE(FitLine3DVector64FTest, initNothing,
FIXTURE_API(CompareVecs<float, 6>,cv::DistanceTypes), 2, cmpF, distType)
GAPI_TEST_FIXTURE(BGR2RGBTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
GAPI_TEST_FIXTURE(RGB2GrayTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
GAPI_TEST_FIXTURE(BGR2GrayTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
GAPI_TEST_FIXTURE(RGB2YUVTest, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
GAPI_TEST_FIXTURE(BGR2I420Test, initMatrixRandN, FIXTURE_API(CompareMats), 1, cmpF)
@@ -0,0 +1,197 @@
// 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
#ifndef OPENCV_GAPI_IMGPROC_TESTS_COMMON_HPP
#define OPENCV_GAPI_IMGPROC_TESTS_COMMON_HPP
#include "gapi_tests_common.hpp"
#include "../../include/opencv2/gapi/imgproc.hpp"
#include <opencv2/imgproc.hpp>
namespace opencv_test
{
// Draw random ellipses on given cv::Mat of given size and type
static void initMatForFindingContours(cv::Mat& mat, const cv::Size& sz, const int type)
{
cv::RNG& rng = theRNG();
mat = cv::Mat(sz, type, cv::Scalar::all(0));
const size_t numEllipses = rng.uniform(1, 10);
for( size_t i = 0; i < numEllipses; i++ )
{
cv::Point center;
cv::Size axes;
center.x = rng.uniform(0, sz.width);
center.y = rng.uniform(0, sz.height);
axes.width = rng.uniform(2, sz.width);
axes.height = rng.uniform(2, sz.height);
const int color = rng.uniform(1, 256);
const double angle = rng.uniform(0., 180.);
cv::ellipse(mat, center, axes, angle, 0., 360., color, 1, FILLED);
}
}
enum OptionalFindContoursOutput {NONE, HIERARCHY};
template<OptionalFindContoursOutput optional = NONE>
cv::GComputation findContoursTestGAPI(const cv::Mat& in, const cv::RetrievalModes mode,
const cv::ContourApproximationModes method,
cv::GCompileArgs&& args,
std::vector<std::vector<cv::Point>>& out_cnts_gapi,
std::vector<cv::Vec4i>& /*out_hier_gapi*/,
const cv::Point& offset = cv::Point())
{
cv::GMat g_in;
cv::GOpaque<cv::Point> gOffset;
cv::GArray<cv::GArray<cv::Point>> outCts;
outCts = cv::gapi::findContours(g_in, mode, method, gOffset);
cv::GComputation c(GIn(g_in, gOffset), GOut(outCts));
c.apply(gin(in, offset), gout(out_cnts_gapi), std::move(args));
return c;
}
template<> cv::GComputation findContoursTestGAPI<HIERARCHY> (
const cv::Mat& in, const cv::RetrievalModes mode, const cv::ContourApproximationModes method,
cv::GCompileArgs&& args, std::vector<std::vector<cv::Point>>& out_cnts_gapi,
std::vector<cv::Vec4i>& out_hier_gapi, const cv::Point& offset)
{
cv::GMat g_in;
cv::GOpaque<cv::Point> gOffset;
cv::GArray<cv::GArray<cv::Point>> outCts;
cv::GArray<cv::Vec4i> outHier;
std::tie(outCts, outHier) = cv::gapi::findContoursH(g_in, mode, method, gOffset);
cv::GComputation c(GIn(g_in, gOffset), GOut(outCts, outHier));
c.apply(gin(in, offset), gout(out_cnts_gapi, out_hier_gapi), std::move(args));
return c;
}
template<OptionalFindContoursOutput optional = NONE>
void findContoursTestOpenCVCompare(const cv::Mat& in, const cv::RetrievalModes mode,
const cv::ContourApproximationModes method,
const std::vector<std::vector<cv::Point>>& out_cnts_gapi,
const std::vector<cv::Vec4i>& out_hier_gapi,
const CompareMats& cmpF, const cv::Point& offset = cv::Point())
{
// OpenCV code /////////////////////////////////////////////////////////////
std::vector<std::vector<cv::Point>> out_cnts_ocv;
std::vector<cv::Vec4i> out_hier_ocv;
cv::findContours(in, out_cnts_ocv, out_hier_ocv, mode, method, offset);
// Comparison //////////////////////////////////////////////////////////////
EXPECT_TRUE(out_cnts_gapi.size() == out_cnts_ocv.size());
cv::Mat out_mat_ocv = cv::Mat(cv::Size{ in.cols, in.rows }, in.type(), cv::Scalar::all(0));
cv::Mat out_mat_gapi = cv::Mat(cv::Size{ in.cols, in.rows }, in.type(), cv::Scalar::all(0));
cv::fillPoly(out_mat_ocv, out_cnts_ocv, cv::Scalar::all(1));
cv::fillPoly(out_mat_gapi, out_cnts_gapi, cv::Scalar::all(1));
EXPECT_TRUE(cmpF(out_mat_ocv, out_mat_gapi));
if (optional == HIERARCHY)
{
EXPECT_TRUE(out_hier_ocv.size() == out_hier_gapi.size());
EXPECT_TRUE(AbsExactVector<cv::Vec4i>().to_compare_f()(out_hier_ocv, out_hier_gapi));
}
}
template<OptionalFindContoursOutput optional = NONE>
void findContoursTestBody(const cv::Size& sz, const MatType2& type, const cv::RetrievalModes mode,
const cv::ContourApproximationModes method, const CompareMats& cmpF,
cv::GCompileArgs&& args, const cv::Point& offset = cv::Point())
{
cv::Mat in;
initMatForFindingContours(in, sz, type);
std::vector<std::vector<cv::Point>> out_cnts_gapi;
std::vector<cv::Vec4i> out_hier_gapi;
findContoursTestGAPI<optional>(in, mode, method, std::move(args), out_cnts_gapi, out_hier_gapi,
offset);
findContoursTestOpenCVCompare<optional>(in, mode, method, out_cnts_gapi, out_hier_gapi, cmpF,
offset);
}
//-------------------------------------------------------------------------------------------------
template<typename In>
static cv::GComputation boundingRectTestGAPI(const In& in, cv::GCompileArgs&& args,
cv::Rect& out_rect_gapi)
{
cv::detail::g_type_of_t<In> g_in;
auto out = cv::gapi::boundingRect(g_in);
cv::GComputation c(cv::GIn(g_in), cv::GOut(out));
c.apply(cv::gin(in), cv::gout(out_rect_gapi), std::move(args));
return c;
}
template<typename In>
static void boundingRectTestOpenCVCompare(const In& in, const cv::Rect& out_rect_gapi,
const CompareRects& cmpF)
{
// OpenCV code /////////////////////////////////////////////////////////////
cv::Rect out_rect_ocv = cv::boundingRect(in);
// Comparison //////////////////////////////////////////////////////////////
EXPECT_TRUE(cmpF(out_rect_gapi, out_rect_ocv));
}
template<typename In>
static void boundingRectTestBody(const In& in, const CompareRects& cmpF, cv::GCompileArgs&& args)
{
cv::Rect out_rect_gapi;
boundingRectTestGAPI(in, std::move(args), out_rect_gapi);
boundingRectTestOpenCVCompare(in, out_rect_gapi, cmpF);
}
//-------------------------------------------------------------------------------------------------
template<typename In>
static cv::GComputation fitLineTestGAPI(const In& in, const cv::DistanceTypes distType,
cv::GCompileArgs&& args, cv::Vec4f& out_vec_gapi)
{
const double paramDefault = 0., repsDefault = 0., aepsDefault = 0.;
cv::detail::g_type_of_t<In> g_in;
auto out = cv::gapi::fitLine2D(g_in, distType, paramDefault, repsDefault, aepsDefault);
cv::GComputation c(cv::GIn(g_in), cv::GOut(out));
c.apply(cv::gin(in), cv::gout(out_vec_gapi), std::move(args));
return c;
}
template<typename In>
static cv::GComputation fitLineTestGAPI(const In& in, const cv::DistanceTypes distType,
cv::GCompileArgs&& args, cv::Vec6f& out_vec_gapi)
{
const double paramDefault = 0., repsDefault = 0., aepsDefault = 0.;
cv::detail::g_type_of_t<In> g_in;
auto out = cv::gapi::fitLine3D(g_in, distType, paramDefault, repsDefault, aepsDefault);
cv::GComputation c(cv::GIn(g_in), cv::GOut(out));
c.apply(cv::gin(in), cv::gout(out_vec_gapi), std::move(args));
return c;
}
template<typename In, int dim>
static void fitLineTestOpenCVCompare(const In& in, const cv::DistanceTypes distType,
const cv::Vec<float, dim>& out_vec_gapi,
const CompareVecs<float, dim>& cmpF)
{
const double paramDefault = 0., repsDefault = 0., aepsDefault = 0.;
// OpenCV code /////////////////////////////////////////////////////////////
cv::Vec<float, dim> out_vec_ocv;
cv::fitLine(in, out_vec_ocv, distType, paramDefault, repsDefault, aepsDefault);
// Comparison //////////////////////////////////////////////////////////////
EXPECT_TRUE(cmpF(out_vec_gapi, out_vec_ocv));
}
template<typename In, int dim>
static void fitLineTestBody(const In& in, const cv::DistanceTypes distType,
const CompareVecs<float, dim>& cmpF, cv::GCompileArgs&& args)
{
cv::Vec<float, dim> out_vec_gapi;
fitLineTestGAPI(in, distType, std::move(args), out_vec_gapi);
fitLineTestOpenCVCompare(in, distType, out_vec_gapi, cmpF);
}
} // namespace opencv_test
#endif // OPENCV_GAPI_IMGPROC_TESTS_COMMON_HPP
@@ -11,6 +11,8 @@
#include <opencv2/gapi/imgproc.hpp>
#include "gapi_imgproc_tests.hpp"
#include "gapi_imgproc_tests_common.hpp"
namespace opencv_test
{
@@ -50,27 +52,6 @@ namespace
rgb2yuyv(in_line_p, out_line_p, in.cols);
}
}
// Draw random ellipses on given mat of given size and type
void initMatForFindingContours(cv::Mat& mat, const cv::Size& sz, const int type)
{
cv::RNG& rng = theRNG();
mat = cv::Mat(sz, type, cv::Scalar::all(0));
size_t numEllipses = rng.uniform(1, 10);
for( size_t i = 0; i < numEllipses; i++ )
{
cv::Point center;
cv::Size axes;
center.x = rng.uniform(0, sz.width);
center.y = rng.uniform(0, sz.height);
axes.width = rng.uniform(2, sz.width);
axes.height = rng.uniform(2, sz.height);
int color = rng.uniform(1, 256);
double angle = rng.uniform(0., 180.);
cv::ellipse(mat, center, axes, angle, 0., 360., color, 1, FILLED);
}
}
}
TEST_P(Filter2DTest, AccuracyTest)
@@ -313,7 +294,7 @@ TEST_P(Dilate3x3Test, AccuracyTest)
TEST_P(MorphologyExTest, AccuracyTest)
{
MorphShapes defShape = cv::MORPH_RECT;
cv::MorphShapes defShape = cv::MORPH_RECT;
int defKernSize = 3;
cv::Mat kernel = cv::getStructuringElement(defShape, cv::Size(defKernSize, defKernSize));
@@ -493,29 +474,7 @@ TEST_P(GoodFeaturesTest, AccuracyTest)
TEST_P(FindContoursNoOffsetTest, AccuracyTest)
{
std::vector<std::vector<cv::Point>> outCtsOCV, outCtsGAPI;
initMatForFindingContours(in_mat1, sz, type);
out_mat_gapi = cv::Mat(sz, type, cv::Scalar::all(0));
out_mat_ocv = cv::Mat(sz, type, cv::Scalar::all(0));
// OpenCV code /////////////////////////////////////////////////////////////
{
cv::findContours(in_mat1, outCtsOCV, mode, method);
}
// G-API code //////////////////////////////////////////////////////////////
cv::GMat in;
cv::GArray<cv::GArray<cv::Point>> outCts;
outCts = cv::gapi::findContours(in, mode, method);
cv::GComputation c(GIn(in), GOut(outCts));
c.apply(gin(in_mat1), gout(outCtsGAPI), getCompileArgs());
// Comparison //////////////////////////////////////////////////////////////
EXPECT_TRUE(outCtsGAPI.size() == outCtsOCV.size());
cv::fillPoly(out_mat_ocv, outCtsOCV, cv::Scalar::all(1));
cv::fillPoly(out_mat_gapi, outCtsGAPI, cv::Scalar::all(1));
EXPECT_TRUE(AbsExact().to_compare_f()(out_mat_ocv, out_mat_gapi));
findContoursTestBody(sz, type, mode, method, cmpF, getCompileArgs());
}
TEST_P(FindContoursOffsetTest, AccuracyTest)
@@ -524,63 +483,15 @@ TEST_P(FindContoursOffsetTest, AccuracyTest)
const MatType2 type = CV_8UC1;
const cv::RetrievalModes mode = cv::RETR_EXTERNAL;
const cv::ContourApproximationModes method = cv::CHAIN_APPROX_NONE;
const CompareMats cmpF = AbsExact().to_compare_obj();
const cv::Point offset(15, 15);
std::vector<std::vector<cv::Point>> outCtsOCV, outCtsGAPI;
initMatForFindingContours(in_mat1, sz, type);
out_mat_gapi = cv::Mat(sz, type, cv::Scalar::all(0));
out_mat_ocv = cv::Mat(sz, type, cv::Scalar::all(0));
// OpenCV code /////////////////////////////////////////////////////////////
{
cv::findContours(in_mat1, outCtsOCV, mode, method, offset);
}
// G-API code //////////////////////////////////////////////////////////////
cv::GMat in;
GOpaque<Point> gOffset;
cv::GArray<cv::GArray<cv::Point>> outCts;
outCts = cv::gapi::findContours(in, mode, method, gOffset);
cv::GComputation c(GIn(in, gOffset), GOut(outCts));
c.apply(gin(in_mat1, offset), gout(outCtsGAPI), getCompileArgs());
// Comparison //////////////////////////////////////////////////////////////
EXPECT_TRUE(outCtsGAPI.size() == outCtsOCV.size());
cv::fillPoly(out_mat_ocv, outCtsOCV, cv::Scalar::all(1));
cv::fillPoly(out_mat_gapi, outCtsGAPI, cv::Scalar::all(1));
EXPECT_TRUE(AbsExact().to_compare_f()(out_mat_ocv, out_mat_gapi));
findContoursTestBody(sz, type, mode, method, cmpF, getCompileArgs(), offset);
}
TEST_P(FindContoursHNoOffsetTest, AccuracyTest)
{
std::vector<std::vector<cv::Point>> outCtsOCV, outCtsGAPI;
std::vector<cv::Vec4i> outHierOCV, outHierGAPI;
initMatForFindingContours(in_mat1, sz, type);
out_mat_gapi = cv::Mat(sz, type, cv::Scalar::all(0));
out_mat_ocv = cv::Mat(sz, type, cv::Scalar::all(0));
// OpenCV code /////////////////////////////////////////////////////////////
{
cv::findContours(in_mat1, outCtsOCV, outHierOCV, mode, method);
}
// G-API code //////////////////////////////////////////////////////////////
cv::GMat in;
cv::GArray<cv::GArray<cv::Point>> outCts;
cv::GArray<cv::Vec4i> outHier;
std::tie(outCts, outHier) = cv::gapi::findContoursH(in, mode, method);
cv::GComputation c(GIn(in), GOut(outCts, outHier));
c.apply(gin(in_mat1), gout(outCtsGAPI, outHierGAPI), getCompileArgs());
// Comparison //////////////////////////////////////////////////////////////
EXPECT_TRUE(outCtsGAPI.size() == outCtsOCV.size());
cv::fillPoly(out_mat_ocv, outCtsOCV, cv::Scalar::all(1));
cv::fillPoly(out_mat_gapi, outCtsGAPI, cv::Scalar::all(1));
EXPECT_TRUE(AbsExact().to_compare_f()(out_mat_ocv, out_mat_gapi));
EXPECT_TRUE(outCtsGAPI.size() == outCtsOCV.size());
EXPECT_TRUE(AbsExactVector<cv::Vec4i>().to_compare_f()(outHierOCV, outHierGAPI));
findContoursTestBody<HIERARCHY>(sz, type, mode, method, cmpF, getCompileArgs());
}
TEST_P(FindContoursHOffsetTest, AccuracyTest)
@@ -589,353 +500,100 @@ TEST_P(FindContoursHOffsetTest, AccuracyTest)
const MatType2 type = CV_8UC1;
const cv::RetrievalModes mode = cv::RETR_EXTERNAL;
const cv::ContourApproximationModes method = cv::CHAIN_APPROX_NONE;
const CompareMats cmpF = AbsExact().to_compare_obj();
const cv::Point offset(15, 15);
std::vector<std::vector<cv::Point>> outCtsOCV, outCtsGAPI;
std::vector<cv::Vec4i> outHierOCV, outHierGAPI;
initMatForFindingContours(in_mat1, sz, type);
out_mat_gapi = cv::Mat(sz, type, cv::Scalar::all(0));
out_mat_ocv = cv::Mat(sz, type, cv::Scalar::all(0));
// OpenCV code /////////////////////////////////////////////////////////////
{
cv::findContours(in_mat1, outCtsOCV, outHierOCV, mode, method, offset);
}
// G-API code //////////////////////////////////////////////////////////////
cv::GMat in;
GOpaque<Point> gOffset;
cv::GArray<cv::GArray<cv::Point>> outCts;
cv::GArray<cv::Vec4i> outHier;
std::tie(outCts, outHier) = cv::gapi::findContoursH(in, mode, method, gOffset);
cv::GComputation c(GIn(in, gOffset), GOut(outCts, outHier));
c.apply(gin(in_mat1, offset), gout(outCtsGAPI, outHierGAPI), getCompileArgs());
// Comparison //////////////////////////////////////////////////////////////
EXPECT_TRUE(outCtsGAPI.size() == outCtsOCV.size());
cv::fillPoly(out_mat_ocv, outCtsOCV, cv::Scalar::all(1));
cv::fillPoly(out_mat_gapi, outCtsGAPI, cv::Scalar::all(1));
EXPECT_TRUE(AbsExact().to_compare_f()(out_mat_ocv, out_mat_gapi));
EXPECT_TRUE(outCtsGAPI.size() == outCtsOCV.size());
EXPECT_TRUE(AbsExactVector<cv::Vec4i>().to_compare_f()(outHierOCV, outHierGAPI));
findContoursTestBody<HIERARCHY>(sz, type, mode, method, cmpF, getCompileArgs(), offset);
}
TEST_P(BoundingRectMatTest, AccuracyTest)
{
cv::Rect out_rect_gapi, out_rect_ocv;
// G-API code //////////////////////////////////////////////////////////////
cv::GMat in;
auto out = cv::gapi::boundingRect(in);
cv::GComputation c(cv::GIn(in), cv::GOut(out));
c.apply(cv::gin(in_mat1), cv::gout(out_rect_gapi), getCompileArgs());
// OpenCV code /////////////////////////////////////////////////////////////
if (initByVector)
{
out_rect_ocv = cv::boundingRect(in_mat1);
initMatByPointsVectorRandU<cv::Point_>(type, sz, dtype);
}
// Comparison //////////////////////////////////////////////////////////////
else
{
EXPECT_TRUE(cmpF(out_rect_gapi, out_rect_ocv));
initMatrixRandU(type, sz, dtype);
}
boundingRectTestBody(in_mat1, cmpF, getCompileArgs());
}
TEST_P(BoundingRectMatVector32STest, AccuracyTest)
{
cv::Rect out_rect_gapi, out_rect_ocv;
std::vector<cv::Point2i> in_vectorS(sz.width);
cv::randu(in_vectorS, cv::Scalar::all(0), cv::Scalar::all(255));
in_mat1 = cv::Mat(in_vectorS);
// G-API code //////////////////////////////////////////////////////////////
cv::GMat in;
auto out = cv::gapi::boundingRect(in);
cv::GComputation c(cv::GIn(in), cv::GOut(out));
c.apply(cv::gin(in_mat1), cv::gout(out_rect_gapi), getCompileArgs());
// OpenCV code /////////////////////////////////////////////////////////////
{
out_rect_ocv = cv::boundingRect(in_mat1);
}
// Comparison //////////////////////////////////////////////////////////////
{
EXPECT_TRUE(cmpF(out_rect_gapi, out_rect_ocv));
}
}
TEST_P(BoundingRectMatVector32FTest, AccuracyTest)
{
cv::RNG& rng = theRNG();
cv::Rect out_rect_gapi, out_rect_ocv;
std::vector<cv::Point2f> in_vectorF(sz.width);
const int fscale = 256; // avoid bits near ULP, generate stable test input
for (int i = 0; i < sz.width; i++)
{
cv::Point2f pt(rng.uniform(0, 255 * fscale) / static_cast<float>(fscale),
rng.uniform(0, 255 * fscale) / static_cast<float>(fscale));
in_vectorF.push_back(pt);
}
in_mat1 = cv::Mat(in_vectorF);
// G-API code //////////////////////////////////////////////////////////////
cv::GMat in;
auto out = cv::gapi::boundingRect(in);
cv::GComputation c(cv::GIn(in), cv::GOut(out));
c.apply(cv::gin(in_mat1), cv::gout(out_rect_gapi), getCompileArgs());
// OpenCV code /////////////////////////////////////////////////////////////
{
out_rect_ocv = cv::boundingRect(in_mat1);
}
// Comparison //////////////////////////////////////////////////////////////
{
EXPECT_TRUE(cmpF(out_rect_gapi, out_rect_ocv));
}
}
TEST_P(BoundingRectVector32STest, AccuracyTest)
{
cv::Rect out_rect_gapi, out_rect_ocv;
std::vector<cv::Point2i> in_vector;
initPointsVectorRandU(sz.width, in_vector);
std::vector<cv::Point2i> in_vectorS(sz.width);
cv::randu(in_vectorS, cv::Scalar::all(0), cv::Scalar::all(255));
// G-API code //////////////////////////////////////////////////////////////
cv::GArray<cv::Point2i> in;
auto out = cv::gapi::boundingRect(in);
cv::GComputation c(cv::GIn(in), cv::GOut(out));
c.apply(cv::gin(in_vectorS), cv::gout(out_rect_gapi), getCompileArgs());
// OpenCV code /////////////////////////////////////////////////////////////
{
out_rect_ocv = cv::boundingRect(in_vectorS);
}
// Comparison //////////////////////////////////////////////////////////////
{
EXPECT_TRUE(cmpF(out_rect_gapi, out_rect_ocv));
}
boundingRectTestBody(in_vector, cmpF, getCompileArgs());
}
TEST_P(BoundingRectVector32FTest, AccuracyTest)
{
cv::RNG& rng = theRNG();
cv::Rect out_rect_gapi, out_rect_ocv;
std::vector<cv::Point2f> in_vector;
initPointsVectorRandU(sz.width, in_vector);
std::vector<cv::Point2f> in_vectorF(sz.width);
const int fscale = 256; // avoid bits near ULP, generate stable test input
for (int i = 0; i < sz.width; i++)
{
cv::Point2f pt(rng.uniform(0, 255 * fscale) / static_cast<float>(fscale),
rng.uniform(0, 255 * fscale) / static_cast<float>(fscale));
in_vectorF.push_back(pt);
}
// G-API code //////////////////////////////////////////////////////////////
cv::GArray<cv::Point2f> in;
auto out = cv::gapi::boundingRect(in);
cv::GComputation c(cv::GIn(in), cv::GOut(out));
c.apply(cv::gin(in_vectorF), cv::gout(out_rect_gapi), getCompileArgs());
// OpenCV code /////////////////////////////////////////////////////////////
{
out_rect_ocv = cv::boundingRect(in_vectorF);
}
// Comparison //////////////////////////////////////////////////////////////
{
EXPECT_TRUE(cmpF(out_rect_gapi, out_rect_ocv));
}
boundingRectTestBody(in_vector, cmpF, getCompileArgs());
}
TEST_P(FitLine2DMatVectorTest, AccuracyTest)
{
cv::Vec4f out_vec_gapi, out_vec_ocv;
double paramDefault = 0., repsDefault = 0., aepsDefault = 0.;
// G-API code //////////////////////////////////////////////////////////////
cv::GMat in;
auto out = cv::gapi::fitLine2D(in, distType, paramDefault, repsDefault, aepsDefault);
cv::GComputation c(cv::GIn(in), cv::GOut(out));
c.apply(cv::gin(in_mat1), cv::gout(out_vec_gapi), getCompileArgs());
// OpenCV code /////////////////////////////////////////////////////////////
{
cv::fitLine(in_mat1, out_vec_ocv, distType, paramDefault, repsDefault, aepsDefault);
}
// Comparison //////////////////////////////////////////////////////////////
{
EXPECT_TRUE(cmpF(out_vec_gapi, out_vec_ocv));
}
fitLineTestBody(in_mat1, distType, cmpF, getCompileArgs());
}
TEST_P(FitLine2DVector32STest, AccuracyTest)
{
cv::Vec4f out_vec_gapi, out_vec_ocv;
double paramDefault = 0., repsDefault = 0., aepsDefault = 0.;
std::vector<cv::Point2i> in_vec;
initPointsVectorRandU(sz.width, in_vec);
// G-API code //////////////////////////////////////////////////////////////
cv::GArray<cv::Point2i> in;
auto out = cv::gapi::fitLine2D(in, distType, paramDefault, repsDefault, aepsDefault);
cv::GComputation c(cv::GIn(in), cv::GOut(out));
c.apply(cv::gin(in_vec), cv::gout(out_vec_gapi), getCompileArgs());
// OpenCV code /////////////////////////////////////////////////////////////
{
cv::fitLine(in_vec, out_vec_ocv, distType, paramDefault, repsDefault, aepsDefault);
}
// Comparison //////////////////////////////////////////////////////////////
{
EXPECT_TRUE(cmpF(out_vec_gapi, out_vec_ocv));
}
fitLineTestBody(in_vec, distType, cmpF, getCompileArgs());
}
TEST_P(FitLine2DVector32FTest, AccuracyTest)
{
cv::Vec4f out_vec_gapi, out_vec_ocv;
double paramDefault = 0., repsDefault = 0., aepsDefault = 0.;
std::vector<cv::Point2f> in_vec;
initPointsVectorRandU(sz.width, in_vec);
// G-API code //////////////////////////////////////////////////////////////
cv::GArray<cv::Point2f> in;
auto out = cv::gapi::fitLine2D(in, distType, paramDefault, repsDefault, aepsDefault);
cv::GComputation c(cv::GIn(in), cv::GOut(out));
c.apply(cv::gin(in_vec), cv::gout(out_vec_gapi), getCompileArgs());
// OpenCV code /////////////////////////////////////////////////////////////
{
cv::fitLine(in_vec, out_vec_ocv, distType, paramDefault, repsDefault, aepsDefault);
}
// Comparison //////////////////////////////////////////////////////////////
{
EXPECT_TRUE(cmpF(out_vec_gapi, out_vec_ocv));
}
fitLineTestBody(in_vec, distType, cmpF, getCompileArgs());
}
TEST_P(FitLine2DVector64FTest, AccuracyTest)
{
cv::Vec4f out_vec_gapi, out_vec_ocv;
double paramDefault = 0., repsDefault = 0., aepsDefault = 0.;
std::vector<cv::Point2d> in_vec;
initPointsVectorRandU(sz.width, in_vec);
// G-API code //////////////////////////////////////////////////////////////
cv::GArray<cv::Point2d> in;
auto out = cv::gapi::fitLine2D(in, distType, paramDefault, repsDefault, aepsDefault);
cv::GComputation c(cv::GIn(in), cv::GOut(out));
c.apply(cv::gin(in_vec), cv::gout(out_vec_gapi), getCompileArgs());
// OpenCV code /////////////////////////////////////////////////////////////
{
cv::fitLine(in_vec, out_vec_ocv, distType, paramDefault, repsDefault, aepsDefault);
}
// Comparison //////////////////////////////////////////////////////////////
{
EXPECT_TRUE(cmpF(out_vec_gapi, out_vec_ocv));
}
fitLineTestBody(in_vec, distType, cmpF, getCompileArgs());
}
TEST_P(FitLine3DMatVectorTest, AccuracyTest)
{
cv::Vec6f out_vec_gapi, out_vec_ocv;
double paramDefault = 0., repsDefault = 0., aepsDefault = 0.;
// G-API code //////////////////////////////////////////////////////////////
cv::GMat in;
auto out = cv::gapi::fitLine3D(in, distType, paramDefault, repsDefault, aepsDefault);
cv::GComputation c(cv::GIn(in), cv::GOut(out));
c.apply(cv::gin(in_mat1), cv::gout(out_vec_gapi), getCompileArgs());
// OpenCV code /////////////////////////////////////////////////////////////
{
cv::fitLine(in_mat1, out_vec_ocv, distType, paramDefault, repsDefault, aepsDefault);
}
// Comparison //////////////////////////////////////////////////////////////
{
EXPECT_TRUE(cmpF(out_vec_gapi, out_vec_ocv));
}
fitLineTestBody(in_mat1, distType, cmpF, getCompileArgs());
}
TEST_P(FitLine3DVector32STest, AccuracyTest)
{
cv::Vec6f out_vec_gapi, out_vec_ocv;
double paramDefault = 0., repsDefault = 0., aepsDefault = 0.;
std::vector<cv::Point3i> in_vec;
initPointsVectorRandU(sz.width, in_vec);
// G-API code //////////////////////////////////////////////////////////////
cv::GArray<cv::Point3i> in;
auto out = cv::gapi::fitLine3D(in, distType, paramDefault, repsDefault, aepsDefault);
cv::GComputation c(cv::GIn(in), cv::GOut(out));
c.apply(cv::gin(in_vec), cv::gout(out_vec_gapi), getCompileArgs());
// OpenCV code /////////////////////////////////////////////////////////////
{
cv::fitLine(in_vec, out_vec_ocv, distType, paramDefault, repsDefault, aepsDefault);
}
// Comparison //////////////////////////////////////////////////////////////
{
EXPECT_TRUE(cmpF(out_vec_gapi, out_vec_ocv));
}
fitLineTestBody(in_vec, distType, cmpF, getCompileArgs());
}
TEST_P(FitLine3DVector32FTest, AccuracyTest)
{
cv::Vec6f out_vec_gapi, out_vec_ocv;
double paramDefault = 0., repsDefault = 0., aepsDefault = 0.;
std::vector<cv::Point3f> in_vec;
initPointsVectorRandU(sz.width, in_vec);
// G-API code //////////////////////////////////////////////////////////////
cv::GArray<cv::Point3f> in;
auto out = cv::gapi::fitLine3D(in, distType, paramDefault, repsDefault, aepsDefault);
cv::GComputation c(cv::GIn(in), cv::GOut(out));
c.apply(cv::gin(in_vec), cv::gout(out_vec_gapi), getCompileArgs());
// OpenCV code /////////////////////////////////////////////////////////////
{
cv::fitLine(in_vec, out_vec_ocv, distType, paramDefault, repsDefault, aepsDefault);
}
// Comparison //////////////////////////////////////////////////////////////
{
EXPECT_TRUE(cmpF(out_vec_gapi, out_vec_ocv));
}
fitLineTestBody(in_vec, distType, cmpF, getCompileArgs());
}
TEST_P(FitLine3DVector64FTest, AccuracyTest)
{
cv::Vec6f out_vec_gapi, out_vec_ocv;
double paramDefault = 0., repsDefault = 0., aepsDefault = 0.;
std::vector<cv::Point3d> in_vec;
initPointsVectorRandU(sz.width, in_vec);
// G-API code //////////////////////////////////////////////////////////////
cv::GArray<cv::Point3d> in;
auto out = cv::gapi::fitLine3D(in, distType, paramDefault, repsDefault, aepsDefault);
cv::GComputation c(cv::GIn(in), cv::GOut(out));
c.apply(cv::gin(in_vec), cv::gout(out_vec_gapi), getCompileArgs());
// OpenCV code /////////////////////////////////////////////////////////////
{
cv::fitLine(in_vec, out_vec_ocv, distType, paramDefault, repsDefault, aepsDefault);
}
// Comparison //////////////////////////////////////////////////////////////
{
EXPECT_TRUE(cmpF(out_vec_gapi, out_vec_ocv));
}
fitLineTestBody(in_vec, distType, cmpF, getCompileArgs());
}
TEST_P(BGR2RGBTest, AccuracyTest)
@@ -130,6 +130,8 @@ struct Fixture : public RenderBGRTestBase API { \
#define GAPI_RENDER_TEST_FIXTURES(Fixture, API, Number, ...) \
GAPI_RENDER_TEST_FIXTURE_BGR(RenderBGR##Fixture, GET_VA_ARGS(API), Number, __VA_ARGS__) \
GAPI_RENDER_TEST_FIXTURE_NV12(RenderNV12##Fixture, GET_VA_ARGS(API), Number, __VA_ARGS__) \
GAPI_RENDER_TEST_FIXTURE_NV12(RenderMFrame##Fixture, GET_VA_ARGS(API), Number, __VA_ARGS__) \
using Points = std::vector<cv::Point>;
GAPI_RENDER_TEST_FIXTURES(TestTexts, FIXTURE_API(std::string, cv::Point, double, cv::Scalar), 4, text, org, fs, color)
@@ -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"
@@ -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
@@ -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_STEREO
#include <opencv2/stereo.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_STEREO
#endif // OPENCV_GAPI_STEREO_TESTS_INL_HPP
+49 -8
View File
@@ -58,7 +58,7 @@ namespace
return o;
}
inline void initTestDataPath()
inline bool initTestDataPathSilent()
{
#ifndef WINRT
static bool initialized = false;
@@ -66,15 +66,32 @@ namespace
{
// Since G-API has no own test data (yet), it is taken from the common space
const char* testDataPath = getenv("OPENCV_TEST_DATA_PATH");
GAPI_Assert(testDataPath != nullptr &&
"OPENCV_TEST_DATA_PATH environment variable is either not set or set incorrectly.");
cvtest::addDataSearchPath(testDataPath);
initialized = true;
if (testDataPath != nullptr) {
cvtest::addDataSearchPath(testDataPath);
initialized = true;
}
}
return initialized;
#endif // WINRT
}
inline void initTestDataPath()
{
bool initialized = initTestDataPathSilent();
GAPI_Assert(initialized &&
"OPENCV_TEST_DATA_PATH environment variable is either not set or set incorrectly.");
}
inline void initTestDataPathOrSkip()
{
bool initialized = initTestDataPathSilent();
if (!initialized)
{
throw cvtest::SkipTestException("Can't find test data");
}
}
template <typename T> inline void initPointRandU(cv::RNG &rng, cv::Point_<T>& pt)
{
GAPI_Assert(std::is_integral<T>::value);
@@ -324,7 +341,7 @@ public:
}
template <typename T>
inline void initPointRandU(cv::RNG& rng, T& pt)
inline void initPointRandU(cv::RNG& rng, T& pt) const
{ ::initPointRandU(rng, pt); }
// Disable unreachable code warning for MSVS 2015
@@ -334,7 +351,7 @@ public:
#endif
// initialize std::vector<cv::Point_<T>>/std::vector<cv::Point3_<T>>
template <typename T, template <typename> class Pt>
void initPointsVectorRandU(const int sz_in, std::vector<Pt<T>> &vec_)
void initPointsVectorRandU(const int sz_in, std::vector<Pt<T>> &vec_) const
{
cv::RNG& rng = theRNG();
@@ -593,6 +610,8 @@ using compare_vec_f = std::function<bool(const cv::Vec<Elem, cn> &a, const cv::V
template<typename T1, typename T2>
struct CompareF
{
CompareF() = default;
using callable_t = std::function<bool(const T1& a, const T2& b)>;
CompareF(callable_t&& cmp, std::string&& cmp_name) :
_comparator(std::move(cmp)), _name(std::move(cmp_name)) {}
@@ -1174,6 +1193,28 @@ inline std::ostream& operator<<(std::ostream& os, DistanceTypes op)
#undef CASE
return os;
}
inline std::ostream& operator<<(std::ostream& os, KmeansFlags op)
{
int op_(op);
switch (op_)
{
case KmeansFlags::KMEANS_RANDOM_CENTERS:
os << "KMEANS_RANDOM_CENTERS";
break;
case KmeansFlags::KMEANS_PP_CENTERS:
os << "KMEANS_PP_CENTERS";
break;
case KmeansFlags::KMEANS_RANDOM_CENTERS | KmeansFlags::KMEANS_USE_INITIAL_LABELS:
os << "KMEANS_RANDOM_CENTERS | KMEANS_USE_INITIAL_LABELS";
break;
case KmeansFlags::KMEANS_PP_CENTERS | KmeansFlags::KMEANS_USE_INITIAL_LABELS:
os << "KMEANS_PP_CENTERS | KMEANS_USE_INITIAL_LABELS";
break;
default: GAPI_Assert(false && "unknown KmeansFlags value");
}
return os;
}
} // namespace cv
#endif //OPENCV_GAPI_TESTS_COMMON_HPP
@@ -28,6 +28,16 @@ GAPI_TEST_FIXTURE_SPEC_PARAMS(BuildPyr_CalcOptFlow_PipelineTest,
FIXTURE_API(std::string,int,int,bool), 4,
fileNamePattern, winSize, maxLevel, withDerivatives)
GAPI_TEST_FIXTURE_SPEC_PARAMS(BackgroundSubtractorTest, FIXTURE_API(tuple<cv::gapi::video::BackgroundSubtractorType,double>,
int, bool, double, std::string, std::size_t),
6, typeAndThreshold, histLength, detectShadows, learningRate, filePath, testNumFrames)
GAPI_TEST_FIXTURE_SPEC_PARAMS(KalmanFilterTest, FIXTURE_API(int, int, int, int, int), 5, type, dDim, mDim, cDim, numIter)
GAPI_TEST_FIXTURE_SPEC_PARAMS(KalmanFilterNoControlTest, FIXTURE_API(int, int, int, int), 4, type, dDim, mDim, numIter)
GAPI_TEST_FIXTURE_SPEC_PARAMS(KalmanFilterCircleSampleTest, FIXTURE_API(int, int), 2, type, numIter)
} // opencv_test
@@ -15,7 +15,6 @@
#endif // HAVE_OPENCV_VIDEO
namespace opencv_test
{
namespace
@@ -128,6 +127,54 @@ struct OptFlowLKTestParams
int flags = 0;
};
inline void compareOutputPyramids(const BuildOpticalFlowPyramidTestOutput& outGAPI,
const BuildOpticalFlowPyramidTestOutput& outOCV)
{
GAPI_Assert(outGAPI.maxLevel == outOCV.maxLevel);
GAPI_Assert(outOCV.maxLevel >= 0);
const size_t maxLevel = static_cast<size_t>(outOCV.maxLevel);
for (size_t i = 0; i <= maxLevel; i++)
{
EXPECT_TRUE(AbsExact().to_compare_f()(outGAPI.pyramid[i], outOCV.pyramid[i]));
}
}
template <typename Elem>
inline bool compareVectorsAbsExactForOptFlow(const std::vector<Elem>& outGAPI,
const std::vector<Elem>& outOCV)
{
return AbsExactVector<Elem>().to_compare_f()(outGAPI, outOCV);
}
inline void compareOutputsOptFlow(const OptFlowLKTestOutput& outGAPI,
const OptFlowLKTestOutput& outOCV)
{
EXPECT_TRUE(compareVectorsAbsExactForOptFlow(outGAPI.nextPoints, outOCV.nextPoints));
EXPECT_TRUE(compareVectorsAbsExactForOptFlow(outGAPI.statuses, outOCV.statuses));
EXPECT_TRUE(compareVectorsAbsExactForOptFlow(outGAPI.errors, outOCV.errors));
}
inline std::ostream& operator<<(std::ostream& os, const cv::TermCriteria& criteria)
{
os << "{";
switch (criteria.type) {
case cv::TermCriteria::COUNT:
os << "COUNT; ";
break;
case cv::TermCriteria::EPS:
os << "EPS; ";
break;
case cv::TermCriteria::COUNT | cv::TermCriteria::EPS:
os << "COUNT | EPS; ";
break;
default:
os << "TypeUndefined; ";
break;
};
return os << criteria.maxCount << "; " << criteria.epsilon <<"}";
}
#ifdef HAVE_OPENCV_VIDEO
inline GComputation runOCVnGAPIBuildOptFlowPyramid(TestFunctional& testInst,
@@ -321,6 +368,66 @@ inline GComputation runOCVnGAPIOptFlowPipeline(TestFunctional& testInst,
return c;
}
inline void testBackgroundSubtractorStreaming(cv::GStreamingCompiled& gapiBackSub,
const cv::Ptr<cv::BackgroundSubtractor>& pOCVBackSub,
const int diffPercent, const int tolerance,
const double lRate, const std::size_t testNumFrames)
{
cv::Mat frame, gapiForeground, ocvForeground;
double numDiff = diffPercent / 100.0;
gapiBackSub.start();
EXPECT_TRUE(gapiBackSub.running());
compare_f cmpF = AbsSimilarPoints(tolerance, numDiff).to_compare_f();
// Comparison of G-API and OpenCV substractors
std::size_t frames = 0u;
while (frames <= testNumFrames && gapiBackSub.pull(cv::gout(frame, gapiForeground)))
{
pOCVBackSub->apply(frame, ocvForeground, lRate);
EXPECT_TRUE(cmpF(gapiForeground, ocvForeground));
frames++;
}
if (gapiBackSub.running())
gapiBackSub.stop();
EXPECT_LT(0u, frames);
EXPECT_FALSE(gapiBackSub.running());
}
inline void initKalmanParams(const int type, const int dDim, const int mDim, const int cDim,
cv::gapi::KalmanParams& kp)
{
kp.state = Mat::zeros(dDim, 1, type);
cv::randu(kp.state, Scalar::all(0), Scalar::all(0.1));
kp.errorCov = Mat::eye(dDim, dDim, type);
kp.transitionMatrix = Mat::ones(dDim, dDim, type) * 2;
kp.processNoiseCov = Mat::eye(dDim, dDim, type) * (1e-5);
kp.measurementMatrix = Mat::eye(mDim, dDim, type) * 2;
kp.measurementNoiseCov = Mat::eye(mDim, mDim, type) * (1e-5);
if (cDim > 0)
kp.controlMatrix = Mat::eye(dDim, cDim, type) * (1e-3);
}
inline void initKalmanFilter(const cv::gapi::KalmanParams& kp, const bool control,
cv::KalmanFilter& ocvKalman)
{
kp.state.copyTo(ocvKalman.statePost);
kp.errorCov.copyTo(ocvKalman.errorCovPost);
kp.transitionMatrix.copyTo(ocvKalman.transitionMatrix);
kp.measurementMatrix.copyTo(ocvKalman.measurementMatrix);
kp.measurementNoiseCov.copyTo(ocvKalman.measurementNoiseCov);
kp.processNoiseCov.copyTo(ocvKalman.processNoiseCov);
if (control)
kp.controlMatrix.copyTo(ocvKalman.controlMatrix);
}
#else // !HAVE_OPENCV_VIDEO
inline cv::GComputation runOCVnGAPIBuildOptFlowPyramid(TestFunctional&,
@@ -361,54 +468,24 @@ inline GComputation runOCVnGAPIOptFlowPipeline(TestFunctional&,
#endif // HAVE_OPENCV_VIDEO
inline void compareOutputPyramids(const BuildOpticalFlowPyramidTestOutput& outOCV,
const BuildOpticalFlowPyramidTestOutput& outGAPI)
{
GAPI_Assert(outGAPI.maxLevel == outOCV.maxLevel);
GAPI_Assert(outOCV.maxLevel >= 0);
size_t maxLevel = static_cast<size_t>(outOCV.maxLevel);
for (size_t i = 0; i <= maxLevel; i++)
{
EXPECT_TRUE(AbsExact().to_compare_f()(outOCV.pyramid[i], outGAPI.pyramid[i]));
}
}
template <typename Elem>
inline bool compareVectorsAbsExactForOptFlow(std::vector<Elem> outOCV, std::vector<Elem> outGAPI)
{
return AbsExactVector<Elem>().to_compare_f()(outOCV, outGAPI);
}
inline void compareOutputsOptFlow(const OptFlowLKTestOutput& outOCV,
const OptFlowLKTestOutput& outGAPI)
{
EXPECT_TRUE(compareVectorsAbsExactForOptFlow(outGAPI.nextPoints, outOCV.nextPoints));
EXPECT_TRUE(compareVectorsAbsExactForOptFlow(outGAPI.statuses, outOCV.statuses));
EXPECT_TRUE(compareVectorsAbsExactForOptFlow(outGAPI.errors, outOCV.errors));
}
inline std::ostream& operator<<(std::ostream& os, const cv::TermCriteria& criteria)
{
os << "{";
switch (criteria.type) {
case cv::TermCriteria::COUNT:
os << "COUNT; ";
break;
case cv::TermCriteria::EPS:
os << "EPS; ";
break;
case cv::TermCriteria::COUNT | cv::TermCriteria::EPS:
os << "COUNT | EPS; ";
break;
default:
os << "TypeUndefined; ";
break;
};
return os << criteria.maxCount << "; " << criteria.epsilon <<"}";
}
} // namespace
} // namespace opencv_test
// Note: namespace must match the namespace of the type of the printed object
namespace cv { namespace gapi { namespace video
{
inline std::ostream& operator<<(std::ostream& os, const BackgroundSubtractorType op)
{
#define CASE(v) case BackgroundSubtractorType::v: os << #v; break
switch (op)
{
CASE(TYPE_BS_MOG2);
CASE(TYPE_BS_KNN);
default: GAPI_Assert(false && "unknown BackgroundSubtractor type");
}
#undef CASE
return os;
}
}}} // namespace cv::gapi::video
#endif // OPENCV_GAPI_VIDEO_TESTS_COMMON_HPP
@@ -8,6 +8,7 @@
#define OPENCV_GAPI_VIDEO_TESTS_INL_HPP
#include "gapi_video_tests.hpp"
#include <opencv2/gapi/streaming/cap.hpp>
namespace opencv_test
{
@@ -26,7 +27,7 @@ TEST_P(BuildOptFlowPyramidTest, AccuracyTest)
runOCVnGAPIBuildOptFlowPyramid(*this, params, outOCV, outGAPI);
compareOutputPyramids(outOCV, outGAPI);
compareOutputPyramids(outGAPI, outOCV);
}
TEST_P(OptFlowLKTest, AccuracyTest)
@@ -43,7 +44,7 @@ TEST_P(OptFlowLKTest, AccuracyTest)
runOCVnGAPIOptFlowLK(*this, inPts, params, outOCV, outGAPI);
compareOutputsOptFlow(outOCV, outGAPI);
compareOutputsOptFlow(outGAPI, outOCV);
}
TEST_P(OptFlowLKTestForPyr, AccuracyTest)
@@ -62,7 +63,7 @@ TEST_P(OptFlowLKTestForPyr, AccuracyTest)
runOCVnGAPIOptFlowLKForPyr(*this, in, params, withDeriv, outOCV, outGAPI);
compareOutputsOptFlow(outOCV, outGAPI);
compareOutputsOptFlow(outGAPI, outOCV);
}
TEST_P(BuildPyr_CalcOptFlow_PipelineTest, AccuracyTest)
@@ -85,9 +86,238 @@ TEST_P(BuildPyr_CalcOptFlow_PipelineTest, AccuracyTest)
runOCVnGAPIOptFlowPipeline(*this, params, outOCV, outGAPI, inPts);
compareOutputsOptFlow(outOCV, outGAPI);
compareOutputsOptFlow(outGAPI, outOCV);
}
#ifdef HAVE_OPENCV_VIDEO
TEST_P(BackgroundSubtractorTest, AccuracyTest)
{
initTestDataPath();
cv::gapi::video::BackgroundSubtractorType opType;
double thr = -1;
std::tie(opType, thr) = typeAndThreshold;
cv::gapi::video::BackgroundSubtractorParams bsp(opType, histLength, thr,
detectShadows, learningRate);
// G-API graph declaration
cv::GMat in;
cv::GMat out = cv::gapi::BackgroundSubtractor(in, bsp);
// Preserving 'in' in output to have possibility to compare with OpenCV reference
cv::GComputation c(cv::GIn(in), cv::GOut(cv::gapi::copy(in), out));
// G-API compilation of graph for streaming mode
auto gapiBackSub = c.compileStreaming(getCompileArgs());
// Testing G-API Background Substractor in streaming mode
const auto path = findDataFile(filePath);
try
{
gapiBackSub.setSource(gapi::wip::make_src<cv::gapi::wip::GCaptureSource>(path));
}
catch (...)
{ throw SkipTestException("Video file can't be opened."); }
cv::Ptr<cv::BackgroundSubtractor> pOCVBackSub;
if (opType == cv::gapi::video::TYPE_BS_MOG2)
pOCVBackSub = cv::createBackgroundSubtractorMOG2(histLength, thr,
detectShadows);
else if (opType == cv::gapi::video::TYPE_BS_KNN)
pOCVBackSub = cv::createBackgroundSubtractorKNN(histLength, thr,
detectShadows);
// Allowing 1% difference of all pixels between G-API and reference OpenCV results
testBackgroundSubtractorStreaming(gapiBackSub, pOCVBackSub, 1, 1, learningRate, testNumFrames);
}
TEST_P(KalmanFilterTest, AccuracyTest)
{
cv::gapi::KalmanParams kp;
initKalmanParams(type, dDim, mDim, cDim, kp);
// OpenCV reference KalmanFilter initialization
cv::KalmanFilter ocvKalman(dDim, mDim, cDim, type);
initKalmanFilter(kp, true, ocvKalman);
// measurement vector
cv::Mat measure_vec(mDim, 1, type);
// control vector
cv::Mat ctrl_vec = Mat::zeros(cDim > 0 ? cDim : 2, 1, type);
// G-API Kalman's output state
cv::Mat gapiKState(dDim, 1, type);
// OCV Kalman's output state
cv::Mat ocvKState(dDim, 1, type);
// G-API graph initialization
cv::GMat m, ctrl;
cv::GOpaque<bool> have_m;
cv::GMat out = cv::gapi::KalmanFilter(m, have_m, ctrl, kp);
cv::GComputation comp(cv::GIn(m, have_m, ctrl), cv::GOut(out));
cv::RNG& rng = cv::theRNG();
bool haveMeasure;
for (int i = 0; i < numIter; i++)
{
haveMeasure = (rng(2u) == 1); // returns 0 or 1 - whether we have measurement at this iteration or not
if (haveMeasure)
cv::randu(measure_vec, Scalar::all(-1), Scalar::all(1));
if (cDim > 0)
cv::randu(ctrl_vec, Scalar::all(-1), Scalar::all(1));
// G-API KalmanFilter call
comp.apply(cv::gin(measure_vec, haveMeasure, ctrl_vec), cv::gout(gapiKState));
// OpenCV KalmanFilter call
ocvKState = cDim > 0 ? ocvKalman.predict(ctrl_vec) : ocvKalman.predict();
if (haveMeasure)
ocvKState = ocvKalman.correct(measure_vec);
}
// Comparison //////////////////////////////////////////////////////////////
{
EXPECT_TRUE(AbsExact().to_compare_f()(gapiKState, ocvKState));
}
}
TEST_P(KalmanFilterNoControlTest, AccuracyTest)
{
cv::gapi::KalmanParams kp;
initKalmanParams(type, dDim, mDim, 0, kp);
// OpenCV reference KalmanFilter initialization
cv::KalmanFilter ocvKalman(dDim, mDim, 0, type);
initKalmanFilter(kp, false, ocvKalman);
// measurement vector
cv::Mat measure_vec(mDim, 1, type);
// G-API Kalman's output state
cv::Mat gapiKState(dDim, 1, type);
// OCV Kalman's output state
cv::Mat ocvKState(dDim, 1, type);
// G-API graph initialization
cv::GMat m;
cv::GOpaque<bool> have_m;
cv::GMat out = cv::gapi::KalmanFilter(m, have_m, kp);
cv::GComputation comp(cv::GIn(m, have_m), cv::GOut(out));
cv::RNG& rng = cv::theRNG();
bool haveMeasure;
for (int i = 0; i < numIter; i++)
{
haveMeasure = (rng(2u) == 1); // returns 0 or 1 - whether we have measurement at this iteration or not
if (haveMeasure)
cv::randu(measure_vec, Scalar::all(-1), Scalar::all(1));
// G-API
comp.apply(cv::gin(measure_vec, haveMeasure), cv::gout(gapiKState));
// OpenCV
ocvKState = ocvKalman.predict();
if (haveMeasure)
ocvKState = ocvKalman.correct(measure_vec);
}
// Comparison //////////////////////////////////////////////////////////////
{
EXPECT_TRUE(AbsExact().to_compare_f()(gapiKState, ocvKState));
}
}
TEST_P(KalmanFilterCircleSampleTest, AccuracyTest)
{
// auxiliary variables
cv::Mat processNoise(2, 1, type);
// Input measurement
cv::Mat measurement = Mat::zeros(1, 1, type);
// Angle and it's delta(phi, delta_phi)
cv::Mat state(2, 1, type);
// G-API graph initialization
cv::gapi::KalmanParams kp;
kp.state = Mat::zeros(2, 1, type);
cv::randn(kp.state, Scalar::all(0), Scalar::all(0.1));
kp.errorCov = Mat::eye(2, 2, type);
if (type == CV_32F)
kp.transitionMatrix = (Mat_<float>(2, 2) << 1, 1, 0, 1);
else
kp.transitionMatrix = (Mat_<double>(2, 2) << 1, 1, 0, 1);
kp.processNoiseCov = Mat::eye(2, 2, type) * (1e-5);
kp.measurementMatrix = Mat::eye(1, 2, type);
kp.measurementNoiseCov = Mat::eye(1, 1, type) * (1e-1);
cv::GMat m;
cv::GOpaque<bool> have_measure;
cv::GMat out = cv::gapi::KalmanFilter(m, have_measure, kp);
cv::GComputation comp(cv::GIn(m, have_measure), cv::GOut(out));
// OCV Kalman initialization
cv::KalmanFilter KF(2, 1, 0);
initKalmanFilter(kp, false, KF);
cv::randn(state, Scalar::all(0), Scalar::all(0.1));
// GAPI Corrected state
cv::Mat gapiState(2, 1, type);
// OCV Corrected state
cv::Mat ocvCorrState(2, 1, type);
// OCV Predicted state
cv::Mat ocvPreState(2, 1, type);
bool haveMeasure;
for (int i = 0; i < numIter; ++i)
{
// Get OCV Prediction
ocvPreState = KF.predict();
GAPI_DbgAssert(cv::norm(kp.measurementNoiseCov, KF.measurementNoiseCov, cv::NORM_INF) == 0);
// generation measurement
cv::randn(measurement, Scalar::all(0), Scalar::all((type == CV_32FC1) ?
kp.measurementNoiseCov.at<float>(0) : kp.measurementNoiseCov.at<double>(0)));
GAPI_DbgAssert(cv::norm(kp.measurementMatrix, KF.measurementMatrix, cv::NORM_INF) == 0);
measurement += kp.measurementMatrix*state;
if (cv::theRNG().uniform(0, 4) != 0)
{
haveMeasure = true;
ocvCorrState = KF.correct(measurement);
comp.apply(cv::gin(measurement, haveMeasure), cv::gout(gapiState));
EXPECT_TRUE(AbsExact().to_compare_f()(gapiState, ocvCorrState));
}
else
{
// Get GAPI Prediction
haveMeasure = false;
comp.apply(cv::gin(measurement, haveMeasure), cv::gout(gapiState));
EXPECT_TRUE(AbsExact().to_compare_f()(gapiState, ocvPreState));
}
GAPI_DbgAssert(cv::norm(kp.processNoiseCov, KF.processNoiseCov, cv::NORM_INF) == 0);
cv::randn(processNoise, Scalar(0), Scalar::all(sqrt(type == CV_32FC1 ?
kp.processNoiseCov.at<float>(0, 0):
kp.processNoiseCov.at<double>(0, 0))));
GAPI_DbgAssert(cv::norm(kp.transitionMatrix, KF.transitionMatrix, cv::NORM_INF) == 0);
state = kp.transitionMatrix*state + processNoise;
}
}
#endif
} // opencv_test
#endif // OPENCV_GAPI_VIDEO_TESTS_INL_HPP