From 6c1247b38c5035451d19633599264206ab933acb Mon Sep 17 00:00:00 2001 From: tz70s Date: Tue, 10 Oct 2017 13:28:07 +0800 Subject: [PATCH] fix#9570: implement mat ptr for generic types The original template based mat ptr for indexing is not implemented, add the similar implementation as uchar type, but cast to user-defined type from the uchar pointer. --- modules/core/include/opencv2/core/mat.inl.hpp | 28 +++++++++++++++++++ modules/core/test/test_mat.cpp | 20 +++++++++++++ 2 files changed, 48 insertions(+) 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