feat: 切换后端至PaddleOCR-NCNN,切换工程为CMake

1.项目后端整体迁移至PaddleOCR-NCNN算法,已通过基本的兼容性测试
2.工程改为使用CMake组织,后续为了更好地兼容第三方库,不再提供QMake工程
3.重整权利声明文件,重整代码工程,确保最小化侵权风险

Log: 切换后端至PaddleOCR-NCNN,切换工程为CMake
Change-Id: I4d5d2c5d37505a4a24b389b1a4c5d12f17bfa38c
This commit is contained in:
wangzhengyang
2022-05-10 09:54:44 +08:00
parent ecdd171c6f
commit 718c41634f
10018 changed files with 3593797 additions and 186748 deletions

View File

@ -0,0 +1,951 @@
#include "../test_precomp.hpp"
#include "backends/common/serialization.hpp"
#include <opencv2/gapi/rmat.hpp>
#include <opencv2/gapi/media.hpp>
#include <../src/backends/common/gbackend.hpp> // asView
namespace {
struct EmptyCustomType { };
struct SimpleCustomType {
bool val;
bool operator==(const SimpleCustomType& other) const {
return val == other.val;
}
};
struct SimpleCustomType2 {
int id;
bool operator==(const SimpleCustomType2& other) const {
return id == other.id;
}
};
struct MyCustomType {
int val;
std::string name;
std::vector<float> vec;
std::map<int, uint64_t> mmap;
bool operator==(const MyCustomType& other) const {
return val == other.val && name == other.name &&
vec == other.vec && mmap == other.mmap;
}
};
struct MyCustomTypeNoS11N {
char sym;
int id;
std::string name;
bool operator==(const MyCustomTypeNoS11N& other) const {
return sym == other.sym && id == other.id &&
name == other.name;
}
};
} // anonymous namespace
namespace cv {
namespace gapi {
namespace s11n {
namespace detail {
template<> struct S11N<EmptyCustomType> {
static void serialize(IOStream &, const EmptyCustomType &) { }
static EmptyCustomType deserialize(IIStream &) { return EmptyCustomType { }; }
};
template<> struct S11N<SimpleCustomType> {
static void serialize(IOStream &os, const SimpleCustomType &p) {
os << p.val;
}
static SimpleCustomType deserialize(IIStream &is) {
SimpleCustomType p;
is >> p.val;
return p;
}
};
template<> struct S11N<SimpleCustomType2> {
static void serialize(IOStream &os, const SimpleCustomType2 &p) {
os << p.id;
}
static SimpleCustomType2 deserialize(IIStream &is) {
SimpleCustomType2 p;
is >> p.id;
return p;
}
};
template<> struct S11N<MyCustomType> {
static void serialize(IOStream &os, const MyCustomType &p) {
os << p.val << p.name << p.vec << p.mmap;
}
static MyCustomType deserialize(IIStream &is) {
MyCustomType p;
is >> p.val >> p.name >> p.vec >> p.mmap;
return p;
}
};
} // namespace detail
} // namespace s11n
} // namespace gapi
} // namespace cv
namespace cv {
namespace detail {
template<> struct CompileArgTag<EmptyCustomType> {
static const char* tag() {
return "org.opencv.test.empty_custom_type";
}
};
template<> struct CompileArgTag<SimpleCustomType> {
static const char* tag() {
return "org.opencv.test.simple_custom_type";
}
};
template<> struct CompileArgTag<SimpleCustomType2> {
static const char* tag() {
return "org.opencv.test.simple_custom_type_2";
}
};
template<> struct CompileArgTag<MyCustomType> {
static const char* tag() {
return "org.opencv.test.my_custom_type";
}
};
template<> struct CompileArgTag<MyCustomTypeNoS11N> {
static const char* tag() {
return "org.opencv.test.my_custom_type_no_s11n";
}
};
} // namespace detail
} // namespace cv
namespace {
class MyRMatAdapter : public cv::RMat::Adapter {
cv::Mat m_mat;
int m_value;
std::string m_str;
public:
MyRMatAdapter() = default;
MyRMatAdapter(cv::Mat m, int value, const std::string& str)
: m_mat(m), m_value(value), m_str(str)
{}
virtual cv::RMat::View access(cv::RMat::Access) override {
return cv::gimpl::asView(m_mat);
}
virtual cv::GMatDesc desc() const override { return cv::descr_of(m_mat); }
virtual void serialize(cv::gapi::s11n::IOStream& os) override {
os << m_value << m_str;
}
virtual void deserialize(cv::gapi::s11n::IIStream& is) override {
is >> m_value >> m_str;
}
int getVal() { return m_value; }
std::string getStr() { return m_str; }
};
class MyMediaFrameAdapter : public cv::MediaFrame::IAdapter {
cv::Mat m_mat;
int m_value;
std::string m_str;
public:
MyMediaFrameAdapter() = default;
MyMediaFrameAdapter(cv::Mat m, int value, const std::string& str)
: m_mat(m), m_value(value), m_str(str)
{}
virtual cv::MediaFrame::View access(cv::MediaFrame::Access) override {
return cv::MediaFrame::View({m_mat.data}, {m_mat.step});
}
virtual cv::GFrameDesc meta() const override { return {cv::MediaFormat::BGR, m_mat.size()}; }
virtual void serialize(cv::gapi::s11n::IOStream& os) override {
os << m_value << m_str;
}
virtual void deserialize(cv::gapi::s11n::IIStream& is) override {
is >> m_value >> m_str;
}
int getVal() { return m_value; }
std::string getStr() { return m_str; }
};
}
namespace opencv_test {
struct S11N_Basic: public ::testing::Test {
template<typename T> void put(T &&t) {
cv::gapi::s11n::ByteMemoryOutStream os;
os << t;
m_buffer = os.data();
}
template<typename T> T get() {
// FIXME: This stream API needs a fix-up
cv::gapi::s11n::ByteMemoryInStream is(m_buffer);
T t{};
is >> t;
return t;
}
private:
std::vector<char> m_buffer;
};
namespace
{
template<typename T>
bool operator==(const cv::detail::VectorRef& a, const cv::detail::VectorRef& b)
{
return a.rref<T>() == b.rref<T>();
}
template<typename T>
bool operator==(const cv::detail::OpaqueRef& a, const cv::detail::OpaqueRef& b)
{
return a.rref<T>() == b.rref<T>();
}
}
TEST_F(S11N_Basic, Test_int_pos) {
int x = 42;
put(x);
EXPECT_EQ(x, get<int>());
}
TEST_F(S11N_Basic, Test_int_neg) {
int x = -42;
put(x);
EXPECT_EQ(x, get<int>());
}
TEST_F(S11N_Basic, Test_fp32) {
float x = 3.14f;
put(x);
EXPECT_EQ(x, get<float>());
}
TEST_F(S11N_Basic, Test_fp64) {
double x = 3.14;
put(x);
EXPECT_EQ(x, get<double>());
}
TEST_F(S11N_Basic, Test_uint64) {
uint64_t x = 2147483647374;
put(x);
EXPECT_EQ(x, get<uint64_t>());
}
TEST_F(S11N_Basic, Test_int32_pos) {
int32_t x = 2147483647;
put(x);
EXPECT_EQ(x, get<int32_t>());
}
TEST_F(S11N_Basic, Test_int32_neg) {
int32_t x = -2147483646;
put(x);
EXPECT_EQ(x, get<int32_t>());
}
TEST_F(S11N_Basic, Test_vector_bool) {
std::vector<bool> v = {false, true, false};
put(v);
EXPECT_EQ(v, get<std::vector<bool>>());
}
TEST_F(S11N_Basic, Test_map_string2string) {
using T = std::map<std::string, std::string>;
T v;
v["gapi"] = "cool";
v["42"] = "answer";
v["hi"] = "hello there";
put(v);
EXPECT_EQ(v, get<T>());
}
TEST_F(S11N_Basic, Test_map_int2int) {
using T = std::map<int, int32_t>;
T v;
v[1] = 23;
v[-100] = 0;
v[435346] = -12346;
put(v);
EXPECT_EQ(v, get<T>());
}
TEST_F(S11N_Basic, Test_map_float2cvsize) {
using T = std::map<float, cv::Size>;
T v;
v[0.4f] = cv::Size(4, 5);
v[234.43f] = cv::Size(3421, 321);
v[2223.f] = cv::Size(1920, 1080);
put(v);
EXPECT_EQ(v, get<T>());
}
TEST_F(S11N_Basic, Test_map_uint642cvmat) {
using T = std::map<uint64_t, cv::Mat>;
T v;
v[21304805324] = cv::Mat(3, 3, CV_8UC1, cv::Scalar::all(3));
v[4353245222] = cv::Mat(5, 5, CV_8UC3, cv::Scalar::all(7));
v[0] = cv::Mat(10, 10, CV_32FC2, cv::Scalar::all(-128.f));
put(v);
auto out_v = get<T>();
for (const auto& el : out_v) {
EXPECT_NE(v.end(), v.find(el.first));
EXPECT_EQ(0, cv::norm(el.second, v[el.first]));
}
}
TEST_F(S11N_Basic, Test_vector_int) {
std::vector<int> v = {1,2,3};
put(v);
EXPECT_EQ(v, get<std::vector<int>>());
}
TEST_F(S11N_Basic, Test_vector_cvSize) {
std::vector<cv::Size> v = {
cv::Size(640, 480),
cv::Size(1280, 1024),
};
put(v);
EXPECT_EQ(v, get<std::vector<cv::Size>>());
}
TEST_F(S11N_Basic, Test_vector_string) {
std::vector<std::string> v = {
"hello",
"world",
"ok!"
};
put(v);
EXPECT_EQ(v, get<std::vector<std::string>>());
}
TEST_F(S11N_Basic, Test_vector_empty) {
std::vector<char> v;
put(v);
EXPECT_EQ(v, get<std::vector<char>>());
}
TEST_F(S11N_Basic, Test_variant) {
using S = std::string;
using V = cv::util::variant<int,S>;
V v1{42}, v2{S{"hey"}};
put(v1);
EXPECT_EQ(v1, get<V>());
put(v2);
EXPECT_EQ(v2, get<V>());
}
TEST_F(S11N_Basic, Test_GArg_int) {
const int x = 42;
cv::GArg gs(x);
put(gs);
cv::GArg gd = get<cv::GArg>();
EXPECT_EQ(cv::detail::ArgKind::OPAQUE_VAL, gd.kind);
EXPECT_EQ(cv::detail::OpaqueKind::CV_INT, gd.opaque_kind);
EXPECT_EQ(x, gs.get<int>());
}
TEST_F(S11N_Basic, Test_GArg_Point) {
const cv::Point pt{1,2};
cv::GArg gs(pt);
put(gs);
cv::GArg gd = get<cv::GArg>();
EXPECT_EQ(cv::detail::ArgKind::OPAQUE_VAL, gd.kind);
EXPECT_EQ(cv::detail::OpaqueKind::CV_POINT, gd.opaque_kind);
EXPECT_EQ(pt, gs.get<cv::Point>());
}
TEST_F(S11N_Basic, Test_Mat_full) {
auto mat = cv::Mat::eye(cv::Size(64,64), CV_8UC3);
put(mat);
EXPECT_EQ(0, cv::norm(mat, get<cv::Mat>(), cv::NORM_INF));
}
TEST_F(S11N_Basic, Test_Mat_view) {
auto mat = cv::Mat::eye(cv::Size(320,240), CV_8UC3);
auto view = mat(cv::Rect(10,15,123,70));
put(view);
EXPECT_EQ(0, cv::norm(view, get<cv::Mat>(), cv::NORM_INF));
}
TEST_F(S11N_Basic, Test_MatDesc) {
cv::GMatDesc v = { CV_8U, 1, {320,240} };
put(v);
EXPECT_EQ(v, get<cv::GMatDesc>());
}
TEST_F(S11N_Basic, Test_MatDescND) {
cv::GMatDesc v = { CV_8U, {1,1,224,224} };
put(v);
EXPECT_EQ(v, get<cv::GMatDesc>());
}
TEST_F(S11N_Basic, Test_MetaArg_MatDesc) {
cv::GMatDesc desc = { CV_8U, 1,{ 320,240 } };
auto v = cv::GMetaArg{ desc };
put(v);
cv::GMetaArg out_v = get<cv::GMetaArg>();
cv::GMatDesc out_desc = cv::util::get<cv::GMatDesc>(out_v);
EXPECT_EQ(desc, out_desc);
}
TEST_F(S11N_Basic, Test_MetaArgs_MatDesc) {
cv::GMatDesc desc1 = { CV_8U, 1,{ 320,240 } };
cv::GMatDesc desc2 = { CV_8U, 1,{ 640,480 } };
GMetaArgs v;
v.resize(2);
v[0] = cv::GMetaArg{ desc1 };
v[1] = cv::GMetaArg{ desc2 };
put(v);
cv::GMetaArgs out_v = get<cv::GMetaArgs>();
cv::GMatDesc out_desc1 = cv::util::get<cv::GMatDesc>(out_v[0]);
cv::GMatDesc out_desc2 = cv::util::get<cv::GMatDesc>(out_v[1]);
EXPECT_EQ(desc1, out_desc1);
EXPECT_EQ(desc2, out_desc2);
}
TEST_F(S11N_Basic, Test_MetaArg_Monostate) {
GMetaArg v;
put(v);
cv::GMetaArg out_v = get<cv::GMetaArg>();
if (!util::holds_alternative<util::monostate>(out_v))
{
GTEST_FAIL();
}
}
TEST_F(S11N_Basic, Test_RunArg_Mat) {
cv::Mat mat = cv::Mat::eye(cv::Size(64, 64), CV_8UC3);
auto v = cv::GRunArg{ mat };
put(v);
cv::GRunArg out_v = get<cv::GRunArg>();
cv::Mat out_mat = cv::util::get<cv::Mat>(out_v);
EXPECT_EQ(0, cv::norm(mat, out_mat, cv::NORM_INF));
}
TEST_F(S11N_Basic, Test_RunArgs_Mat) {
cv::Mat mat1 = cv::Mat::eye(cv::Size(64, 64), CV_8UC3);
cv::Mat mat2 = cv::Mat::eye(cv::Size(128, 128), CV_8UC3);
GRunArgs v;
v.resize(2);
v[0] = cv::GRunArg{ mat1 };
v[1] = cv::GRunArg{ mat2 };
put(v);
cv::GRunArgs out_v = get<cv::GRunArgs>();
cv::Mat out_mat1 = cv::util::get<cv::Mat>(out_v[0]);
cv::Mat out_mat2 = cv::util::get<cv::Mat>(out_v[1]);
EXPECT_EQ(0, cv::norm(mat1, out_mat1, cv::NORM_INF));
EXPECT_EQ(0, cv::norm(mat2, out_mat2, cv::NORM_INF));
}
TEST_F(S11N_Basic, Test_RunArg_Scalar) {
cv::Scalar scalar = cv::Scalar(128, 33, 53);
auto v = cv::GRunArg{ scalar };
put(v);
cv::GRunArg out_v = get<cv::GRunArg>();
cv::Scalar out_scalar = cv::util::get<cv::Scalar>(out_v);
EXPECT_EQ(scalar, out_scalar);
}
TEST_F(S11N_Basic, Test_RunArgs_Scalar) {
cv::Scalar scalar1 = cv::Scalar(128, 33, 53);
cv::Scalar scalar2 = cv::Scalar(64, 15, 23);
GRunArgs v;
v.resize(2);
v[0] = cv::GRunArg{ scalar1 };
v[1] = cv::GRunArg{ scalar2 };
put(v);
cv::GRunArgs out_v = get<cv::GRunArgs>();
cv::Scalar out_scalar1 = cv::util::get<cv::Scalar>(out_v[0]);
cv::Scalar out_scalar2 = cv::util::get<cv::Scalar>(out_v[1]);
EXPECT_EQ(scalar1, out_scalar1);
EXPECT_EQ(scalar2, out_scalar2);
}
TEST_F(S11N_Basic, Test_RunArg_Opaque) {
auto op = cv::detail::OpaqueRef(42);
auto v = cv::GRunArg{ op };
put(v);
cv::GRunArg out_v = get<cv::GRunArg>();
cv::detail::OpaqueRef out_op = cv::util::get<cv::detail::OpaqueRef>(out_v);
EXPECT_TRUE(operator==<int>(op, out_op));
}
TEST_F(S11N_Basic, Test_RunArgs_Opaque) {
cv::detail::OpaqueRef op1 = cv::detail::OpaqueRef(cv::Point(1, 2));
cv::detail::OpaqueRef op2 = cv::detail::OpaqueRef(cv::Size(12, 21));
GRunArgs v;
v.resize(2);
v[0] = cv::GRunArg{ op1 };
v[1] = cv::GRunArg{ op2 };
put(v);
cv::GRunArgs out_v = get<cv::GRunArgs>();
cv::detail::OpaqueRef out_op1 = cv::util::get<cv::detail::OpaqueRef>(out_v[0]);
cv::detail::OpaqueRef out_op2 = cv::util::get<cv::detail::OpaqueRef>(out_v[1]);
EXPECT_TRUE(operator==<cv::Point>(op1, out_op1));
EXPECT_TRUE(operator==<cv::Size>(op2, out_op2));
}
TEST_F(S11N_Basic, Test_RunArg_Array) {
auto op = cv::detail::VectorRef(std::vector<cv::Mat>{cv::Mat::eye(3, 3, CV_8UC1), cv::Mat::zeros(5, 5, CV_8UC3)});
auto v = cv::GRunArg{ op };
put(v);
cv::GRunArg out_v = get<cv::GRunArg>();
cv::detail::VectorRef out_op = cv::util::get<cv::detail::VectorRef>(out_v);
auto vec1 = op.rref<cv::Mat>();
auto vec2 = out_op.rref<cv::Mat>();
EXPECT_EQ(0, cv::norm(vec1[0], vec2[0], cv::NORM_INF));
EXPECT_EQ(0, cv::norm(vec1[1], vec2[1], cv::NORM_INF));
}
TEST_F(S11N_Basic, Test_RunArgs_Array) {
auto vec_sc = std::vector<cv::Scalar>{cv::Scalar(11), cv::Scalar(31)};
auto vec_d = std::vector<double>{0.4, 1.0, 123.55, 22.08};
cv::detail::VectorRef op1 = cv::detail::VectorRef(vec_sc);
cv::detail::VectorRef op2 = cv::detail::VectorRef(vec_d);
GRunArgs v;
v.resize(2);
v[0] = cv::GRunArg{ op1 };
v[1] = cv::GRunArg{ op2 };
put(v);
cv::GRunArgs out_v = get<cv::GRunArgs>();
cv::detail::VectorRef out_op1 = cv::util::get<cv::detail::VectorRef>(out_v[0]);
cv::detail::VectorRef out_op2 = cv::util::get<cv::detail::VectorRef>(out_v[1]);
EXPECT_TRUE(operator==<cv::Scalar>(op1, out_op1));
EXPECT_TRUE(operator==<double>(op2, out_op2));
}
TEST_F(S11N_Basic, Test_RunArgs_MatScalar) {
cv::Mat mat = cv::Mat::eye(cv::Size(64, 64), CV_8UC3);
cv::Scalar scalar = cv::Scalar(128, 33, 53);
GRunArgs v;
v.resize(2);
v[0] = cv::GRunArg{ mat };
v[1] = cv::GRunArg{ scalar };
put(v);
cv::GRunArgs out_v = get<cv::GRunArgs>();
unsigned int i = 0;
for (auto it : out_v)
{
using T = cv::GRunArg;
switch (it.index())
{
case T::index_of<cv::Mat>() :
{
cv::Mat out_mat = cv::util::get<cv::Mat>(out_v[i]);
EXPECT_EQ(0, cv::norm(mat, out_mat, cv::NORM_INF));
} break;
case T::index_of<cv::Scalar>() :
{
cv::Scalar out_scalar = cv::util::get<cv::Scalar>(out_v[i]);
EXPECT_EQ(scalar, out_scalar);
} break;
default:
GAPI_Assert(false && "This value type is not supported!"); // ...maybe because of STANDALONE mode.
break;
}
i++;
}
}
TEST_F(S11N_Basic, Test_Bind_RunArgs_MatScalar) {
cv::Mat mat = cv::Mat::eye(cv::Size(128, 64), CV_8UC3);
cv::Scalar scalar = cv::Scalar(128, 33, 53);
GRunArgs v;
v.resize(2);
v[0] = cv::GRunArg{ mat };
v[1] = cv::GRunArg{ scalar };
GRunArgsP output = cv::gapi::bind(v);
unsigned int i = 0;
for (auto it : output)
{
using T = cv::GRunArgP;
switch (it.index())
{
case T::index_of<cv::Mat*>() :
{
cv::Mat* out_mat = cv::util::get<cv::Mat*>(it);
EXPECT_EQ(mat.size(), out_mat->size());
} break;
case T::index_of<cv::Scalar*>() :
{
cv::Scalar* out_scalar = cv::util::get<cv::Scalar*>(it);
EXPECT_EQ(out_scalar->val[0], scalar.val[0]);
EXPECT_EQ(out_scalar->val[1], scalar.val[1]);
EXPECT_EQ(out_scalar->val[2], scalar.val[2]);
} break;
default:
GAPI_Assert(false && "This value type is not supported!"); // ...maybe because of STANDALONE mode.
break;
}
i++;
}
}
TEST_F(S11N_Basic, Test_Vector_Of_Strings) {
std::vector<std::string> vs{"hello", "world", "42"};
const std::vector<char> ser = cv::gapi::serialize(vs);
auto des = cv::gapi::deserialize<std::vector<std::string>>(ser);
EXPECT_EQ("hello", des[0]);
EXPECT_EQ("world", des[1]);
EXPECT_EQ("42", des[2]);
}
TEST_F(S11N_Basic, Test_RunArg) {
cv::Mat mat = cv::Mat::eye(cv::Size(128, 64), CV_8UC3);
auto v = cv::GRunArgs{ cv::GRunArg{ mat } };
const std::vector<char> sargsin = cv::gapi::serialize(v);
cv::GRunArgs out = cv::gapi::deserialize<cv::GRunArgs>(sargsin);
cv::Mat out_mat = cv::util::get<cv::Mat>(out[0]);
EXPECT_EQ(0, cv::norm(mat, out_mat));
}
TEST_F(S11N_Basic, Test_RunArg_RMat) {
cv::Mat mat = cv::Mat::eye(cv::Size(128, 64), CV_8UC3);
cv::RMat rmat = cv::make_rmat<MyRMatAdapter>(mat, 42, "It actually works");
auto v = cv::GRunArgs{ cv::GRunArg{ rmat } };
const std::vector<char> sargsin = cv::gapi::serialize(v);
cv::GRunArgs out = cv::gapi::deserialize<cv::GRunArgs, MyRMatAdapter>(sargsin);
cv::RMat out_mat = cv::util::get<cv::RMat>(out[0]);
auto adapter = out_mat.get<MyRMatAdapter>();
EXPECT_EQ(42, adapter->getVal());
EXPECT_EQ("It actually works", adapter->getStr());
}
TEST_F(S11N_Basic, Test_RunArg_RMat_Scalar_Mat) {
cv::Mat mat = cv::Mat::eye(cv::Size(128, 64), CV_8UC3);
cv::RMat rmat = cv::make_rmat<MyRMatAdapter>(mat, 42, "It actually works");
cv::Scalar sc(111);
auto v = cv::GRunArgs{ cv::GRunArg{ rmat }, cv::GRunArg{ sc }, cv::GRunArg{ mat } };
const std::vector<char> sargsin = cv::gapi::serialize(v);
cv::GRunArgs out = cv::gapi::deserialize<cv::GRunArgs, MyRMatAdapter>(sargsin);
cv::RMat out_rmat = cv::util::get<cv::RMat>(out[0]);
auto adapter = out_rmat.get<MyRMatAdapter>();
EXPECT_EQ(42, adapter->getVal());
EXPECT_EQ("It actually works", adapter->getStr());
cv::Scalar out_sc = cv::util::get<cv::Scalar>(out[1]);
EXPECT_EQ(sc, out_sc);
cv::Mat out_mat = cv::util::get<cv::Mat>(out[2]);
EXPECT_EQ(0, cv::norm(mat, out_mat));
}
TEST_F(S11N_Basic, Test_RunArg_MediaFrame) {
cv::Mat mat = cv::Mat::eye(cv::Size(128, 64), CV_8UC3);
auto frame = cv::MediaFrame::Create<MyMediaFrameAdapter>(mat, 42, "It actually works");
auto v = cv::GRunArgs{ cv::GRunArg{ frame } };
const std::vector<char> sargsin = cv::gapi::serialize(v);
cv::GRunArgs out = cv::gapi::deserialize<cv::GRunArgs, MyMediaFrameAdapter>(sargsin);
cv::MediaFrame out_mat = cv::util::get<cv::MediaFrame>(out[0]);
auto adapter = out_mat.get<MyMediaFrameAdapter>();
EXPECT_EQ(42, adapter->getVal());
EXPECT_EQ("It actually works", adapter->getStr());
}
TEST_F(S11N_Basic, Test_RunArg_MediaFrame_Scalar_Mat) {
cv::Mat mat = cv::Mat::eye(cv::Size(128, 64), CV_8UC3);
auto frame = cv::MediaFrame::Create<MyMediaFrameAdapter>(mat, 42, "It actually works");
cv::Scalar sc(111);
auto v = cv::GRunArgs{ cv::GRunArg{ frame }, cv::GRunArg{ sc }, cv::GRunArg{ mat } };
const std::vector<char> sargsin = cv::gapi::serialize(v);
cv::GRunArgs out = cv::gapi::deserialize<cv::GRunArgs, MyMediaFrameAdapter>(sargsin);
cv::MediaFrame out_frame = cv::util::get<cv::MediaFrame>(out[0]);
auto adapter = out_frame.get<MyMediaFrameAdapter>();
EXPECT_EQ(42, adapter->getVal());
EXPECT_EQ("It actually works", adapter->getStr());
cv::Scalar out_sc = cv::util::get<cv::Scalar>(out[1]);
EXPECT_EQ(sc, out_sc);
cv::Mat out_mat = cv::util::get<cv::Mat>(out[2]);
EXPECT_EQ(0, cv::norm(mat, out_mat));
}
TEST_F(S11N_Basic, Test_RunArg_MediaFrame_RMat) {
cv::Mat mat = cv::Mat::eye(cv::Size(128, 64), CV_8UC3);
cv::Mat mat2 = cv::Mat::eye(cv::Size(128, 64), CV_8UC3);
auto frame = cv::MediaFrame::Create<MyMediaFrameAdapter>(mat, 42, "It actually works");
auto rmat = cv::make_rmat<MyRMatAdapter>(mat2, 24, "Hello there");
auto v = cv::GRunArgs{ cv::GRunArg{ frame }, cv::GRunArg{ rmat } };
const std::vector<char> sargsin = cv::gapi::serialize(v);
cv::GRunArgs out = cv::gapi::deserialize<cv::GRunArgs, MyMediaFrameAdapter, MyRMatAdapter>(sargsin);
cv::MediaFrame out_frame = cv::util::get<cv::MediaFrame>(out[0]);
cv::RMat out_rmat = cv::util::get<cv::RMat>(out[1]);
auto adapter = out_frame.get<MyMediaFrameAdapter>();
EXPECT_EQ(42, adapter->getVal());
EXPECT_EQ("It actually works", adapter->getStr());
auto adapter2 = out_rmat.get<MyRMatAdapter>();
EXPECT_EQ(24, adapter2->getVal());
EXPECT_EQ("Hello there", adapter2->getStr());
}
TEST_F(S11N_Basic, Test_RunArg_RMat_MediaFrame) {
cv::Mat mat = cv::Mat::eye(cv::Size(128, 64), CV_8UC3);
cv::Mat mat2 = cv::Mat::eye(cv::Size(128, 64), CV_8UC3);
auto frame = cv::MediaFrame::Create<MyMediaFrameAdapter>(mat, 42, "It actually works");
auto rmat = cv::make_rmat<MyRMatAdapter>(mat2, 24, "Hello there");
auto v = cv::GRunArgs{ cv::GRunArg{ rmat }, cv::GRunArg{ frame } };
const std::vector<char> sargsin = cv::gapi::serialize(v);
cv::GRunArgs out = cv::gapi::deserialize<cv::GRunArgs, MyMediaFrameAdapter, MyRMatAdapter>(sargsin);
cv::RMat out_rmat = cv::util::get<cv::RMat>(out[0]);
cv::MediaFrame out_frame = cv::util::get<cv::MediaFrame>(out[1]);
auto adapter = out_frame.get<MyMediaFrameAdapter>();
EXPECT_EQ(42, adapter->getVal());
EXPECT_EQ("It actually works", adapter->getStr());
auto adapter2 = out_rmat.get<MyRMatAdapter>();
EXPECT_EQ(24, adapter2->getVal());
EXPECT_EQ("Hello there", adapter2->getStr());
}
namespace {
template <cv::detail::OpaqueKind K, typename T>
bool verifyOpaqueKind(T&& in) {
auto inObjs = cv::gin(in);
auto in_o_ref = cv::util::get<cv::detail::OpaqueRef>(inObjs[0]);
return K == in_o_ref.getKind();
}
template <cv::detail::OpaqueKind K, typename T>
bool verifyArrayKind(T&& in) {
auto inObjs = cv::gin(in);
auto in_o_ref = cv::util::get<cv::detail::VectorRef>(inObjs[0]);
return K == in_o_ref.getKind();
}
}
TEST_F(S11N_Basic, Test_Gin_GOpaque) {
int i; float f; double d;
std::uint64_t ui; bool b;
std::string s;
cv::Rect r; cv::Size sz;
cv::Point p;
EXPECT_TRUE(verifyOpaqueKind<cv::detail::OpaqueKind::CV_INT>(i));
EXPECT_TRUE(verifyOpaqueKind<cv::detail::OpaqueKind::CV_FLOAT>(f));
EXPECT_TRUE(verifyOpaqueKind<cv::detail::OpaqueKind::CV_DOUBLE>(d));
EXPECT_TRUE(verifyOpaqueKind<cv::detail::OpaqueKind::CV_UINT64>(ui));
EXPECT_TRUE(verifyOpaqueKind<cv::detail::OpaqueKind::CV_BOOL>(b));
EXPECT_TRUE(verifyOpaqueKind<cv::detail::OpaqueKind::CV_STRING>(s));
EXPECT_TRUE(verifyOpaqueKind<cv::detail::OpaqueKind::CV_RECT>(r));
EXPECT_TRUE(verifyOpaqueKind<cv::detail::OpaqueKind::CV_SIZE>(sz));
EXPECT_TRUE(verifyOpaqueKind<cv::detail::OpaqueKind::CV_POINT>(p));
}
TEST_F(S11N_Basic, Test_Gin_GArray) {
std::vector<int> i; std::vector<float> f; std::vector<double> d;
std::vector<std::uint64_t> ui; std::vector<bool> b;
std::vector<std::string> s;
std::vector<cv::Rect> r; std::vector<cv::Size> sz;
std::vector<cv::Point> p;
std::vector<cv::Mat> mat;
std::vector<cv::Scalar> sc;
EXPECT_TRUE(verifyArrayKind<cv::detail::OpaqueKind::CV_INT>(i));
EXPECT_TRUE(verifyArrayKind<cv::detail::OpaqueKind::CV_FLOAT>(f));
EXPECT_TRUE(verifyArrayKind<cv::detail::OpaqueKind::CV_DOUBLE>(d));
EXPECT_TRUE(verifyArrayKind<cv::detail::OpaqueKind::CV_UINT64>(ui));
EXPECT_TRUE(verifyArrayKind<cv::detail::OpaqueKind::CV_BOOL>(b));
EXPECT_TRUE(verifyArrayKind<cv::detail::OpaqueKind::CV_STRING>(s));
EXPECT_TRUE(verifyArrayKind<cv::detail::OpaqueKind::CV_RECT>(r));
EXPECT_TRUE(verifyArrayKind<cv::detail::OpaqueKind::CV_SIZE>(sz));
EXPECT_TRUE(verifyArrayKind<cv::detail::OpaqueKind::CV_POINT>(p));
EXPECT_TRUE(verifyArrayKind<cv::detail::OpaqueKind::CV_MAT>(mat));
EXPECT_TRUE(verifyArrayKind<cv::detail::OpaqueKind::CV_SCALAR>(sc));
}
TEST_F(S11N_Basic, Test_Custom_Type) {
MyCustomType var{1324, "Hello", {1920, 1080, 720}, {{1, 2937459432}, {42, 253245432}}};
cv::gapi::s11n::ByteMemoryOutStream os;
cv::gapi::s11n::detail::S11N<MyCustomType>::serialize(os, var);
cv::gapi::s11n::ByteMemoryInStream is(os.data());
MyCustomType new_var = cv::gapi::s11n::detail::S11N<MyCustomType>::deserialize(is);
EXPECT_EQ(var, new_var);
}
TEST_F(S11N_Basic, Test_CompileArg) {
MyCustomType customVar{1248, "World", {1280, 720, 640, 480}, {{5, 32434142342}, {7, 34242432}}};
std::vector<char> sArgs = cv::gapi::serialize(cv::compile_args(customVar));
GCompileArgs dArgs = cv::gapi::deserialize<GCompileArgs, MyCustomType>(sArgs);
MyCustomType dCustomVar = cv::gapi::getCompileArg<MyCustomType>(dArgs).value();
EXPECT_EQ(customVar, dCustomVar);
}
TEST_F(S11N_Basic, Test_CompileArg_Without_UserCallback) {
SimpleCustomType customVar1 { false };
MyCustomTypeNoS11N customVar2 { 'z', 189, "Name" };
MyCustomType customVar3 { 1248, "World", {1280, 720, 640, 480},
{{5, 32434142342}, {7, 34242432}} };
EXPECT_NO_THROW(cv::gapi::serialize(cv::compile_args(customVar1, customVar2, customVar3)));
std::vector<char> sArgs = cv::gapi::serialize(
cv::compile_args(customVar1, customVar2, customVar3));
GCompileArgs dArgs = cv::gapi::deserialize<GCompileArgs,
SimpleCustomType,
MyCustomType>(sArgs);
SimpleCustomType dCustomVar1 = cv::gapi::getCompileArg<SimpleCustomType>(dArgs).value();
MyCustomType dCustomVar3 = cv::gapi::getCompileArg<MyCustomType>(dArgs).value();
EXPECT_EQ(customVar1, dCustomVar1);
EXPECT_EQ(customVar3, dCustomVar3);
}
TEST_F(S11N_Basic, Test_Deserialize_Only_Requested_CompileArgs) {
MyCustomType myCustomVar { 1248, "World", {1280, 720, 640, 480},
{{5, 32434142342}, {7, 34242432}} };
SimpleCustomType simpleCustomVar { false };
std::vector<char> sArgs = cv::gapi::serialize(cv::compile_args(myCustomVar, simpleCustomVar));
GCompileArgs dArgs = cv::gapi::deserialize<GCompileArgs, MyCustomType>(sArgs);
EXPECT_EQ(1u, dArgs.size());
EXPECT_EQ(myCustomVar, cv::gapi::getCompileArg<MyCustomType>(dArgs).value());
dArgs.clear();
dArgs = cv::gapi::deserialize<GCompileArgs, SimpleCustomType>(sArgs);
EXPECT_EQ(1u, dArgs.size());
EXPECT_EQ(simpleCustomVar, cv::gapi::getCompileArg<SimpleCustomType>(dArgs).value());
dArgs.clear();
dArgs = cv::gapi::deserialize<GCompileArgs, SimpleCustomType2>(sArgs);
EXPECT_EQ(0u, dArgs.size());
dArgs.clear();
dArgs = cv::gapi::deserialize<GCompileArgs, MyCustomType, SimpleCustomType>(sArgs);
EXPECT_EQ(2u, dArgs.size());
EXPECT_EQ(myCustomVar, cv::gapi::getCompileArg<MyCustomType>(dArgs).value());
EXPECT_EQ(simpleCustomVar, cv::gapi::getCompileArg<SimpleCustomType>(dArgs).value());
SimpleCustomType2 simpleCustomVar2 { 5 };
std::vector<char> sArgs2 = cv::gapi::serialize(
cv::compile_args(myCustomVar, simpleCustomVar, simpleCustomVar2));
GCompileArgs dArgs2 = cv::gapi::deserialize<GCompileArgs,
MyCustomType,
SimpleCustomType2>(sArgs2);
EXPECT_EQ(2u, dArgs2.size());
EXPECT_EQ(myCustomVar, cv::gapi::getCompileArg<MyCustomType>(dArgs2).value());
EXPECT_EQ(simpleCustomVar2, cv::gapi::getCompileArg<SimpleCustomType2>(dArgs2).value());
}
TEST_F(S11N_Basic, Test_Deserialize_CompileArgs_RandomOrder) {
SimpleCustomType simpleCustomVar { false };
SimpleCustomType2 simpleCustomVar2 { 5 };
std::vector<char> sArgs = cv::gapi::serialize(
cv::compile_args(simpleCustomVar, simpleCustomVar2));
GCompileArgs dArgs = cv::gapi::deserialize<GCompileArgs,
SimpleCustomType2,
SimpleCustomType>(sArgs);
EXPECT_EQ(simpleCustomVar, cv::gapi::getCompileArg<SimpleCustomType>(dArgs).value());
EXPECT_EQ(simpleCustomVar2, cv::gapi::getCompileArg<SimpleCustomType2>(dArgs).value());
}
TEST_F(S11N_Basic, Test_CompileArgs_With_EmptyCompileArg) {
MyCustomType myCustomVar { 1248, "World", {1280, 720, 640, 480},
{{5, 32434142342}, {7, 34242432}} };
SimpleCustomType simpleCustomVar { false };
EmptyCustomType emptyCustomVar { };
//----{ emptyCustomVar, myCustomVar }----
std::vector<char> sArgs1 = cv::gapi::serialize(cv::compile_args(emptyCustomVar, myCustomVar));
GCompileArgs dArgsEmptyVar1 = cv::gapi::deserialize<GCompileArgs, EmptyCustomType>(sArgs1);
GCompileArgs dArgsMyVar1 = cv::gapi::deserialize<GCompileArgs, MyCustomType>(sArgs1);
GCompileArgs dArgsEmptyAndMyVars1 = cv::gapi::deserialize<GCompileArgs,
EmptyCustomType,
MyCustomType>(sArgs1);
EXPECT_EQ(1u, dArgsEmptyVar1.size());
EXPECT_TRUE(cv::gapi::getCompileArg<EmptyCustomType>(dArgsEmptyVar1).has_value());
EXPECT_EQ(1u, dArgsMyVar1.size());
EXPECT_EQ(myCustomVar, cv::gapi::getCompileArg<MyCustomType>(dArgsMyVar1).value());
EXPECT_EQ(2u, dArgsEmptyAndMyVars1.size());
EXPECT_TRUE(cv::gapi::getCompileArg<EmptyCustomType>(dArgsEmptyAndMyVars1).has_value());
EXPECT_EQ(myCustomVar, cv::gapi::getCompileArg<MyCustomType>(dArgsEmptyAndMyVars1).value());
//----{ myCustomVar, emptyCustomVar }----
std::vector<char> sArgs2 = cv::gapi::serialize(cv::compile_args(myCustomVar, emptyCustomVar));
GCompileArgs dArgsMyVar2 = cv::gapi::deserialize<GCompileArgs, MyCustomType>(sArgs2);
GCompileArgs dArgsEmptyVar2 = cv::gapi::deserialize<GCompileArgs, EmptyCustomType>(sArgs2);
GCompileArgs dArgsMyAndEmptyVars2 = cv::gapi::deserialize<GCompileArgs,
MyCustomType,
EmptyCustomType>(sArgs2);
EXPECT_EQ(1u, dArgsMyVar2.size());
EXPECT_EQ(myCustomVar, cv::gapi::getCompileArg<MyCustomType>(dArgsMyVar2).value());
EXPECT_EQ(1u, dArgsEmptyVar2.size());
EXPECT_TRUE(cv::gapi::getCompileArg<EmptyCustomType>(dArgsEmptyVar2).has_value());
EXPECT_EQ(2u, dArgsMyAndEmptyVars2.size());
EXPECT_EQ(myCustomVar, cv::gapi::getCompileArg<MyCustomType>(dArgsMyAndEmptyVars2).value());
EXPECT_TRUE(cv::gapi::getCompileArg<EmptyCustomType>(dArgsMyAndEmptyVars2).has_value());
//----{ myCustomVar, emptyCustomVar, simpleCustomVar }----
std::vector<char> sArgs3 = cv::gapi::serialize(
cv::compile_args(myCustomVar, emptyCustomVar, simpleCustomVar));
GCompileArgs dArgsMyVar3 = cv::gapi::deserialize<GCompileArgs, MyCustomType>(sArgs3);
GCompileArgs dArgsEmptyVar3 = cv::gapi::deserialize<GCompileArgs, EmptyCustomType>(sArgs3);
GCompileArgs dArgsSimpleVar3 = cv::gapi::deserialize<GCompileArgs, SimpleCustomType>(sArgs3);
GCompileArgs dArgsMyAndSimpleVars3 = cv::gapi::deserialize<GCompileArgs,
MyCustomType,
SimpleCustomType>(sArgs3);
GCompileArgs dArgs3 = cv::gapi::deserialize<GCompileArgs,
MyCustomType,
EmptyCustomType,
SimpleCustomType>(sArgs3);
EXPECT_EQ(1u, dArgsMyVar3.size());
EXPECT_EQ(myCustomVar, cv::gapi::getCompileArg<MyCustomType>(dArgsMyVar3).value());
EXPECT_EQ(1u, dArgsEmptyVar3.size());
EXPECT_TRUE(cv::gapi::getCompileArg<EmptyCustomType>(dArgsEmptyVar3).has_value());
EXPECT_EQ(1u, dArgsSimpleVar3.size());
EXPECT_EQ(simpleCustomVar, cv::gapi::getCompileArg<SimpleCustomType>(dArgsSimpleVar3).value());
EXPECT_EQ(2u, dArgsMyAndSimpleVars3.size());
EXPECT_EQ(myCustomVar, cv::gapi::getCompileArg<MyCustomType>(dArgsMyAndSimpleVars3).value());
EXPECT_EQ(simpleCustomVar,
cv::gapi::getCompileArg<SimpleCustomType>(dArgsMyAndSimpleVars3).value());
EXPECT_EQ(3u, dArgs3.size());
EXPECT_EQ(myCustomVar, cv::gapi::getCompileArg<MyCustomType>(dArgs3).value());
EXPECT_TRUE(cv::gapi::getCompileArg<EmptyCustomType>(dArgs3).has_value());
EXPECT_EQ(simpleCustomVar, cv::gapi::getCompileArg<SimpleCustomType>(dArgs3).value());
//----{ emptyCustomVar }----
std::vector<char> sArgs4 = cv::gapi::serialize(cv::compile_args(emptyCustomVar));
GCompileArgs dArgsEmptyVar4 = cv::gapi::deserialize<GCompileArgs, EmptyCustomType>(sArgs4);
EXPECT_EQ(1u, dArgsEmptyVar4.size());
EXPECT_TRUE(cv::gapi::getCompileArg<EmptyCustomType>(dArgsEmptyVar4).has_value());
}
} // namespace opencv_test

