Skip to content

Commit e5fbb4f

Browse files
sovrasovalalek
authored andcommitted
Merge pull request opencv#9034 from sovrasov:mats_from_initializer_list
Add constructors taking initializer_list for some of OpenCV data types (opencv#9034) * Add a constructor taking initializer_list for Matx * Add a constructor taking initializer list for Mat and Mat_ * Add one more method to initialize Mat to the corresponding tutorial * Add a note how to initialize Matx * CV_CXX_11->CV_CXX11
1 parent 11626fe commit e5fbb4f

File tree

9 files changed

+118
-15
lines changed

9 files changed

+118
-15
lines changed

doc/tutorials/core/mat_the_basic_image_container/mat_the_basic_image_container.markdown

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,10 +192,12 @@ object in multiple ways:
192192

193193
![](images/MatBasicContainerOut3.png)
194194

195-
- For small matrices you may use comma separated initializers:
195+
- For small matrices you may use comma separated initializers or initializer lists (C++11 support is required in the last case):
196196

197197
@snippet mat_the_basic_image_container.cpp comma
198198

199+
@snippet mat_the_basic_image_container.cpp list
200+
199201
![](images/MatBasicContainerOut6.png)
200202

201203
- Create a new header for an existing *Mat* object and @ref cv::Mat::clone or @ref cv::Mat::copyTo it.

modules/core/include/opencv2/core/cvdef.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -357,13 +357,13 @@ Cv64suf;
357357
/****************************************************************************************\
358358
* C++ 11 *
359359
\****************************************************************************************/
360-
#ifndef CV_CXX_11
361-
# if __cplusplus >= 201103L || defined(_MSC_VER) && _MSC_VER >= 1600
362-
# define CV_CXX_11 1
360+
#ifndef CV_CXX11
361+
# if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)
362+
# define CV_CXX11 1
363363
# endif
364364
#else
365-
# if CV_CXX_11 == 0
366-
# undef CV_CXX_11
365+
# if CV_CXX11 == 0
366+
# undef CV_CXX11
367367
# endif
368368
#endif
369369

@@ -373,7 +373,7 @@ Cv64suf;
373373
\****************************************************************************************/
374374

375375
#ifndef CV_CXX_MOVE_SEMANTICS
376-
# if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(_MSC_VER) && _MSC_VER >= 1600
376+
# if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) || (defined(_MSC_VER) && _MSC_VER >= 1600)
377377
# define CV_CXX_MOVE_SEMANTICS 1
378378
# elif defined(__clang)
379379
# if __has_feature(cxx_rvalue_references)

modules/core/include/opencv2/core/mat.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -981,6 +981,12 @@ class CV_EXPORTS Mat
981981
*/
982982
template<typename _Tp> explicit Mat(const std::vector<_Tp>& vec, bool copyData=false);
983983

984+
#ifdef CV_CXX11
985+
/** @overload
986+
*/
987+
template<typename _Tp> explicit Mat(const std::initializer_list<_Tp> list);
988+
#endif
989+
984990
#ifdef CV_CXX_STD_ARRAY
985991
/** @overload
986992
*/
@@ -2170,6 +2176,10 @@ template<typename _Tp> class Mat_ : public Mat
21702176
explicit Mat_(const Point3_<typename DataType<_Tp>::channel_type>& pt, bool copyData=true);
21712177
explicit Mat_(const MatCommaInitializer_<_Tp>& commaInitializer);
21722178

2179+
#ifdef CV_CXX11
2180+
Mat_(std::initializer_list<_Tp> values);
2181+
#endif
2182+
21732183
#ifdef CV_CXX_STD_ARRAY
21742184
template <std::size_t _Nm> explicit Mat_(const std::array<_Tp, _Nm>& arr, bool copyData=false);
21752185
#endif

modules/core/include/opencv2/core/mat.inl.hpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,18 @@ Mat::Mat(const std::vector<_Tp>& vec, bool copyData)
570570
Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this);
571571
}
572572

573+
#ifdef CV_CXX11
574+
template<typename _Tp> inline
575+
Mat::Mat(const std::initializer_list<_Tp> list)
576+
: flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows((int)list.size()),
577+
cols(1), data(0), datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0)
578+
{
579+
if(list.size() == 0)
580+
return;
581+
Mat((int)list.size(), 1, DataType<_Tp>::type, (uchar*)list.begin()).copyTo(*this);
582+
}
583+
#endif
584+
573585
#ifdef CV_CXX_STD_ARRAY
574586
template<typename _Tp, std::size_t _Nm> inline
575587
Mat::Mat(const std::array<_Tp, _Nm>& arr, bool copyData)
@@ -1573,6 +1585,13 @@ Mat_<_Tp>::Mat_(const std::vector<_Tp>& vec, bool copyData)
15731585
: Mat(vec, copyData)
15741586
{}
15751587

