Skip to content

Commit 46af075

Browse files
committed
Add test case for cv::Mat::forEach
This test case uses a matrix with more dimensions than columns. Without the fix in opencv@b45e784 this crashes with a segmentation fault, hangs or simply fails with wrong values.
1 parent b45e784 commit 46af075

File tree

1 file changed

+63
-0
lines changed

1 file changed

+63
-0
lines changed

modules/core/test/test_mat.cpp

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,18 @@ struct InitializerFunctor{
659659
}
660660
};
661661

662+
template<typename Pixel>
663+
struct InitializerFunctor5D{
664+
/// Initializer for cv::Mat::forEach test (5 dimensional case)
665+
void operator()(Pixel & pixel, const int * idx) const {
666+
pixel[0] = idx[0];
667+
pixel[1] = idx[1];
668+
pixel[2] = idx[2];
669+
pixel[3] = idx[3];
670+
pixel[4] = idx[4];
671+
}
672+
};
673+
662674
void Core_ArrayOpTest::run( int /* start_from */)
663675
{
664676
int errcount = 0;
@@ -736,6 +748,57 @@ void Core_ArrayOpTest::run( int /* start_from */)
736748
}
737749
}
738750

751+
// test cv::Mat::forEach
752+
// with a matrix that has more dimensions than columns
753+
// See https://github.com/opencv/opencv/issues/8447
754+
{
755+
const int dims[5] = { 2, 2, 2, 2, 2 };
756+
typedef cv::Vec<int, 5> Pixel;
757+
758+
cv::Mat a = cv::Mat::zeros(5, dims, CV_32SC(5));
759+
InitializerFunctor5D<Pixel> initializer;
760+
761+
a.forEach<Pixel>(initializer);
762+
763+
uint64 total = 0;
764+
bool error_reported = false;
765+
for (int i0 = 0; i0 < dims[0]; ++i0) {
766+
for (int i1 = 0; i1 < dims[1]; ++i1) {
767+
for (int i2 = 0; i2 < dims[2]; ++i2) {
768+
for (int i3 = 0; i3 < dims[3]; ++i3) {
769+
for (int i4 = 0; i4 < dims[4]; ++i4) {
770+
const int i[5] = { i0, i1, i2, i3, i4 };
771+
Pixel& pixel = a.at<Pixel>(i);
772+
if (pixel[0] != i0 || pixel[1] != i1 || pixel[2] != i2 || pixel[3] != i3 || pixel[4] != i4) {
773+
if (!error_reported) {
774+
ts->printf(cvtest::TS::LOG, "forEach is not correct.\n"
775+
"First error detected at position (%d, %d, %d, %d, %d), got value (%d, %d, %d, %d, %d).\n",
776+
i0, i1, i2, i3, i4,
777+
pixel[0], pixel[1], pixel[2], pixel[3], pixel[4]);
778+
error_reported = true;
779+
}
780+
errcount++;
781+
}
782+
total += pixel[0];
783+
total += pixel[1];
784+
total += pixel[2];
785+
total += pixel[3];
786+
total += pixel[4];
787+
}
788+
}
789+
}
790+
}
791+
}
792+
uint64 total2 = 0;
793+
for (size_t i = 0; i < sizeof(dims) / sizeof(dims[0]); ++i) {
794+
total2 += ((dims[i] - 1) * dims[i] / 2) * dims[0] * dims[1] * dims[2] * dims[3] * dims[4] / dims[i];
795+
}
796+
if (total != total2) {
797+
ts->printf(cvtest::TS::LOG, "forEach is not correct because total is invalid.\n");
798+
errcount++;
799+
}
800+
}
801+
739802
RNG rng;
740803
const int MAX_DIM = 5, MAX_DIM_SZ = 10;
741804
// sparse matrix operations

0 commit comments

Comments
 (0)