mirror of
https://github.com/opencv/opencv.git
synced 2025-08-06 14:36:36 +08:00
Merge pull request #9034 from sovrasov:mats_from_initializer_list
Add constructors taking initializer_list for some of OpenCV data types (#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
This commit is contained in:
parent
11626fe32c
commit
e5fbb4f5d2
@ -192,10 +192,12 @@ object in multiple ways:
|
||||
|
||||

|
||||
|
||||
- For small matrices you may use comma separated initializers:
|
||||
- For small matrices you may use comma separated initializers or initializer lists (C++11 support is required in the last case):
|
||||
|
||||
@snippet mat_the_basic_image_container.cpp comma
|
||||
|
||||
@snippet mat_the_basic_image_container.cpp list
|
||||
|
||||

|
||||
|
||||
- Create a new header for an existing *Mat* object and @ref cv::Mat::clone or @ref cv::Mat::copyTo it.
|
||||
|
@ -357,13 +357,13 @@ Cv64suf;
|
||||
/****************************************************************************************\
|
||||
* C++ 11 *
|
||||
\****************************************************************************************/
|
||||
#ifndef CV_CXX_11
|
||||
# if __cplusplus >= 201103L || defined(_MSC_VER) && _MSC_VER >= 1600
|
||||
# define CV_CXX_11 1
|
||||
#ifndef CV_CXX11
|
||||
# if __cplusplus >= 201103L || (defined(_MSC_VER) && _MSC_VER >= 1600)
|
||||
# define CV_CXX11 1
|
||||
# endif
|
||||
#else
|
||||
# if CV_CXX_11 == 0
|
||||
# undef CV_CXX_11
|
||||
# if CV_CXX11 == 0
|
||||
# undef CV_CXX11
|
||||
# endif
|
||||
#endif
|
||||
|
||||
@ -373,7 +373,7 @@ Cv64suf;
|
||||
\****************************************************************************************/
|
||||
|
||||
#ifndef CV_CXX_MOVE_SEMANTICS
|
||||
# if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(_MSC_VER) && _MSC_VER >= 1600
|
||||
# if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) || (defined(_MSC_VER) && _MSC_VER >= 1600)
|
||||
# define CV_CXX_MOVE_SEMANTICS 1
|
||||
# elif defined(__clang)
|
||||
# if __has_feature(cxx_rvalue_references)
|
||||
|
@ -981,6 +981,12 @@ public:
|
||||
*/
|
||||
template<typename _Tp> explicit Mat(const std::vector<_Tp>& vec, bool copyData=false);
|
||||
|
||||
#ifdef CV_CXX11
|
||||
/** @overload
|
||||
*/
|
||||
template<typename _Tp> explicit Mat(const std::initializer_list<_Tp> list);
|
||||
#endif
|
||||
|
||||
#ifdef CV_CXX_STD_ARRAY
|
||||
/** @overload
|
||||
*/
|
||||
@ -2170,6 +2176,10 @@ public:
|
||||
explicit Mat_(const Point3_<typename DataType<_Tp>::channel_type>& pt, bool copyData=true);
|
||||
explicit Mat_(const MatCommaInitializer_<_Tp>& commaInitializer);
|
||||
|
||||
#ifdef CV_CXX11
|
||||
Mat_(std::initializer_list<_Tp> values);
|
||||
#endif
|
||||
|
||||
#ifdef CV_CXX_STD_ARRAY
|
||||
template <std::size_t _Nm> explicit Mat_(const std::array<_Tp, _Nm>& arr, bool copyData=false);
|
||||
#endif
|
||||
|
@ -570,6 +570,18 @@ Mat::Mat(const std::vector<_Tp>& vec, bool copyData)
|
||||
Mat((int)vec.size(), 1, DataType<_Tp>::type, (uchar*)&vec[0]).copyTo(*this);
|
||||
}
|
||||
|
||||
#ifdef CV_CXX11
|
||||
template<typename _Tp> inline
|
||||
Mat::Mat(const std::initializer_list<_Tp> list)
|
||||
: flags(MAGIC_VAL | DataType<_Tp>::type | CV_MAT_CONT_FLAG), dims(2), rows((int)list.size()),
|
||||
cols(1), data(0), datastart(0), dataend(0), datalimit(0), allocator(0), u(0), size(&rows), step(0)
|
||||
{
|
||||
if(list.size() == 0)
|
||||
return;
|
||||
Mat((int)list.size(), 1, DataType<_Tp>::type, (uchar*)list.begin()).copyTo(*this);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CV_CXX_STD_ARRAY
|
||||
template<typename _Tp, std::size_t _Nm> inline
|
||||
Mat::Mat(const std::array<_Tp, _Nm>& arr, bool copyData)
|
||||
@ -1573,6 +1585,13 @@ Mat_<_Tp>::Mat_(const std::vector<_Tp>& vec, bool copyData)
|
||||
: Mat(vec, copyData)
|
||||
{}
|
||||
|
||||
#ifdef CV_CXX11
|
||||
template<typename _Tp> inline
|
||||
Mat_<_Tp>::Mat_(std::initializer_list<_Tp> list)
|
||||
: Mat(list)
|
||||
{}
|
||||
#endif
|
||||
|
||||
#ifdef CV_CXX_STD_ARRAY
|
||||
template<typename _Tp> template<std::size_t _Nm> inline
|
||||
Mat_<_Tp>::Mat_(const std::array<_Tp, _Nm>& arr, bool copyData)
|
||||
|
@ -53,6 +53,10 @@
|
||||
#include "opencv2/core/traits.hpp"
|
||||
#include "opencv2/core/saturate.hpp"
|
||||
|
||||
#ifdef CV_CXX11
|
||||
#include <initializer_list>
|
||||
#endif
|
||||
|
||||
namespace cv
|
||||
{
|
||||
|
||||
@ -77,12 +81,21 @@ If you need a more flexible type, use Mat . The elements of the matrix M are acc
|
||||
M(i,j) notation. Most of the common matrix operations (see also @ref MatrixExpressions ) are
|
||||
available. To do an operation on Matx that is not implemented, you can easily convert the matrix to
|
||||
Mat and backwards:
|
||||
@code
|
||||
@code{.cpp}
|
||||
Matx33f m(1, 2, 3,
|
||||
4, 5, 6,
|
||||
7, 8, 9);
|
||||
cout << sum(Mat(m*m.t())) << endl;
|
||||
@endcode
|
||||
@endcode
|
||||
Except of the plain constructor which takes a list of elements, Matx can be initialized from a C-array:
|
||||
@code{.cpp}
|
||||
float values[] = { 1, 2, 3};
|
||||
Matx31f m(values);
|
||||
@endcode
|
||||
In case if C++11 features are avaliable, std::initializer_list can be also used to initizlize Matx:
|
||||
@code{.cpp}
|
||||
Matx31f m = { 1, 2, 3};
|
||||
@endcode
|
||||
*/
|
||||
template<typename _Tp, int m, int n> class Matx
|
||||
{
|
||||
@ -125,6 +138,10 @@ public:
|
||||
_Tp v12, _Tp v13, _Tp v14, _Tp v15); //!< 1x16, 4x4 or 16x1 matrix
|
||||
explicit Matx(const _Tp* vals); //!< initialize from a plain array
|
||||
|
||||
#ifdef CV_CXX11
|
||||
Matx(std::initializer_list<_Tp>); //!< initialize from an initializer list
|
||||
#endif
|
||||
|
||||
static Matx all(_Tp alpha);
|
||||
static Matx zeros();
|
||||
static Matx ones();
|
||||
@ -327,6 +344,10 @@ public:
|
||||
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
|
||||
explicit Vec(const _Tp* values);
|
||||
|
||||
#ifdef CV_CXX11
|
||||
Vec(std::initializer_list<_Tp>);
|
||||
#endif
|
||||
|
||||
Vec(const Vec<_Tp, cn>& v);
|
||||
|
||||
static Vec all(_Tp alpha);
|
||||
@ -616,6 +637,19 @@ Matx<_Tp, m, n>::Matx(const _Tp* values)
|
||||
for( int i = 0; i < channels; i++ ) val[i] = values[i];
|
||||
}
|
||||
|
||||
#ifdef CV_CXX11
|
||||
template<typename _Tp, int m, int n> inline
|
||||
Matx<_Tp, m, n>::Matx(std::initializer_list<_Tp> list)
|
||||
{
|
||||
CV_DbgAssert(list.size() == channels);
|
||||
int i = 0;
|
||||
for(const auto& elem : list)
|
||||
{
|
||||
val[i++] = elem;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename _Tp, int m, int n> inline
|
||||
Matx<_Tp, m, n> Matx<_Tp, m, n>::all(_Tp alpha)
|
||||
{
|
||||
@ -957,6 +991,12 @@ template<typename _Tp, int cn> inline
|
||||
Vec<_Tp, cn>::Vec(const _Tp* values)
|
||||
: Matx<_Tp, cn, 1>(values) {}
|
||||
|
||||
#ifdef CV_CXX11
|
||||
template<typename _Tp, int cn> inline
|
||||
Vec<_Tp, cn>::Vec(std::initializer_list<_Tp> list)
|
||||
: Matx<_Tp, cn, 1>(list) {}
|
||||
#endif
|
||||
|
||||
template<typename _Tp, int cn> inline
|
||||
Vec<_Tp, cn>::Vec(const Vec<_Tp, cn>& m)
|
||||
: Matx<_Tp, cn, 1>(m.val) {}
|
||||
@ -1081,7 +1121,7 @@ Vec<_Tp, cn> normalize(const Vec<_Tp, cn>& v)
|
||||
|
||||
|
||||
|
||||
//////////////////////////////// matx comma initializer //////////////////////////////////
|
||||
//////////////////////////////// vec comma initializer //////////////////////////////////
|
||||
|
||||
|
||||
template<typename _Tp, typename _T2, int cn> static inline
|
||||
|
@ -56,7 +56,7 @@
|
||||
#include "opencv2/core.hpp"
|
||||
#include <ostream>
|
||||
|
||||
#ifdef CV_CXX_11
|
||||
#ifdef CV_CXX11
|
||||
#include <functional>
|
||||
#endif
|
||||
|
||||
@ -482,7 +482,7 @@ public:
|
||||
*/
|
||||
CV_EXPORTS void parallel_for_(const Range& range, const ParallelLoopBody& body, double nstripes=-1.);
|
||||
|
||||
#ifdef CV_CXX_11
|
||||
#ifdef CV_CXX11
|
||||
class ParallelLoopBodyLambdaWrapper : public ParallelLoopBody
|
||||
{
|
||||
private:
|
||||
|
@ -1398,6 +1398,15 @@ TEST(Core_Matx, fromMat_)
|
||||
ASSERT_EQ( cvtest::norm(a, b, NORM_INF), 0.);
|
||||
}
|
||||
|
||||
#ifdef CV_CXX11
|
||||
TEST(Core_Matx, from_initializer_list)
|
||||
{
|
||||
Mat_<double> a = (Mat_<double>(2,2) << 10, 11, 12, 13);
|
||||
Matx22d b = {10, 11, 12, 13};
|
||||
ASSERT_EQ( cvtest::norm(a, b, NORM_INF), 0.);
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(Core_InputArray, empty)
|
||||
{
|
||||
vector<vector<Point> > data;
|
||||
@ -1735,7 +1744,7 @@ TEST(Mat, regression_8680)
|
||||
ASSERT_EQ(mat.channels(), 2);
|
||||
}
|
||||
|
||||
#ifdef CV_CXX_11
|
||||
#ifdef CV_CXX11
|
||||
|
||||
TEST(Mat_, range_based_for)
|
||||
{
|
||||
@ -1751,4 +1760,21 @@ TEST(Mat_, range_based_for)
|
||||
ASSERT_DOUBLE_EQ(norm(img, ref), 0.);
|
||||
}
|
||||
|
||||
TEST(Mat, from_initializer_list)
|
||||
{
|
||||
Mat A({1.f, 2.f, 3.f});
|
||||
Mat_<float> B(3, 1); B << 1, 2, 3;
|
||||
|
||||
ASSERT_EQ(A.type(), CV_32F);
|
||||
ASSERT_DOUBLE_EQ(norm(A, B, NORM_INF), 0.);
|
||||
}
|
||||
|
||||
TEST(Mat_, from_initializer_list)
|
||||
{
|
||||
Mat_<float> A = {1, 2, 3};
|
||||
Mat_<float> B(3, 1); B << 1, 2, 3;
|
||||
|
||||
ASSERT_DOUBLE_EQ(norm(A, B, NORM_INF), 0.);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -102,7 +102,7 @@ int main()
|
||||
|
||||
double t1 = (double) getTickCount();
|
||||
|
||||
#ifdef CV_CXX_11
|
||||
#ifdef CV_CXX11
|
||||
|
||||
//! [mandelbrot-parallel-call-cxx11]
|
||||
parallel_for_(Range(0, mandelbrotImg.rows*mandelbrotImg.cols), [&](const Range& range){
|
||||
|
@ -58,7 +58,13 @@ int main(int,char**)
|
||||
Mat C = (Mat_<double>(3,3) << 0, -1, 0, -1, 5, -1, 0, -1, 0);
|
||||
cout << "C = " << endl << " " << C << endl << endl;
|
||||
//! [comma]
|
||||
|
||||
// do the same with initializer_list
|
||||
#ifdef CV_CXX11
|
||||
//! [list]
|
||||
C = (Mat_<double>({0, -1, 0, -1, 5, -1, 0, -1, 0})).reshape(3);
|
||||
cout << "C = " << endl << " " << C << endl << endl;
|
||||
//! [list]
|
||||
#endif
|
||||
//! [clone]
|
||||
Mat RowClone = C.row(1).clone();
|
||||
cout << "RowClone = " << endl << " " << RowClone << endl << endl;
|
||||
|
Loading…
Reference in New Issue
Block a user