1588+
#ifdef CV_CXX11
1589+
template<typename _Tp> inline
1590+
Mat_<_Tp>::Mat_(std::initializer_list<_Tp> list)
1591+
: Mat(list)
1592+
{}
1593+
#endif
1594+
15761595
#ifdef CV_CXX_STD_ARRAY
15771596
template<typename _Tp> template<std::size_t _Nm> inline
15781597
Mat_<_Tp>::Mat_(const std::array<_Tp, _Nm>& arr, bool copyData)

modules/core/include/opencv2/core/matx.hpp

Lines changed: 43 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@
5353
#include "opencv2/core/traits.hpp"
5454
#include "opencv2/core/saturate.hpp"
5555

56+
#ifdef CV_CXX11
57+
#include <initializer_list>
58+
#endif
59+
5660
namespace cv
5761
{
5862

@@ -77,12 +81,21 @@ If you need a more flexible type, use Mat . The elements of the matrix M are acc
7781
M(i,j) notation. Most of the common matrix operations (see also @ref MatrixExpressions ) are
7882
available. To do an operation on Matx that is not implemented, you can easily convert the matrix to
7983
Mat and backwards:
80-
@code
84+
@code{.cpp}
8185
Matx33f m(1, 2, 3,
8286
4, 5, 6,
8387
7, 8, 9);
8488
cout << sum(Mat(m*m.t())) << endl;
85-
@endcode
89+
@endcode
90+
Except of the plain constructor which takes a list of elements, Matx can be initialized from a C-array:
91+
@code{.cpp}
92+
float values[] = { 1, 2, 3};
93+
Matx31f m(values);
94+
@endcode
95+
In case if C++11 features are avaliable, std::initializer_list can be also used to initizlize Matx:
96+
@code{.cpp}
97+
Matx31f m = { 1, 2, 3};
98+
@endcode
8699
*/
87100
template<typename _Tp, int m, int n> class Matx
88101
{
@@ -125,6 +138,10 @@ template<typename _Tp, int m, int n> class Matx
125138
_Tp v12, _Tp v13, _Tp v14, _Tp v15); //!< 1x16, 4x4 or 16x1 matrix
126139
explicit Matx(const _Tp* vals); //!< initialize from a plain array
127140

141+
#ifdef CV_CXX11
142+
Matx(std::initializer_list<_Tp>); //!< initialize from an initializer list
143+
#endif
144+
128145
static Matx all(_Tp alpha);
129146
static Matx zeros();
130147
static Matx ones();
@@ -327,6 +344,10 @@ template<typename _Tp, int cn> class Vec : public Matx<_Tp, cn, 1>
327344
Vec(_Tp v0, _Tp v1, _Tp v2, _Tp v3, _Tp v4, _Tp v5, _Tp v6, _Tp v7, _Tp v8, _Tp v9, _Tp v10, _Tp v11, _Tp v12, _Tp v13); //!< 14-element vector constructor
328345
explicit Vec(const _Tp* values);
329346

347+
#ifdef CV_CXX11
348+
Vec(std::initializer_list<_Tp>);
349+
#endif
350+
330351
Vec(const Vec<_Tp, cn>& v);
331352

332353
static Vec all(_Tp alpha);
@@ -616,6 +637,19 @@ Matx<_Tp, m, n>::Matx(const _Tp* values)
616637
for( int i = 0; i < channels; i++ ) val[i] = values[i];
617638
}
618639

