diff --git a/modules/core/include/opencv2/core/mat.inl.hpp b/modules/core/include/opencv2/core/mat.inl.hpp index 2ef7aec3c6..2d79130c32 100644 --- a/modules/core/include/opencv2/core/mat.inl.hpp +++ b/modules/core/include/opencv2/core/mat.inl.hpp @@ -1058,6 +1058,34 @@ const uchar* Mat::ptr(const int* idx) const return p; } +template inline +_Tp* Mat::ptr(const int* idx) +{ + int i, d = dims; + uchar* p = data; + CV_DbgAssert( d >= 1 && p ); + for( i = 0; i < d; i++ ) + { + CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] ); + p += idx[i] * step.p[i]; + } + return (_Tp*)p; +} + +template inline +const _Tp* Mat::ptr(const int* idx) const +{ + int i, d = dims; + uchar* p = data; + CV_DbgAssert( d >= 1 && p ); + for( i = 0; i < d; i++ ) + { + CV_DbgAssert( (unsigned)idx[i] < (unsigned)size.p[i] ); + p += idx[i] * step.p[i]; + } + return (const _Tp*)p; +} + template inline _Tp& Mat::at(int i0, int i1) { diff --git a/modules/core/test/test_mat.cpp b/modules/core/test/test_mat.cpp index 6c2ab85c3c..58437d2c4a 100644 --- a/modules/core/test/test_mat.cpp +++ b/modules/core/test/test_mat.cpp @@ -1804,4 +1804,24 @@ TEST(Mat_, from_initializer_list) ASSERT_DOUBLE_EQ(norm(A, B, NORM_INF), 0.); } + +TEST(Mat, template_based_ptr) +{ + Mat mat = (Mat_(2, 2) << 11.0f, 22.0f, 33.0f, 44.0f); + int idx[2] = {1, 0}; + ASSERT_FLOAT_EQ(33.0f, *(mat.ptr(idx))); + idx[0] = 1; + idx[1] = 1; + ASSERT_FLOAT_EQ(44.0f, *(mat.ptr(idx))); +} + +TEST(Mat_, template_based_ptr) +{ + int dim[4] = {2, 2, 1, 2}; + Mat_ mat = (Mat_(4, dim) << 11.0f, 22.0f, 33.0f, 44.0f, + 55.0f, 66.0f, 77.0f, 88.0f); + int idx[4] = {1, 0, 0, 1}; + ASSERT_FLOAT_EQ(66.0f, *(mat.ptr(idx))); +} + #endif