Skip to content

Commit

Permalink
Merge pull request opencv#21782 from TolyaTalamanov:at/fix-1d-mat-pro…
Browse files Browse the repository at this point in the history
…blems

[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
  • Loading branch information
TolyaTalamanov authored Mar 31, 2022
1 parent 5e43407 commit 9390c56
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 1 deletion.
2 changes: 2 additions & 0 deletions modules/core/src/matrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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++ )
Expand Down
11 changes: 11 additions & 0 deletions modules/core/test/test_mat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
6 changes: 6 additions & 0 deletions modules/gapi/src/api/gbackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}

Expand Down
83 changes: 83 additions & 0 deletions modules/gapi/test/gapi_sample_pipelines.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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") {};
Expand Down Expand Up @@ -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

0 comments on commit 9390c56

Please sign in to comment.