Merge pull request #21782 from TolyaTalamanov:at/fix-1d-mat-problems

[G-API] Fix problems with 1D cv::Mat as graph output

* Fix issues with 1D cv::Mat

* Fix cv::Mat::create

* Fix standalone build

* Add test on 1d mat

* Fix warning

* Add additional condition

* Add more tests
This commit is contained in:
Anatoliy Talamanov 2022-04-01 00:00:45 +03:00 committed by GitHub
parent 5e434073d4
commit 9390c56831
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 104 additions and 1 deletions

View File

@ -664,6 +664,8 @@ void Mat::create(int d, const int* _sizes, int _type)
if( data && (d == dims || (d == 1 && dims <= 2)) && _type == type() )
{
if ( dims == 1 && (d == 1 && _sizes[0] == size[0]) )
return;
if( d == 2 && rows == _sizes[0] && cols == _sizes[1] )
return;
for( i = 0; i < d; i++ )

View File

@ -2461,5 +2461,16 @@ TEST(Mat, reverse_iterator_19967)
}
TEST(Mat, Recreate1DMatWithSameMeta)
{
std::vector<int> dims = {100};
auto depth = CV_8U;
cv::Mat m(dims, depth);
// By default m has dims: [1, 100]
m.dims = 1;
EXPECT_NO_THROW(m.create(dims, depth));
}
}} // namespace

View File

@ -133,7 +133,8 @@ struct DummyCall {
if (output.dims.size() == 2) {
return cv::GMatDesc(output.precision,
1,
cv::Size(output.dims[0], output.dims[1]));
// NB: Dims[H, W] -> Size(W, H)
cv::Size(output.dims[1], output.dims[0]));
}
return cv::GMatDesc(output.precision, output.dims);
}

View File

@ -411,6 +411,12 @@ void createMat(const cv::GMatDesc &desc, cv::Mat& mat)
{
GAPI_Assert(!desc.planar);
mat.create(desc.dims, desc.depth);
#if !defined(GAPI_STANDALONE)
// NB: WA for 1D mats.
if (desc.dims.size() == 1u) {
mat.dims = 1;
}
#endif
}
}

View File

@ -49,6 +49,24 @@ namespace
static GMatDesc outMeta(GMatDesc in) { return in; }
};
G_TYPED_KERNEL(GZeros, <GMat(GMat, GMatDesc)>, "org.opencv.test.zeros")
{
static GMatDesc outMeta(GMatDesc /*in*/, GMatDesc user_desc)
{
return user_desc;
}
};
GAPI_OCV_KERNEL(GOCVZeros, GZeros)
{
static void run(const cv::Mat& /*in*/,
const cv::GMatDesc& /*desc*/,
cv::Mat& out)
{
out.setTo(0);
}
};
// These definitons test the correct macro work if the kernel has multiple output values
G_TYPED_KERNEL(GRetGArrayTupleOfGMat2Kernel, <GArray<std::tuple<GMat, GMat>>(GMat, Scalar)>, "org.opencv.test.retarrayoftupleofgmat2kernel") {};
G_TYPED_KERNEL(GRetGArraTupleyOfGMat3Kernel, <GArray<std::tuple<GMat, GMat, GMat>>(GMat)>, "org.opencv.test.retarrayoftupleofgmat3kernel") {};
@ -430,4 +448,69 @@ TEST(GAPI_Pipeline, ReplaceDefaultByFunctor)
EXPECT_TRUE(f.is_called);
}
TEST(GAPI_Pipeline, GraphOutputIs1DMat)
{
int dim = 100;
cv::Mat in_mat(1, 1, CV_8UC3);
cv::Mat out_mat;
cv::GMat in;
auto cc = cv::GComputation(in, GZeros::on(in, cv::GMatDesc(CV_8U, {dim})))
.compile(cv::descr_of(in_mat), cv::compile_args(cv::gapi::kernels<GOCVZeros>()));
// NB: Computation is able to write 1D output cv::Mat to empty out_mat.
ASSERT_NO_THROW(cc(cv::gin(in_mat), cv::gout(out_mat)));
ASSERT_EQ(1, out_mat.size.dims());
ASSERT_EQ(dim, out_mat.size[0]);
// NB: Computation is able to write 1D output cv::Mat
// to pre-allocated with the same meta out_mat.
ASSERT_NO_THROW(cc(cv::gin(in_mat), cv::gout(out_mat)));
ASSERT_EQ(1, out_mat.size.dims());
ASSERT_EQ(dim, out_mat.size[0]);
}
TEST(GAPI_Pipeline, 1DMatBetweenIslands)
{
int dim = 100;
cv::Mat in_mat(1, 1, CV_8UC3);
cv::Mat out_mat;
cv::Mat ref_mat({dim}, CV_8U);
ref_mat.dims = 1;
ref_mat.setTo(0);
cv::GMat in;
auto out = cv::gapi::copy(GZeros::on(cv::gapi::copy(in), cv::GMatDesc(CV_8U, {dim})));
auto cc = cv::GComputation(in, out)
.compile(cv::descr_of(in_mat), cv::compile_args(cv::gapi::kernels<GOCVZeros>()));
cc(cv::gin(in_mat), cv::gout(out_mat));
EXPECT_EQ(0, cv::norm(out_mat, ref_mat));
}
TEST(GAPI_Pipeline, 1DMatWithinSingleIsland)
{
int dim = 100;
cv::Size blur_sz(3, 3);
cv::Mat in_mat(10, 10, CV_8UC3);
cv::randu(in_mat, 0, 255);
cv::Mat out_mat;
cv::Mat ref_mat({dim}, CV_8U);
ref_mat.dims = 1;
ref_mat.setTo(0);
cv::GMat in;
auto out = cv::gapi::blur(
GZeros::on(cv::gapi::blur(in, blur_sz), cv::GMatDesc(CV_8U, {dim})), blur_sz);
auto cc = cv::GComputation(in, out)
.compile(cv::descr_of(in_mat), cv::compile_args(cv::gapi::kernels<GOCVZeros>()));
cc(cv::gin(in_mat), cv::gout(out_mat));
EXPECT_EQ(0, cv::norm(out_mat, ref_mat));
}
} // namespace opencv_test