640+
#ifdef CV_CXX11
641+
template<typename _Tp, int m, int n> inline
642+
Matx<_Tp, m, n>::Matx(std::initializer_list<_Tp> list)
643+
{
644+
CV_DbgAssert(list.size() == channels);
645+
int i = 0;
646+
for(const auto& elem : list)
647+
{
648+
val[i++] = elem;
649+
}
650+
}
651+
#endif
652+
619653
template<typename _Tp, int m, int n> inline
620654
Matx<_Tp, m, n> Matx<_Tp, m, n>::all(_Tp alpha)
621655
{
@@ -957,6 +991,12 @@ template<typename _Tp, int cn> inline
957991
Vec<_Tp, cn>::Vec(const _Tp* values)
958992
: Matx<_Tp, cn, 1>(values) {}
959993

994+
#ifdef CV_CXX11
995+
template<typename _Tp, int cn> inline
996+
Vec<_Tp, cn>::Vec(std::initializer_list<_Tp> list)
997+
: Matx<_Tp, cn, 1>(list) {}
998+
#endif
999+
9601000
template<typename _Tp, int cn> inline
9611001
Vec<_Tp, cn>::Vec(const Vec<_Tp, cn>& m)
9621002
: Matx<_Tp, cn, 1>(m.val) {}
@@ -1081,7 +1121,7 @@ Vec<_Tp, cn> normalize(const Vec<_Tp, cn>& v)
10811121

10821122

10831123

1084-
//////////////////////////////// matx comma initializer //////////////////////////////////
1124+
//////////////////////////////// vec comma initializer //////////////////////////////////
10851125

10861126

10871127
template<typename _Tp, typename _T2, int cn> static inline

modules/core/include/opencv2/core/utility.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
#include "opencv2/core.hpp"
5757
#include <ostream>
5858

59-
#ifdef CV_CXX_11
59+
#ifdef CV_CXX11
6060
#include <functional>
6161
#endif
6262

@@ -482,7 +482,7 @@ class CV_EXPORTS ParallelLoopBody
482482
*/
483483
CV_EXPORTS void parallel_for_(const Range& range, const ParallelLoopBody& body, double nstripes=-1.);
484484

485-
#ifdef CV_CXX_11
485+
#ifdef CV_CXX11
486486
class ParallelLoopBodyLambdaWrapper : public ParallelLoopBody
487487
{
488488
private:

modules/core/test/test_mat.cpp

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1398,6 +1398,15 @@ TEST(Core_Matx, fromMat_)
13981398
ASSERT_EQ( cvtest::norm(a, b, NORM_INF), 0.);
13991399
}
14001400

1401+
#ifdef CV_CXX11
1402+
TEST(Core_Matx, from_initializer_list)
1403+
{
1404+
Mat_<double> a = (Mat_<double>(2,2) << 10, 11, 12, 13);
1405+
Matx22d b = {10, 11, 12, 13};
1406+
ASSERT_EQ( cvtest::norm(a, b, NORM_INF), 0.);
1407+
}
1408+
#endif
1409+
14011410
TEST(Core_InputArray, empty)
14021411
{
14031412
vector<vector<Point> > data;
@@ -1735,7 +1744,7 @@ TEST(Mat, regression_8680)
17351744
ASSERT_EQ(mat.channels(), 2);
17361745
}
17371746

1738-
#ifdef CV_CXX_11
1747+
#ifdef CV_CXX11
17391748

17401749
TEST(Mat_, range_based_for)
17411750
{
@@ -1751,4 +1760,21 @@ TEST(Mat_, range_based_for)
17511760
ASSERT_DOUBLE_EQ(norm(img, ref), 0.);
17521761
}
17531762

1763+
TEST(Mat, from_initializer_list)
1764+
{
1765+
Mat A({1.f, 2.f, 3.f});
1766+
Mat_<float> B(3, 1); B << 1, 2, 3;
1767+
1768+
ASSERT_EQ(A.type(), CV_32F);
1769+
ASSERT_DOUBLE_EQ(norm(A, B, NORM_INF), 0.);
1770+
}
1771+
1772+
TEST(Mat_, from_initializer_list)
1773+
{
1774+
Mat_<float> A = {1, 2, 3};
1775+
Mat_<float> B(3, 1); B << 1, 2, 3;
1776+
1777+
ASSERT_DOUBLE_EQ(norm(A, B, NORM_INF), 0.);
1778+
}
1779+
17541780
#endif

samples/cpp/tutorial_code/core/how_to_use_OpenCV_parallel_for_/how_to_use_OpenCV_parallel_for_.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ int main()
102102

103103
double t1 = (double) getTickCount();
104104

105-
#ifdef CV_CXX_11
105+
#ifdef CV_CXX11
106106

107107
//! [mandelbrot-parallel-call-cxx11]
108108
parallel_for_(Range(0, mandelbrotImg.rows*mandelbrotImg.cols), [&](const Range& range){

samples/cpp/tutorial_code/core/mat_the_basic_image_container/mat_the_basic_image_container.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,13 @@ int main(int,char**)
5858
Mat C = (Mat_<double>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
5959
cout << "C = " << endl << " " << C << endl << endl;
6060
//! [comma]
61-
61+
// do the same with initializer_list
62+
#ifdef CV_CXX11
63+
//! [list]
64+
C = (Mat_<double>({0, -1, 0, -1, 5, -1, 0, -1, 0})).reshape(3);
65+
cout << "C = " << endl << " " << C << endl << endl;
66+
//! [list]
67+
#endif
6268
//! [clone]
6369
Mat RowClone = C.row(1).clone();
6470
cout << "RowClone = " << endl << " " << RowClone << endl << endl;

0 commit comments

Comments
 (0)