View File

@ -0,0 +1,838 @@
// 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
#include "../test_precomp.hpp"
#include <ade/util/iota_range.hpp>
#include <opencv2/gapi/s11n.hpp>
#include "api/render_priv.hpp"
#include "../common/gapi_render_tests.hpp"
namespace opencv_test
{
TEST(S11N, Pipeline_Crop_Rect)
{
cv::Rect rect_to{ 4,10,37,50 };
cv::Size sz_in = cv::Size(1920, 1080);
cv::Size sz_out = cv::Size(37, 50);
cv::Mat in_mat = cv::Mat::eye(sz_in, CV_8UC1);
cv::Mat out_mat_gapi(sz_out, CV_8UC1);
cv::Mat out_mat_ocv(sz_out, CV_8UC1);
// G-API code //////////////////////////////////////////////////////////////
cv::GMat in;
auto out = cv::gapi::crop(in, rect_to);
auto p = cv::gapi::serialize(cv::GComputation(in, out));
auto c = cv::gapi::deserialize<cv::GComputation>(p);
c.apply(in_mat, out_mat_gapi);
// OpenCV code /////////////////////////////////////////////////////////////
{
out_mat_ocv = in_mat(rect_to);
}
// Comparison //////////////////////////////////////////////////////////////
{
EXPECT_EQ(0, cvtest::norm(out_mat_ocv, out_mat_gapi, NORM_INF));
}
}
TEST(S11N, Pipeline_Canny_Bool)
{
const cv::Size sz_in(1280, 720);
cv::GMat in;
double thrLow = 120.0;
double thrUp = 240.0;
int apSize = 5;
bool l2gr = true;
cv::Mat in_mat = cv::Mat::eye(1280, 720, CV_8UC1);
cv::Mat out_mat_gapi(sz_in, CV_8UC1);
cv::Mat out_mat_ocv(sz_in, CV_8UC1);
// G-API code //////////////////////////////////////////////////////////////
auto out = cv::gapi::Canny(in, thrLow, thrUp, apSize, l2gr);
auto p = cv::gapi::serialize(cv::GComputation(in, out));
auto c = cv::gapi::deserialize<cv::GComputation>(p);
c.apply(in_mat, out_mat_gapi);
// OpenCV code /////////////////////////////////////////////////////////////
{
cv::Canny(in_mat, out_mat_ocv, thrLow, thrUp, apSize, l2gr);
}
// Comparison //////////////////////////////////////////////////////////////
EXPECT_EQ(0, cvtest::norm(out_mat_gapi, out_mat_ocv, NORM_INF));
}
TEST(S11N, Pipeline_Not)
{
cv::GMat in;
auto p = cv::gapi::serialize(cv::GComputation(in, cv::gapi::bitwise_not(in)));
auto c = cv::gapi::deserialize<cv::GComputation>(p);
cv::Mat in_mat = cv::Mat::eye(32, 32, CV_8UC1);
cv::Mat ref_mat = ~in_mat;
cv::Mat out_mat;
c.apply(in_mat, out_mat);
EXPECT_EQ(0, cvtest::norm(out_mat, ref_mat, NORM_INF));
out_mat = cv::Mat();
auto cc = c.compile(cv::descr_of(in_mat));
cc(in_mat, out_mat);
EXPECT_EQ(0, cvtest::norm(out_mat, ref_mat, NORM_INF));
}
TEST(S11N, Pipeline_Sum_Scalar)
{
cv::GMat in;
auto p = cv::gapi::serialize(cv::GComputation(in, cv::gapi::sum(in)));
auto c = cv::gapi::deserialize<cv::GComputation>(p);
cv::Mat in_mat = cv::Mat::eye(32, 32, CV_8UC1);
cv::Scalar ref_scl = cv::sum(in_mat);
cv::Scalar out_scl;
c.apply(in_mat, out_scl);
EXPECT_EQ(out_scl, ref_scl);
out_scl = cv::Scalar();
auto cc = c.compile(cv::descr_of(in_mat));
cc(in_mat, out_scl);
EXPECT_EQ(out_scl, ref_scl);
}
TEST(S11N, Pipeline_BinaryOp)
{
cv::GMat a, b;
auto p = cv::gapi::serialize(cv::GComputation(a, b, cv::gapi::add(a, b)));
auto c = cv::gapi::deserialize<cv::GComputation>(p);
cv::Mat in_mat = cv::Mat::eye(32, 32, CV_8UC1);
cv::Mat ref_mat = (in_mat + in_mat);
cv::Mat out_mat;
c.apply(in_mat, in_mat, out_mat);
EXPECT_EQ(0, cvtest::norm(out_mat, ref_mat, NORM_INF));
out_mat = cv::Mat();
auto cc = c.compile(cv::descr_of(in_mat), cv::descr_of(in_mat));
cc(in_mat, in_mat, out_mat);
EXPECT_EQ(0, cvtest::norm(out_mat, ref_mat, NORM_INF));
}
TEST(S11N, Pipeline_Binary_Sum_Scalar)
{
cv::GMat a, b;
auto p = cv::gapi::serialize(cv::GComputation(a, b, cv::gapi::sum(a + b)));
auto c = cv::gapi::deserialize<cv::GComputation>(p);
cv::Mat in_mat = cv::Mat::eye(32, 32, CV_8UC1);
cv::Scalar ref_scl = cv::sum(in_mat + in_mat);
cv::Scalar out_scl;
c.apply(in_mat, in_mat, out_scl);
EXPECT_EQ(out_scl, ref_scl);
out_scl = cv::Scalar();
auto cc = c.compile(cv::descr_of(in_mat), cv::descr_of(in_mat));
cc(in_mat, in_mat, out_scl);
EXPECT_EQ(out_scl, ref_scl);
}
TEST(S11N, Pipeline_Sharpen)
{
const cv::Size sz_in (1280, 720);
const cv::Size sz_out( 640, 480);
cv::Mat in_mat (sz_in, CV_8UC3);
in_mat = cv::Scalar(128, 33, 53);
cv::Mat out_mat(sz_out, CV_8UC3);
cv::Mat out_mat_y;
cv::Mat out_mat_ocv(sz_out, CV_8UC3);
float sharpen_coeffs[] = {
0.0f, -1.f, 0.0f,
-1.0f, 5.f, -1.0f,
0.0f, -1.f, 0.0f
};
cv::Mat sharpen_kernel(3, 3, CV_32F, sharpen_coeffs);
// G-API code //////////////////////////////////////////////////////////////
cv::GMat in;
auto vga = cv::gapi::resize(in, sz_out);
auto yuv = cv::gapi::RGB2YUV(vga);
auto yuv_p = cv::gapi::split3(yuv);
auto y_sharp = cv::gapi::filter2D(std::get<0>(yuv_p), -1, sharpen_kernel);
auto yuv_new = cv::gapi::merge3(y_sharp, std::get<1>(yuv_p), std::get<2>(yuv_p));
auto out = cv::gapi::YUV2RGB(yuv_new);
auto p = cv::gapi::serialize(cv::GComputation(cv::GIn(in), cv::GOut(y_sharp, out)));
auto c = cv::gapi::deserialize<cv::GComputation>(p);
c.apply(cv::gin(in_mat), cv::gout(out_mat_y, out_mat));
// OpenCV code /////////////////////////////////////////////////////////////
{
cv::Mat smaller;
cv::resize(in_mat, smaller, sz_out);
cv::Mat yuv_mat;
cv::cvtColor(smaller, yuv_mat, cv::COLOR_RGB2YUV);
std::vector<cv::Mat> yuv_planar(3);
cv::split(yuv_mat, yuv_planar);
cv::filter2D(yuv_planar[0], yuv_planar[0], -1, sharpen_kernel);
cv::merge(yuv_planar, yuv_mat);
cv::cvtColor(yuv_mat, out_mat_ocv, cv::COLOR_YUV2RGB);
}
// Comparison //////////////////////////////////////////////////////////////
{
cv::Mat diff = out_mat_ocv != out_mat;
std::vector<cv::Mat> diffBGR(3);
cv::split(diff, diffBGR);
EXPECT_EQ(0, cvtest::norm(diffBGR[0], NORM_INF));
EXPECT_EQ(0, cvtest::norm(diffBGR[1], NORM_INF));
EXPECT_EQ(0, cvtest::norm(diffBGR[2], NORM_INF));
}
// Metadata check /////////////////////////////////////////////////////////
{
auto cc = c.compile(cv::descr_of(in_mat));
auto metas = cc.outMetas();
ASSERT_EQ(2u, metas.size());
auto out_y_meta = cv::util::get<cv::GMatDesc>(metas[0]);
auto out_meta = cv::util::get<cv::GMatDesc>(metas[1]);
// Y-output
EXPECT_EQ(CV_8U, out_y_meta.depth);
EXPECT_EQ(1, out_y_meta.chan);
EXPECT_EQ(640, out_y_meta.size.width);
EXPECT_EQ(480, out_y_meta.size.height);
// Final output
EXPECT_EQ(CV_8U, out_meta.depth);
EXPECT_EQ(3, out_meta.chan);
EXPECT_EQ(640, out_meta.size.width);
EXPECT_EQ(480, out_meta.size.height);
}
}
TEST(S11N, Pipeline_CustomRGB2YUV)
{
const cv::Size sz(1280, 720);
const int INS = 3;
std::vector<cv::Mat> in_mats(INS);
for (auto i : ade::util::iota(INS))
{
in_mats[i].create(sz, CV_8U);
cv::randu(in_mats[i], cv::Scalar::all(0), cv::Scalar::all(255));
}
const int OUTS = 3;
std::vector<cv::Mat> out_mats_cv(OUTS);
std::vector<cv::Mat> out_mats_gapi(OUTS);
for (auto i : ade::util::iota(OUTS))
{
out_mats_cv[i].create(sz, CV_8U);
out_mats_gapi[i].create(sz, CV_8U);
}
// G-API code //////////////////////////////////////////////////////////////
{
cv::GMat r, g, b;
cv::GMat y = 0.299f*r + 0.587f*g + 0.114f*b;
cv::GMat u = 0.492f*(b - y);
cv::GMat v = 0.877f*(r - y);
auto p = cv::gapi::serialize(cv::GComputation({r, g, b}, {y, u, v}));
auto c = cv::gapi::deserialize<cv::GComputation>(p);
c.apply(in_mats, out_mats_gapi);
}
// OpenCV code /////////////////////////////////////////////////////////////
{
cv::Mat r = in_mats[0], g = in_mats[1], b = in_mats[2];
cv::Mat y = 0.299f*r + 0.587f*g + 0.114f*b;
cv::Mat u = 0.492f*(b - y);
cv::Mat v = 0.877f*(r - y);
out_mats_cv[0] = y;
out_mats_cv[1] = u;
out_mats_cv[2] = v;
}
// Comparison //////////////////////////////////////////////////////////////
{
const auto diff = [](cv::Mat m1, cv::Mat m2, int t) {
return cv::abs(m1 - m2) > t;
};
// FIXME: Not bit-accurate even now!
cv::Mat
diff_y = diff(out_mats_cv[0], out_mats_gapi[0], 2),
diff_u = diff(out_mats_cv[1], out_mats_gapi[1], 2),
diff_v = diff(out_mats_cv[2], out_mats_gapi[2], 2);
EXPECT_EQ(0, cvtest::norm(diff_y, NORM_INF));
EXPECT_EQ(0, cvtest::norm(diff_u, NORM_INF));
EXPECT_EQ(0, cvtest::norm(diff_v, NORM_INF));
}
}
namespace ThisTest
{
using GOpBool = GOpaque<bool>;
using GOpInt = GOpaque<int>;
using GOpDouble = GOpaque<double>;
using GOpPoint = GOpaque<cv::Point>;
using GOpSize = GOpaque<cv::Size>;
using GOpRect = GOpaque<cv::Rect>;
using GOpOut = std::tuple<GOpPoint, GOpSize, GOpRect>;
G_TYPED_KERNEL_M(OpGenerate, <GOpOut(GOpBool, GOpInt, GOpDouble)>, "test.s11n.gopaque")
{
static std::tuple<GOpaqueDesc, GOpaqueDesc, GOpaqueDesc> outMeta(const GOpaqueDesc&, const GOpaqueDesc&, const GOpaqueDesc&) {
return std::make_tuple(empty_gopaque_desc(), empty_gopaque_desc(), empty_gopaque_desc());
}
};
GAPI_OCV_KERNEL(OCVOpGenerate, OpGenerate)
{
static void run(const bool& b, const int& i, const double& d,
cv::Point& p, cv::Size& s, cv::Rect& r)
{
p = cv::Point(i, i*2);
s = b ? cv::Size(42, 42) : cv::Size(7, 7);
int ii = static_cast<int>(d);
r = cv::Rect(ii, ii, ii, ii);
}
};
using GArrInt = GArray<int>;
using GArrDouble = GArray<double>;
using GArrPoint = GArray<cv::Point>;
using GArrSize = GArray<cv::Size>;
using GArrRect = GArray<cv::Rect>;
using GArrMat = GArray<cv::Mat>;
using GArrScalar = GArray<cv::Scalar>;
using GArrOut = std::tuple<GArrPoint, GArrSize, GArrRect, GArrMat>;
G_TYPED_KERNEL_M(ArrGenerate, <GArrOut(GArrInt, GArrInt, GArrDouble, GArrScalar)>, "test.s11n.garray")
{
static std::tuple<GArrayDesc, GArrayDesc, GArrayDesc, GArrayDesc> outMeta(const GArrayDesc&, const GArrayDesc&,
const GArrayDesc&, const GArrayDesc&) {
return std::make_tuple(empty_array_desc(), empty_array_desc(), empty_array_desc(), empty_array_desc());
}
};
GAPI_OCV_KERNEL(OCVArrGenerate, ArrGenerate)
{
static void run(const std::vector<int>& b, const std::vector<int>& i,
const std::vector<double>& d, const std::vector<cv::Scalar>& sc,
std::vector<cv::Point>& p, std::vector<cv::Size>& s,
std::vector<cv::Rect>& r, std::vector<cv::Mat>& m)
{
p.clear(); p.resize(b.size());
s.clear(); s.resize(b.size());
r.clear(); r.resize(b.size());
m.clear(); m.resize(b.size());
for (std::size_t idx = 0; idx < b.size(); ++idx)
{
p[idx] = cv::Point(i[idx], i[idx]*2);
s[idx] = b[idx] == 1 ? cv::Size(42, 42) : cv::Size(7, 7);
int ii = static_cast<int>(d[idx]);
r[idx] = cv::Rect(ii, ii, ii, ii);
m[idx] = cv::Mat(3, 3, CV_8UC1, sc[idx]);
}
}
};
G_TYPED_KERNEL_M(OpArrK1, <std::tuple<GArrInt,GOpSize>(GOpInt, GArrSize)>, "test.s11n.oparrk1")
{
static std::tuple<GArrayDesc, GOpaqueDesc> outMeta(const GOpaqueDesc&, const GArrayDesc&) {
return std::make_tuple(empty_array_desc(), empty_gopaque_desc());
}
};
GAPI_OCV_KERNEL(OCVOpArrK1, OpArrK1)
{
static void run(const int& i, const std::vector<cv::Size>& vs,
std::vector<int>& vi, cv::Size& s)
{
vi.clear(); vi.resize(vs.size());
s = cv::Size(i, i);
for (std::size_t idx = 0; idx < vs.size(); ++ idx)
vi[idx] = vs[idx].area();
}
};
G_TYPED_KERNEL_M(OpArrK2, <std::tuple<GOpDouble,GArrPoint>(GArrInt, GOpSize)>, "test.s11n.oparrk2")
{
static std::tuple<GOpaqueDesc, GArrayDesc> outMeta(const GArrayDesc&, const GOpaqueDesc&) {
return std::make_tuple(empty_gopaque_desc(), empty_array_desc());
}
};
GAPI_OCV_KERNEL(OCVOpArrK2, OpArrK2)
{
static void run(const std::vector<int>& vi, const cv::Size& s,
double& d, std::vector<cv::Point>& vp)
{
vp.clear(); vp.resize(vi.size());
d = s.area() * 1.5;
for (std::size_t idx = 0; idx < vi.size(); ++ idx)
vp[idx] = cv::Point(vi[idx], vi[idx]);
}
};
using GK3Out = std::tuple<cv::GArray<uint64_t>, cv::GArray<int32_t>>;
G_TYPED_KERNEL_M(OpArrK3, <GK3Out(cv::GArray<bool>, cv::GArray<int32_t>, cv::GOpaque<float>)>, "test.s11n.oparrk3")
{
static std::tuple<GArrayDesc, GArrayDesc> outMeta(const GArrayDesc&, const GArrayDesc&, const GOpaqueDesc&) {
return std::make_tuple(empty_array_desc(), empty_array_desc());
}
};
GAPI_OCV_KERNEL(OCVOpArrK3, OpArrK3)
{
static void run(const std::vector<bool>& vb, const std::vector<int32_t>& vi_in, const float& f,
std::vector<uint64_t>& vui, std::vector<int32_t>& vi)
{
vui.clear(); vui.resize(vi_in.size());
vi.clear(); vi.resize(vi_in.size());
for (std::size_t idx = 0; idx < vi_in.size(); ++ idx)
{
vi[idx] = vb[idx] ? vi_in[idx] : -vi_in[idx];
vui[idx] = vb[idx] ? static_cast<uint64_t>(vi_in[idx] * f) :
static_cast<uint64_t>(vi_in[idx] / f);
}
}
};
using GK4Out = std::tuple<cv::GOpaque<int>, cv::GArray<std::string>>;
G_TYPED_KERNEL_M(OpArrK4, <GK4Out(cv::GOpaque<bool>, cv::GOpaque<std::string>)>, "test.s11n.oparrk4")
{
static std::tuple<GOpaqueDesc, GArrayDesc> outMeta(const GOpaqueDesc&, const GOpaqueDesc&) {
return std::make_tuple(empty_gopaque_desc(), empty_array_desc());
}
};
GAPI_OCV_KERNEL(OCVOpArrK4, OpArrK4)
{
static void run(const bool& b, const std::string& s,
int& i, std::vector<std::string>& vs)
{
vs.clear();
vs.resize(2);
i = b ? 42 : 24;
auto s_copy = s + " world";
vs = std::vector<std::string>{s_copy, s_copy};
}
};
} // namespace ThisTest
TEST(S11N, Pipeline_GOpaque)
{
using namespace ThisTest;
GOpBool in1;
GOpInt in2;
GOpDouble in3;
auto out = OpGenerate::on(in1, in2, in3);
cv::GComputation c(cv::GIn(in1, in2, in3), cv::GOut(std::get<0>(out), std::get<1>(out), std::get<2>(out)));
auto p = cv::gapi::serialize(c);
auto dc = cv::gapi::deserialize<cv::GComputation>(p);
bool b = true;
int i = 33;
double d = 128.7;
cv::Point pp;
cv::Size s;
cv::Rect r;
dc.apply(cv::gin(b, i, d), cv::gout(pp, s, r), cv::compile_args(cv::gapi::kernels<OCVOpGenerate>()));
EXPECT_EQ(pp, cv::Point(i, i*2));
EXPECT_EQ(s, cv::Size(42, 42));
int ii = static_cast<int>(d);
EXPECT_EQ(r, cv::Rect(ii, ii, ii, ii));
}
TEST(S11N, Pipeline_GArray)
{
using namespace ThisTest;
GArrInt in1, in2;
GArrDouble in3;
GArrScalar in4;
auto out = ArrGenerate::on(in1, in2, in3, in4);
cv::GComputation c(cv::GIn(in1, in2, in3, in4),
cv::GOut(std::get<0>(out), std::get<1>(out),
std::get<2>(out), std::get<3>(out)));
auto p = cv::gapi::serialize(c);
auto dc = cv::gapi::deserialize<cv::GComputation>(p);
std::vector<int> b {1, 0, -1};
std::vector<int> i {3, 0 , 59};
std::vector<double> d {0.7, 120.5, 44.14};
std::vector<cv::Scalar> sc {cv::Scalar::all(10), cv::Scalar::all(15), cv::Scalar::all(99)};
std::vector<cv::Point> pp;
std::vector<cv::Size> s;
std::vector<cv::Rect> r;
std::vector<cv::Mat> m;
dc.apply(cv::gin(b, i, d, sc), cv::gout(pp, s, r, m), cv::compile_args(cv::gapi::kernels<OCVArrGenerate>()));
for (std::size_t idx = 0; idx < b.size(); ++idx)
{
EXPECT_EQ(pp[idx], cv::Point(i[idx], i[idx]*2));
EXPECT_EQ(s[idx], b[idx] == 1 ? cv::Size(42, 42) : cv::Size(7, 7));
int ii = static_cast<int>(d[idx]);
EXPECT_EQ(r[idx], cv::Rect(ii, ii, ii, ii));
}
}
TEST(S11N, Pipeline_GArray_GOpaque_Multinode)
{
using namespace ThisTest;
GOpInt in1;
GArrSize in2;
auto tmp = OpArrK1::on(in1, in2);
auto out = OpArrK2::on(std::get<0>(tmp), std::get<1>(tmp));
cv::GComputation c(cv::GIn(in1, in2),
cv::GOut(std::get<0>(out), std::get<1>(out)));
auto p = cv::gapi::serialize(c);
auto dc = cv::gapi::deserialize<cv::GComputation>(p);
int i = 42;
std::vector<cv::Size> s{cv::Size(11, 22), cv::Size(13, 18)};
double d;
std::vector<cv::Point> pp;
dc.apply(cv::gin(i, s), cv::gout(d, pp), cv::compile_args(cv::gapi::kernels<OCVOpArrK1, OCVOpArrK2>()));
auto st = cv::Size(i ,i);
EXPECT_EQ(d, st.area() * 1.5);
for (std::size_t idx = 0; idx < s.size(); ++idx)
{
EXPECT_EQ(pp[idx], cv::Point(s[idx].area(), s[idx].area()));
}
}
TEST(S11N, Pipeline_GArray_GOpaque_2)
{
using namespace ThisTest;
cv::GArray<bool> in1;
cv::GArray<int32_t> in2;
cv::GOpaque<float> in3;
auto out = OpArrK3::on(in1, in2, in3);
cv::GComputation c(cv::GIn(in1, in2, in3),
cv::GOut(std::get<0>(out), std::get<1>(out)));
auto p = cv::gapi::serialize(c);
auto dc = cv::gapi::deserialize<cv::GComputation>(p);
std::vector<bool> b {true, false, false};
std::vector<int32_t> i {234324, -234252, 999};
float f = 0.85f;
std::vector<int32_t> out_i;
std::vector<uint64_t> out_ui;
dc.apply(cv::gin(b, i, f), cv::gout(out_ui, out_i), cv::compile_args(cv::gapi::kernels<OCVOpArrK3>()));
for (std::size_t idx = 0; idx < b.size(); ++idx)
{
EXPECT_EQ(out_i[idx], b[idx] ? i[idx] : -i[idx]);
EXPECT_EQ(out_ui[idx], b[idx] ? static_cast<uint64_t>(i[idx] * f) :
static_cast<uint64_t>(i[idx] / f));
}
}
TEST(S11N, Pipeline_GArray_GOpaque_3)
{
using namespace ThisTest;
cv::GOpaque<bool> in1;
cv::GOpaque<std::string> in2;
auto out = OpArrK4::on(in1, in2);
cv::GComputation c(cv::GIn(in1, in2),
cv::GOut(std::get<0>(out), std::get<1>(out)));
auto p = cv::gapi::serialize(c);
auto dc = cv::gapi::deserialize<cv::GComputation>(p);
bool b = false;
std::string s("hello");
int i = 0;
std::vector<std::string> vs{};
dc.apply(cv::gin(b, s), cv::gout(i, vs), cv::compile_args(cv::gapi::kernels<OCVOpArrK4>()));
EXPECT_EQ(24, i);
std::vector<std::string> vs_ref{"hello world", "hello world"};
EXPECT_EQ(vs_ref, vs);
}
TEST(S11N, Pipeline_Render_NV12)
{
cv::Size sz (100, 200);
int rects_num = 10;
int text_num = 10;
int image_num = 10;
int thick = 2;
int lt = LINE_8;
cv::Scalar color(111, 222, 77);
// G-API code //////////////////////////////////////////////////////////////
cv::gapi::wip::draw::Prims prims;
// Rects
int shift = 0;
for (int i = 0; i < rects_num; ++i) {
cv::Rect rect(200 + i, 200 + i, 200, 200);
prims.emplace_back(cv::gapi::wip::draw::Rect(rect, color, thick, lt, shift));
}
// Mosaic
int cellsz = 50;
int decim = 0;
for (int i = 0; i < rects_num; ++i) {
cv::Rect mos(200 + i, 200 + i, 200, 200);
prims.emplace_back(cv::gapi::wip::draw::Mosaic(mos, cellsz, decim));
}
// Text
std::string text = "Some text";
int ff = FONT_HERSHEY_SIMPLEX;
double fs = 2.0;
bool blo = false;
for (int i = 0; i < text_num; ++i) {
cv::Point org(200 + i, 200 + i);
prims.emplace_back(cv::gapi::wip::draw::Text(text, org, ff, fs, color, thick, lt, blo));
}
// Image
double transparency = 1.0;
cv::Rect rect_img(0 ,0 , 50, 50);
cv::Mat img(rect_img.size(), CV_8UC3, color);
cv::Mat alpha(rect_img.size(), CV_32FC1, transparency);
auto tl = rect_img.tl();
for (int i = 0; i < image_num; ++i) {
cv::Point org_img = {tl.x + i, tl.y + rect_img.size().height + i};
prims.emplace_back(cv::gapi::wip::draw::Image({org_img, img, alpha}));
}
// Circle
cv::Point center(300, 400);
int rad = 25;
prims.emplace_back(cv::gapi::wip::draw::Circle({center, rad, color, thick, lt, shift}));
// Line
cv::Point point_next(300, 425);
prims.emplace_back(cv::gapi::wip::draw::Line({center, point_next, color, thick, lt, shift}));
// Poly
std::vector<cv::Point> points = {{300, 400}, {290, 450}, {348, 410}, {300, 400}};
prims.emplace_back(cv::gapi::wip::draw::Poly({points, color, thick, lt, shift}));
cv::GMat y_in, uv_in, y_out, uv_out;
cv::GArray<cv::gapi::wip::draw::Prim> arr;
std::tie(y_out, uv_out) = cv::gapi::wip::draw::renderNV12(y_in, uv_in, arr);
cv::GComputation comp(cv::GIn(y_in, uv_in, arr), cv::GOut(y_out, uv_out));
auto serialized = cv::gapi::serialize(comp);
auto dc = cv::gapi::deserialize<cv::GComputation>(serialized);
cv::Mat y(1920, 1080, CV_8UC1);
cv::Mat uv(960, 540, CV_8UC2);
cv::randu(y, cv::Scalar(0), cv::Scalar(255));
cv::randu(uv, cv::Scalar::all(0), cv::Scalar::all(255));
cv::Mat y_ref_mat = y.clone(), uv_ref_mat = uv.clone();
dc.apply(cv::gin(y, uv, prims), cv::gout(y, uv));
// OpenCV code //////////////////////////////////////////////////////////////
cv::Mat yuv;
cv::gapi::wip::draw::cvtNV12ToYUV(y_ref_mat, uv_ref_mat, yuv);
for (int i = 0; i < rects_num; ++i) {
cv::Rect rect(200 + i, 200 + i, 200, 200);
cv::rectangle(yuv, rect, cvtBGRToYUVC(color), thick, lt, shift);
}
for (int i = 0; i < rects_num; ++i) {
cv::Rect mos(200 + i, 200 + i, 200, 200);
drawMosaicRef(yuv, mos, cellsz);
}
for (int i = 0; i < text_num; ++i) {
cv::Point org(200 + i, 200 + i);
cv::putText(yuv, text, org, ff, fs, cvtBGRToYUVC(color), thick, lt, blo);
}
for (int i = 0; i < image_num; ++i) {
cv::Point org_img = {tl.x + i, tl.y + rect_img.size().height + i};
cv::Mat yuv_img;
cv::cvtColor(img, yuv_img, cv::COLOR_BGR2YUV);
blendImageRef(yuv, org_img, yuv_img, alpha);
}
cv::circle(yuv, center, rad, cvtBGRToYUVC(color), thick, lt, shift);
cv::line(yuv, center, point_next, cvtBGRToYUVC(color), thick, lt, shift);
std::vector<std::vector<cv::Point>> pp{points};
cv::fillPoly(yuv, pp, cvtBGRToYUVC(color), lt, shift);
// YUV -> NV12
cv::gapi::wip::draw::cvtYUVToNV12(yuv, y_ref_mat, uv_ref_mat);
EXPECT_EQ(cv::norm( y, y_ref_mat), 0);
EXPECT_EQ(cv::norm(uv, uv_ref_mat), 0);
}
TEST(S11N, Pipeline_Render_RGB)
{
cv::Size sz (100, 200);
int rects_num = 10;
int text_num = 10;
int image_num = 10;
int thick = 2;
int lt = LINE_8;
cv::Scalar color(111, 222, 77);
// G-API code //////////////////////////////////////////////////////////////
cv::gapi::wip::draw::Prims prims;
// Rects
int shift = 0;
for (int i = 0; i < rects_num; ++i) {
cv::Rect rect(200 + i, 200 + i, 200, 200);
prims.emplace_back(cv::gapi::wip::draw::Rect(rect, color, thick, lt, shift));
}
// Mosaic
int cellsz = 50;
int decim = 0;
for (int i = 0; i < rects_num; ++i) {
cv::Rect mos(200 + i, 200 + i, 200, 200);
prims.emplace_back(cv::gapi::wip::draw::Mosaic(mos, cellsz, decim));
}
// Text
std::string text = "Some text";
int ff = FONT_HERSHEY_SIMPLEX;
double fs = 2.0;
bool blo = false;
for (int i = 0; i < text_num; ++i) {
cv::Point org(200 + i, 200 + i);
prims.emplace_back(cv::gapi::wip::draw::Text(text, org, ff, fs, color, thick, lt, blo));
}
// Image
double transparency = 1.0;
cv::Rect rect_img(0 ,0 , 50, 50);
cv::Mat img(rect_img.size(), CV_8UC3, color);
cv::Mat alpha(rect_img.size(), CV_32FC1, transparency);
auto tl = rect_img.tl();
for (int i = 0; i < image_num; ++i) {
cv::Point org_img = {tl.x + i, tl.y + rect_img.size().height + i};
prims.emplace_back(cv::gapi::wip::draw::Image({org_img, img, alpha}));
}
// Circle
cv::Point center(300, 400);
int rad = 25;
prims.emplace_back(cv::gapi::wip::draw::Circle({center, rad, color, thick, lt, shift}));
// Line
cv::Point point_next(300, 425);
prims.emplace_back(cv::gapi::wip::draw::Line({center, point_next, color, thick, lt, shift}));
// Poly
std::vector<cv::Point> points = {{300, 400}, {290, 450}, {348, 410}, {300, 400}};
prims.emplace_back(cv::gapi::wip::draw::Poly({points, color, thick, lt, shift}));
cv::GMat in, out;
cv::GArray<cv::gapi::wip::draw::Prim> arr;
out = cv::gapi::wip::draw::render3ch(in, arr);
cv::GComputation comp(cv::GIn(in, arr), cv::GOut(out));
auto serialized = cv::gapi::serialize(comp);
auto dc = cv::gapi::deserialize<cv::GComputation>(serialized);
cv::Mat input(1920, 1080, CV_8UC3);
cv::randu(input, cv::Scalar::all(0), cv::Scalar::all(255));
cv::Mat ref_mat = input.clone();
dc.apply(cv::gin(input, prims), cv::gout(input));
// OpenCV code //////////////////////////////////////////////////////////////
for (int i = 0; i < rects_num; ++i) {
cv::Rect rect(200 + i, 200 + i, 200, 200);
cv::rectangle(ref_mat, rect, color, thick, lt, shift);
}
for (int i = 0; i < rects_num; ++i) {
cv::Rect mos(200 + i, 200 + i, 200, 200);
drawMosaicRef(ref_mat, mos, cellsz);
}
for (int i = 0; i < text_num; ++i) {
cv::Point org(200 + i, 200 + i);
cv::putText(ref_mat, text, org, ff, fs, color, thick, lt, blo);
}
for (int i = 0; i < image_num; ++i) {
cv::Point org_img = {tl.x + i, tl.y + rect_img.size().height + i};
blendImageRef(ref_mat, org_img, img, alpha);
}
cv::circle(ref_mat, center, rad, color, thick, lt, shift);
cv::line(ref_mat, center, point_next, color, thick, lt, shift);
std::vector<std::vector<cv::Point>> pp{points};
cv::fillPoly(ref_mat, pp, color, lt, shift);
EXPECT_EQ(cv::norm(input, ref_mat), 0);
}
TEST(S11N, Pipeline_Const_GScalar)
{
static constexpr auto in_scalar = 10;
cv::GMat a;
cv::GScalar s;
cv::GComputation computation(GIn(a), GOut(cv::gapi::addC(a, in_scalar)));
auto p = cv::gapi::serialize(computation);
auto deserialized_computation = cv::gapi::deserialize<cv::GComputation>(p);
cv::Mat in_mat = cv::Mat::eye(32, 32, CV_8UC1);
cv::Mat ref_mat;
cv::add(in_mat, in_scalar, ref_mat);
cv::Mat out_mat;
computation.apply(cv::gin(in_mat/*, in_scalar*/), cv::gout(out_mat));
EXPECT_EQ(0, cvtest::norm(out_mat, ref_mat, NORM_INF));
out_mat = cv::Mat();
deserialized_computation.apply(cv::gin(in_mat/*, in_scalar*/), cv::gout(out_mat));
EXPECT_EQ(0, cvtest::norm(out_mat, ref_mat, NORM_INF));
out_mat = cv::Mat();
auto cc = deserialized_computation.compile(cv::descr_of(in_mat));
cc(cv::gin(in_mat/*, in_scalar*/), cv::gout(out_mat));
EXPECT_EQ(0, cvtest::norm(out_mat, ref_mat, NORM_INF));
}
} // namespace opencv_test