mirror of
https://github.com/opencv/opencv.git
synced 2025-06-06 00:43:52 +08:00
Added N-dim submat selection with vectors
Currently, to select a submatrix of a N-dimensional matrix, it requires two lines of code while only one line of code is required if using a 2D array. I added functionality to be able to select an N-dim submatrix using a vector list instead of a Range pointer. This allows initializer lists to be used for a one-line selection.
This commit is contained in:
parent
c038d1be60
commit
eb04b2bfa9
@ -925,6 +925,16 @@ public:
|
||||
*/
|
||||
Mat(const Mat& m, const Range* ranges);
|
||||
|
||||
/** @overload
|
||||
@param m Array that (as a whole or partly) is assigned to the constructed matrix. No data is copied
|
||||
by these constructors. Instead, the header pointing to m data or its sub-array is constructed and
|
||||
associated with it. The reference counter, if any, is incremented. So, when you modify the matrix
|
||||
formed using such a constructor, you also modify the corresponding elements of m . If you want to
|
||||
have an independent copy of the sub-array, use Mat::clone() .
|
||||
@param ranges Array of selected ranges of m along each dimensionality.
|
||||
*/
|
||||
Mat(const Mat& m, const std::vector<Range>& ranges);
|
||||
|
||||
/** @overload
|
||||
@param vec STL vector whose elements form the matrix. The matrix has a single column and the number
|
||||
of rows equal to the number of vector elements. Type of the matrix matches the type of vector
|
||||
@ -1516,6 +1526,11 @@ public:
|
||||
*/
|
||||
Mat operator()( const Range* ranges ) const;
|
||||
|
||||
/** @overload
|
||||
@param ranges Array of selected ranges along each array dimension.
|
||||
*/
|
||||
Mat operator()(const std::vector<Range>& ranges) const;
|
||||
|
||||
// //! converts header to CvMat; no data is copied
|
||||
// operator CvMat() const;
|
||||
// //! converts header to CvMatND; no data is copied
|
||||
@ -2054,6 +2069,8 @@ public:
|
||||
Mat_(const Mat_& m, const Rect& roi);
|
||||
//! selects a submatrix, n-dim version
|
||||
Mat_(const Mat_& m, const Range* ranges);
|
||||
//! selects a submatrix, n-dim version
|
||||
Mat_(const Mat_& m, const std::vector<Range>& ranges);
|
||||
//! from a matrix expression
|
||||
explicit Mat_(const MatExpr& e);
|
||||
//! makes a matrix out of Vec, std::vector, Point_ or Point3_. The matrix will have a single column
|
||||
@ -2123,6 +2140,7 @@ public:
|
||||
Mat_ operator()( const Range& rowRange, const Range& colRange ) const;
|
||||
Mat_ operator()( const Rect& roi ) const;
|
||||
Mat_ operator()( const Range* ranges ) const;
|
||||
Mat_ operator()(const std::vector<Range>& ranges) const;
|
||||
|
||||
//! more convenient forms of row and element access operators
|
||||
_Tp* operator [](int y);
|
||||
@ -2227,6 +2245,7 @@ public:
|
||||
UMat(const UMat& m, const Range& rowRange, const Range& colRange=Range::all());
|
||||
UMat(const UMat& m, const Rect& roi);
|
||||
UMat(const UMat& m, const Range* ranges);
|
||||
UMat(const UMat& m, const std::vector<Range>& ranges);
|
||||
//! builds matrix from std::vector with or without copying the data
|
||||
template<typename _Tp> explicit UMat(const std::vector<_Tp>& vec, bool copyData=false);
|
||||
//! builds matrix from cv::Vec; the data is copied by default
|
||||
@ -2333,6 +2352,7 @@ public:
|
||||
UMat operator()( Range rowRange, Range colRange ) const;
|
||||
UMat operator()( const Rect& roi ) const;
|
||||
UMat operator()( const Range* ranges ) const;
|
||||
UMat operator()(const std::vector<Range>& ranges) const;
|
||||
|
||||
//! returns true iff the matrix data is continuous
|
||||
// (i.e. when there are no gaps between successive rows).
|
||||
|
@ -736,6 +736,12 @@ Mat Mat::operator()(const Range* ranges) const
|
||||
return Mat(*this, ranges);
|
||||
}
|
||||
|
||||
inline
|
||||
Mat Mat::operator()(const std::vector<Range>& ranges) const
|
||||
{
|
||||
return Mat(*this, ranges);
|
||||
}
|
||||
|
||||
inline
|
||||
bool Mat::isContinuous() const
|
||||
{
|
||||
@ -1383,6 +1389,11 @@ Mat_<_Tp>::Mat_(const Mat_<_Tp>& m, const Range* ranges)
|
||||
: Mat(m, ranges)
|
||||
{}
|
||||
|
||||
template<typename _Tp> inline
|
||||
Mat_<_Tp>::Mat_(const Mat_<_Tp>& m, const std::vector<Range>& ranges)
|
||||
: Mat(m, ranges)
|
||||
{}
|
||||
|
||||
template<typename _Tp> inline
|
||||
Mat_<_Tp>::Mat_(const Mat& m)
|
||||
: Mat()
|
||||
@ -1614,6 +1625,12 @@ Mat_<_Tp> Mat_<_Tp>::operator()( const Range* ranges ) const
|
||||
return Mat_<_Tp>(*this, ranges);
|
||||
}
|
||||
|
||||
template<typename _Tp> inline
|
||||
Mat_<_Tp> Mat_<_Tp>::operator()(const std::vector<Range>& ranges) const
|
||||
{
|
||||
return Mat_<_Tp>(*this, ranges);
|
||||
}
|
||||
|
||||
template<typename _Tp> inline
|
||||
_Tp* Mat_<_Tp>::operator [](int y)
|
||||
{
|
||||
@ -3540,6 +3557,12 @@ UMat UMat::operator()(const Range* ranges) const
|
||||
return UMat(*this, ranges);
|
||||
}
|
||||
|
||||
inline
|
||||
UMat UMat::operator()(const std::vector<Range>& ranges) const
|
||||
{
|
||||
return UMat(*this, ranges);
|
||||
}
|
||||
|
||||
inline
|
||||
bool UMat::isContinuous() const
|
||||
{
|
||||
|
@ -583,6 +583,31 @@ Mat::Mat(const Mat& m, const Range* ranges)
|
||||
updateContinuityFlag(*this);
|
||||
}
|
||||
|
||||
Mat::Mat(const Mat& m, const std::vector<Range>& ranges)
|
||||
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
|
||||
datalimit(0), allocator(0), u(0), size(&rows)
|
||||
{
|
||||
int d = m.dims;
|
||||
|
||||
CV_Assert((int)ranges.size() == d);
|
||||
for (int i = 0; i < d; i++)
|
||||
{
|
||||
Range r = ranges[i];
|
||||
CV_Assert(r == Range::all() || (0 <= r.start && r.start < r.end && r.end <= m.size[i]));
|
||||
}
|
||||
*this = m;
|
||||
for (int i = 0; i < d; i++)
|
||||
{
|
||||
Range r = ranges[i];
|
||||
if (r != Range::all() && r != Range(0, size.p[i]))
|
||||
{
|
||||
size.p[i] = r.end - r.start;
|
||||
data += r.start*step.p[i];
|
||||
flags |= SUBMATRIX_FLAG;
|
||||
}
|
||||
}
|
||||
updateContinuityFlag(*this);
|
||||
}
|
||||
|
||||
static Mat cvMatNDToMat(const CvMatND* m, bool copyData)
|
||||
{
|
||||
|
@ -512,6 +512,31 @@ UMat::UMat(const UMat& m, const Range* ranges)
|
||||
updateContinuityFlag(*this);
|
||||
}
|
||||
|
||||
UMat::UMat(const UMat& m, const std::vector<Range>& ranges)
|
||||
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(USAGE_DEFAULT), u(0), offset(0), size(&rows)
|
||||
{
|
||||
int i, d = m.dims;
|
||||
|
||||
CV_Assert((int)ranges.size() == d);
|
||||
for (i = 0; i < d; i++)
|
||||
{
|
||||
Range r = ranges[i];
|
||||
CV_Assert(r == Range::all() || (0 <= r.start && r.start < r.end && r.end <= m.size[i]));
|
||||
}
|
||||
*this = m;
|
||||
for (i = 0; i < d; i++)
|
||||
{
|
||||
Range r = ranges[i];
|
||||
if (r != Range::all() && r != Range(0, size.p[i]))
|
||||
{
|
||||
size.p[i] = r.end - r.start;
|
||||
offset += r.start*step.p[i];
|
||||
flags |= SUBMATRIX_FLAG;
|
||||
}
|
||||
}
|
||||
updateContinuityFlag(*this);
|
||||
}
|
||||
|
||||
UMat UMat::diag(int d) const
|
||||
{
|
||||
CV_Assert( dims <= 2 );
|
||||
|
@ -1546,3 +1546,28 @@ TEST(Mat, regression_5917_clone_empty)
|
||||
|
||||
ASSERT_NO_THROW(cloned = source.clone());
|
||||
}
|
||||
|
||||
TEST(Mat, regression_7873_mat_vector_initialize)
|
||||
{
|
||||
std::vector<int> dims;
|
||||
dims.push_back(12);
|
||||
dims.push_back(3);
|
||||
dims.push_back(2);
|
||||
Mat multi_mat(dims, CV_32FC1, cv::Scalar(0));
|
||||
|
||||
ASSERT_EQ(3, multi_mat.dims);
|
||||
ASSERT_EQ(12, multi_mat.size[0]);
|
||||
ASSERT_EQ(3, multi_mat.size[1]);
|
||||
ASSERT_EQ(2, multi_mat.size[2]);
|
||||
|
||||
std::vector<Range> ranges;
|
||||
ranges.push_back(Range(1, 2));
|
||||
ranges.push_back(Range::all());
|
||||
ranges.push_back(Range::all());
|
||||
Mat sub_mat = multi_mat(ranges);
|
||||
|
||||
ASSERT_EQ(3, sub_mat.dims);
|
||||
ASSERT_EQ(1, sub_mat.size[0]);
|
||||
ASSERT_EQ(3, sub_mat.size[1]);
|
||||
ASSERT_EQ(2, sub_mat.size[2]);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user