fix#9570: implement mat ptr for generic types
authortz70s <su3g4284zo6y7@gmail.com>
Tue, 10 Oct 2017 05:28:07 +0000 (13:28 +0800)
committertz70s <su3g4284zo6y7@gmail.com>
Tue, 10 Oct 2017 13:46:49 +0000 (21:46 +0800)
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
modules/core/test/test_mat.cpp

index 2ef7aec..2d79130 100644 (file)
@@ -1059,6 +1059,34 @@ const uchar* Mat::ptr(const int* idx) const
 }
 
 template<typename _Tp> 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<typename _Tp> 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<typename _Tp> inline
 _Tp& Mat::at(int i0, int i1)
 {
     CV_DbgAssert(dims <= 2);
index 6c2ab85..58437d2 100644 (file)
@@ -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_<float>(2, 2) << 11.0f, 22.0f, 33.0f, 44.0f);
+    int idx[2] = {1, 0};
+    ASSERT_FLOAT_EQ(33.0f, *(mat.ptr<float>(idx)));
+    idx[0] = 1;
+    idx[1] = 1;
+    ASSERT_FLOAT_EQ(44.0f, *(mat.ptr<float>(idx)));
+}
+
+TEST(Mat_, template_based_ptr)
+{
+    int dim[4] = {2, 2, 1, 2};
+    Mat_<float> mat = (Mat_<float>(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<float>(idx)));
+}
+
 #endif