Finalize cv::Mat transition

This commit is contained in:
Andrey Kamaev 2013-03-30 19:03:55 +04:00
parent 71e43852ce
commit c886afb502
8 changed files with 3302 additions and 2530 deletions

View File

@ -404,21 +404,21 @@ protected:
// Input should be a vector of n 2D points or a Nx2 matrix
cv::Mat cv::findEssentialMat( InputArray _points1, InputArray _points2, double focal, Point2d pp,
int method, double prob, double threshold, OutputArray _mask)
int method, double prob, double threshold, OutputArray _mask)
{
Mat points1, points2;
_points1.getMat().convertTo(points1, CV_64F);
_points2.getMat().convertTo(points2, CV_64F);
Mat points1, points2;
_points1.getMat().convertTo(points1, CV_64F);
_points2.getMat().convertTo(points2, CV_64F);
int npoints = points1.checkVector(2);
int npoints = points1.checkVector(2);
CV_Assert( npoints >= 5 && points2.checkVector(2) == npoints &&
points1.type() == points2.type());
points1.type() == points2.type());
if( points1.channels() > 1 )
{
points1 = points1.reshape(1, npoints);
points2 = points2.reshape(1, npoints);
}
if( points1.channels() > 1 )
{
points1 = points1.reshape(1, npoints);
points2 = points2.reshape(1, npoints);
}
double ifocal = focal != 0 ? 1./focal : 1.;
for( int i = 0; i < npoints; i++ )
@ -429,11 +429,11 @@ cv::Mat cv::findEssentialMat( InputArray _points1, InputArray _points2, double f
points2.at<double>(i, 1) = (points2.at<double>(i, 1) - pp.y)*ifocal;
}
// Reshape data to fit opencv ransac function
points1 = points1.reshape(2, npoints);
points2 = points2.reshape(2, npoints);
// Reshape data to fit opencv ransac function
points1 = points1.reshape(2, npoints);
points2 = points2.reshape(2, npoints);
threshold /= focal;
threshold /= focal;
Mat E;
if( method == CV_RANSAC )
@ -441,165 +441,165 @@ cv::Mat cv::findEssentialMat( InputArray _points1, InputArray _points2, double f
else
createLMeDSPointSetRegistrator(new EMEstimatorCallback, 5, prob)->run(points1, points2, E, _mask);
return E;
return E;
}
int cv::recoverPose( InputArray E, InputArray _points1, InputArray _points2, OutputArray _R,
OutputArray _t, double focal, Point2d pp, InputOutputArray _mask)
{
Mat points1, points2;
_points1.getMat().copyTo(points1);
_points2.getMat().copyTo(points2);
Mat points1, points2;
_points1.getMat().copyTo(points1);
_points2.getMat().copyTo(points2);
int npoints = points1.checkVector(2);
int npoints = points1.checkVector(2);
CV_Assert( npoints >= 0 && points2.checkVector(2) == npoints &&
points1.type() == points2.type());
points1.type() == points2.type());
if (points1.channels() > 1)
{
points1 = points1.reshape(1, npoints);
points2 = points2.reshape(1, npoints);
}
points1.convertTo(points1, CV_64F);
points2.convertTo(points2, CV_64F);
if (points1.channels() > 1)
{
points1 = points1.reshape(1, npoints);
points2 = points2.reshape(1, npoints);
}
points1.convertTo(points1, CV_64F);
points2.convertTo(points2, CV_64F);
points1.col(0) = (points1.col(0) - pp.x) / focal;
points2.col(0) = (points2.col(0) - pp.x) / focal;
points1.col(1) = (points1.col(1) - pp.y) / focal;
points2.col(1) = (points2.col(1) - pp.y) / focal;
points1.col(0) = (points1.col(0) - pp.x) / focal;
points2.col(0) = (points2.col(0) - pp.x) / focal;
points1.col(1) = (points1.col(1) - pp.y) / focal;
points2.col(1) = (points2.col(1) - pp.y) / focal;
points1 = points1.t();
points2 = points2.t();
points1 = points1.t();
points2 = points2.t();
Mat R1, R2, t;
decomposeEssentialMat(E, R1, R2, t);
Mat P0 = Mat::eye(3, 4, R1.type());
Mat P1(3, 4, R1.type()), P2(3, 4, R1.type()), P3(3, 4, R1.type()), P4(3, 4, R1.type());
P1(Range::all(), Range(0, 3)) = R1 * 1.0; P1.col(3) = t * 1.0;
P2(Range::all(), Range(0, 3)) = R2 * 1.0; P2.col(3) = t * 1.0;
P3(Range::all(), Range(0, 3)) = R1 * 1.0; P3.col(3) = -t * 1.0;
P4(Range::all(), Range(0, 3)) = R2 * 1.0; P4.col(3) = -t * 1.0;
Mat R1, R2, t;
decomposeEssentialMat(E, R1, R2, t);
Mat P0 = Mat::eye(3, 4, R1.type());
Mat P1(3, 4, R1.type()), P2(3, 4, R1.type()), P3(3, 4, R1.type()), P4(3, 4, R1.type());
P1(Range::all(), Range(0, 3)) = R1 * 1.0; P1.col(3) = t * 1.0;
P2(Range::all(), Range(0, 3)) = R2 * 1.0; P2.col(3) = t * 1.0;
P3(Range::all(), Range(0, 3)) = R1 * 1.0; P3.col(3) = -t * 1.0;
P4(Range::all(), Range(0, 3)) = R2 * 1.0; P4.col(3) = -t * 1.0;
// Do the cheirality check.
// Notice here a threshold dist is used to filter
// out far away points (i.e. infinite points) since
// there depth may vary between postive and negtive.
double dist = 50.0;
Mat Q;
triangulatePoints(P0, P1, points1, points2, Q);
Mat mask1 = Q.row(2).mul(Q.row(3)) > 0;
Q.row(0) /= Q.row(3);
Q.row(1) /= Q.row(3);
Q.row(2) /= Q.row(3);
Q.row(3) /= Q.row(3);
mask1 = (Q.row(2) < dist) & mask1;
Q = P1 * Q;
mask1 = (Q.row(2) > 0) & mask1;
mask1 = (Q.row(2) < dist) & mask1;
// Do the cheirality check.
// Notice here a threshold dist is used to filter
// out far away points (i.e. infinite points) since
// there depth may vary between postive and negtive.
double dist = 50.0;
Mat Q;
triangulatePoints(P0, P1, points1, points2, Q);
Mat mask1 = Q.row(2).mul(Q.row(3)) > 0;
Q.row(0) /= Q.row(3);
Q.row(1) /= Q.row(3);
Q.row(2) /= Q.row(3);
Q.row(3) /= Q.row(3);
mask1 = (Q.row(2) < dist) & mask1;
Q = P1 * Q;
mask1 = (Q.row(2) > 0) & mask1;
mask1 = (Q.row(2) < dist) & mask1;
triangulatePoints(P0, P2, points1, points2, Q);
Mat mask2 = Q.row(2).mul(Q.row(3)) > 0;
Q.row(0) /= Q.row(3);
Q.row(1) /= Q.row(3);
Q.row(2) /= Q.row(3);
Q.row(3) /= Q.row(3);
mask2 = (Q.row(2) < dist) & mask2;
Q = P2 * Q;
mask2 = (Q.row(2) > 0) & mask2;
mask2 = (Q.row(2) < dist) & mask2;
triangulatePoints(P0, P2, points1, points2, Q);
Mat mask2 = Q.row(2).mul(Q.row(3)) > 0;
Q.row(0) /= Q.row(3);
Q.row(1) /= Q.row(3);
Q.row(2) /= Q.row(3);
Q.row(3) /= Q.row(3);
mask2 = (Q.row(2) < dist) & mask2;
Q = P2 * Q;
mask2 = (Q.row(2) > 0) & mask2;
mask2 = (Q.row(2) < dist) & mask2;
triangulatePoints(P0, P3, points1, points2, Q);
Mat mask3 = Q.row(2).mul(Q.row(3)) > 0;
Q.row(0) /= Q.row(3);
Q.row(1) /= Q.row(3);
Q.row(2) /= Q.row(3);
Q.row(3) /= Q.row(3);
mask3 = (Q.row(2) < dist) & mask3;
Q = P3 * Q;
mask3 = (Q.row(2) > 0) & mask3;
mask3 = (Q.row(2) < dist) & mask3;
triangulatePoints(P0, P3, points1, points2, Q);
Mat mask3 = Q.row(2).mul(Q.row(3)) > 0;
Q.row(0) /= Q.row(3);
Q.row(1) /= Q.row(3);
Q.row(2) /= Q.row(3);
Q.row(3) /= Q.row(3);
mask3 = (Q.row(2) < dist) & mask3;
Q = P3 * Q;
mask3 = (Q.row(2) > 0) & mask3;
mask3 = (Q.row(2) < dist) & mask3;
triangulatePoints(P0, P4, points1, points2, Q);
Mat mask4 = Q.row(2).mul(Q.row(3)) > 0;
Q.row(0) /= Q.row(3);
Q.row(1) /= Q.row(3);
Q.row(2) /= Q.row(3);
Q.row(3) /= Q.row(3);
mask4 = (Q.row(2) < dist) & mask4;
Q = P4 * Q;
mask4 = (Q.row(2) > 0) & mask4;
mask4 = (Q.row(2) < dist) & mask4;
triangulatePoints(P0, P4, points1, points2, Q);
Mat mask4 = Q.row(2).mul(Q.row(3)) > 0;
Q.row(0) /= Q.row(3);
Q.row(1) /= Q.row(3);
Q.row(2) /= Q.row(3);
Q.row(3) /= Q.row(3);
mask4 = (Q.row(2) < dist) & mask4;
Q = P4 * Q;
mask4 = (Q.row(2) > 0) & mask4;
mask4 = (Q.row(2) < dist) & mask4;
// If _mask is given, then use it to filter outliers.
if (_mask.needed())
{
_mask.create(1, npoints, CV_8U, -1, true);
Mat mask = _mask.getMat();
bitwise_and(mask, mask1, mask1);
bitwise_and(mask, mask2, mask2);
bitwise_and(mask, mask3, mask3);
bitwise_and(mask, mask4, mask4);
}
// If _mask is given, then use it to filter outliers.
if (_mask.needed())
{
_mask.create(1, npoints, CV_8U, -1, true);
Mat mask = _mask.getMat();
bitwise_and(mask, mask1, mask1);
bitwise_and(mask, mask2, mask2);
bitwise_and(mask, mask3, mask3);
bitwise_and(mask, mask4, mask4);
}
CV_Assert(_R.needed() && _t.needed());
_R.create(3, 3, R1.type());
_t.create(3, 1, t.type());
int good1 = countNonZero(mask1);
int good2 = countNonZero(mask2);
int good3 = countNonZero(mask3);
int good4 = countNonZero(mask4);
if (good1 >= good2 && good1 >= good3 && good1 >= good4)
{
int good1 = countNonZero(mask1);
int good2 = countNonZero(mask2);
int good3 = countNonZero(mask3);
int good4 = countNonZero(mask4);
if (good1 >= good2 && good1 >= good3 && good1 >= good4)
{
R1.copyTo(_R);
t.copyTo(_t);
if (_mask.needed()) mask1.copyTo(_mask);
return good1;
}
else if (good2 >= good1 && good2 >= good3 && good2 >= good4)
{
if (_mask.needed()) mask1.copyTo(_mask);
return good1;
}
else if (good2 >= good1 && good2 >= good3 && good2 >= good4)
{
R2.copyTo(_R);
t.copyTo(_t);
if (_mask.needed()) mask2.copyTo(_mask);
return good2;
}
else if (good3 >= good1 && good3 >= good2 && good3 >= good4)
{
if (_mask.needed()) mask2.copyTo(_mask);
return good2;
}
else if (good3 >= good1 && good3 >= good2 && good3 >= good4)
{
t = -t;
R1.copyTo(_R);
t.copyTo(_t);
if (_mask.needed()) mask3.copyTo(_mask);
return good3;
}
else
{
if (_mask.needed()) mask3.copyTo(_mask);
return good3;
}
else
{
t = -t;
R2.copyTo(_R);
t.copyTo(_t);
if (_mask.needed()) mask4.copyTo(_mask);
return good4;
}
if (_mask.needed()) mask4.copyTo(_mask);
return good4;
}
}
void cv::decomposeEssentialMat( InputArray _E, OutputArray _R1, OutputArray _R2, OutputArray _t )
{
Mat E = _E.getMat().reshape(1, 3);
CV_Assert(E.cols == 3 && E.rows == 3);
CV_Assert(E.cols == 3 && E.rows == 3);
Mat D, U, Vt;
SVD::compute(E, D, U, Vt);
SVD::compute(E, D, U, Vt);
if (determinant(U) < 0) U *= -1.;
if (determinant(Vt) < 0) Vt *= -1.;
if (determinant(Vt) < 0) Vt *= -1.;
Mat W = (Mat_<double>(3, 3) << 0, 1, 0, -1, 0, 0, 0, 0, 1);
W.convertTo(W, E.type());
W.convertTo(W, E.type());
Mat R1, R2, t;
R1 = U * W * Vt;
R2 = U * W.t() * Vt;
t = U.col(2) * 1.0;
R2 = U * W.t() * Vt;
t = U.col(2) * 1.0;
R1.copyTo(_R1);
R2.copyTo(_R2);

File diff suppressed because it is too large Load Diff

View File

@ -279,11 +279,22 @@ CV_EXPORTS int LU(float* A, size_t astep, int m, float* b, size_t bstep, int n);
CV_EXPORTS int LU(double* A, size_t astep, int m, double* b, size_t bstep, int n);
CV_EXPORTS bool Cholesky(float* A, size_t astep, int m, float* b, size_t bstep, int n);
CV_EXPORTS bool Cholesky(double* A, size_t astep, int m, double* b, size_t bstep, int n);
CV_EXPORTS float normL2Sqr_(const float* a, const float* b, int n);
CV_EXPORTS float normL1_(const float* a, const float* b, int n);
CV_EXPORTS int normL1_(const uchar* a, const uchar* b, int n);
CV_EXPORTS int normHamming(const uchar* a, const uchar* b, int n);
CV_EXPORTS int normHamming(const uchar* a, const uchar* b, int n, int cellSize);
CV_EXPORTS float normL1_(const float* a, const float* b, int n);
CV_EXPORTS float normL2Sqr_(const float* a, const float* b, int n);
CV_EXPORTS void exp(const float* src, float* dst, int n);
CV_EXPORTS void log(const float* src, float* dst, int n);
CV_EXPORTS void fastAtan2(const float* y, const float* x, float* dst, int n, bool angleInDegrees);
CV_EXPORTS void magnitude(const float* x, const float* y, float* dst, int n);
//! computes cube root of the argument
CV_EXPORTS_W float cubeRoot(float val);
//! computes the angle in degrees (0..360) of the vector (x,y)
CV_EXPORTS_W float fastAtan2(float y, float x);
@ -442,11 +453,11 @@ class CV_EXPORTS KeyPoint;
class CV_EXPORTS DMatch;
class CV_EXPORTS Mat;
class CV_EXPORTS MatExpr;
class CV_EXPORTS SparseMat;
typedef Mat MatND;
class CV_EXPORTS MatExpr;
template<typename _Tp> class CV_EXPORTS Mat_;
template<typename _Tp> class CV_EXPORTS SparseMat_;
@ -470,8 +481,6 @@ namespace gpu
class CV_EXPORTS GpuMat;
}
} // cv
#endif //__OPENCV_CORE_BASE_HPP__

View File

@ -91,7 +91,6 @@ public:
template<typename _Tp> _InputArray(const std::vector<Mat_<_Tp> >& vec);
template<typename _Tp> _InputArray(const _Tp* vec, int n);
template<typename _Tp, int m, int n> _InputArray(const Matx<_Tp, m, n>& matx);
_InputArray(const Scalar& s);
_InputArray(const double& val);
_InputArray(const gpu::GpuMat& d_mat);
_InputArray(const ogl::Buffer& buf);
@ -780,7 +779,6 @@ public:
MStep step;
protected:
void initEmpty();
};
@ -1345,7 +1343,7 @@ public:
///////////////////////////////// Mat_<_Tp> ////////////////////////////////////
///////////////////////////////// SparseMat_<_Tp> ////////////////////////////////////
/*!
The Template Sparse Matrix class derived from cv::SparseMat
@ -1427,6 +1425,598 @@ public:
SparseMatConstIterator_<_Tp> end() const;
};
////////////////////////////////// MatConstIterator //////////////////////////////////
class CV_EXPORTS MatConstIterator
{
public:
typedef uchar* value_type;
typedef ptrdiff_t difference_type;
typedef const uchar** pointer;
typedef uchar* reference;
#ifndef OPENCV_NOSTL
typedef std::random_access_iterator_tag iterator_category;
#endif
//! default constructor
MatConstIterator();
//! constructor that sets the iterator to the beginning of the matrix
MatConstIterator(const Mat* _m);
//! constructor that sets the iterator to the specified element of the matrix
MatConstIterator(const Mat* _m, int _row, int _col=0);
//! constructor that sets the iterator to the specified element of the matrix
MatConstIterator(const Mat* _m, Point _pt);
//! constructor that sets the iterator to the specified element of the matrix
MatConstIterator(const Mat* _m, const int* _idx);
//! copy constructor
MatConstIterator(const MatConstIterator& it);
//! copy operator
MatConstIterator& operator = (const MatConstIterator& it);
//! returns the current matrix element
uchar* operator *() const;
//! returns the i-th matrix element, relative to the current
uchar* operator [](ptrdiff_t i) const;
//! shifts the iterator forward by the specified number of elements
MatConstIterator& operator += (ptrdiff_t ofs);
//! shifts the iterator backward by the specified number of elements
MatConstIterator& operator -= (ptrdiff_t ofs);
//! decrements the iterator
MatConstIterator& operator --();
//! decrements the iterator
MatConstIterator operator --(int);
//! increments the iterator
MatConstIterator& operator ++();
//! increments the iterator
MatConstIterator operator ++(int);
//! returns the current iterator position
Point pos() const;
//! returns the current iterator position
void pos(int* _idx) const;
ptrdiff_t lpos() const;
void seek(ptrdiff_t ofs, bool relative = false);
void seek(const int* _idx, bool relative = false);
const Mat* m;
size_t elemSize;
uchar* ptr;
uchar* sliceStart;
uchar* sliceEnd;
};
////////////////////////////////// MatConstIterator_ /////////////////////////////////
/*!
Matrix read-only iterator
*/
template<typename _Tp>
class MatConstIterator_ : public MatConstIterator
{
public:
typedef _Tp value_type;
typedef ptrdiff_t difference_type;
typedef const _Tp* pointer;
typedef const _Tp& reference;
#ifndef OPENCV_NOSTL
typedef std::random_access_iterator_tag iterator_category;
#endif
//! default constructor
MatConstIterator_();
//! constructor that sets the iterator to the beginning of the matrix
MatConstIterator_(const Mat_<_Tp>* _m);
//! constructor that sets the iterator to the specified element of the matrix
MatConstIterator_(const Mat_<_Tp>* _m, int _row, int _col=0);
//! constructor that sets the iterator to the specified element of the matrix
MatConstIterator_(const Mat_<_Tp>* _m, Point _pt);
//! constructor that sets the iterator to the specified element of the matrix
MatConstIterator_(const Mat_<_Tp>* _m, const int* _idx);
//! copy constructor
MatConstIterator_(const MatConstIterator_& it);
//! copy operator
MatConstIterator_& operator = (const MatConstIterator_& it);
//! returns the current matrix element
_Tp operator *() const;
//! returns the i-th matrix element, relative to the current
_Tp operator [](ptrdiff_t i) const;
//! shifts the iterator forward by the specified number of elements
MatConstIterator_& operator += (ptrdiff_t ofs);
//! shifts the iterator backward by the specified number of elements
MatConstIterator_& operator -= (ptrdiff_t ofs);
//! decrements the iterator
MatConstIterator_& operator --();
//! decrements the iterator
MatConstIterator_ operator --(int);
//! increments the iterator
MatConstIterator_& operator ++();
//! increments the iterator
MatConstIterator_ operator ++(int);
//! returns the current iterator position
Point pos() const;
};
//////////////////////////////////// MatIterator_ ////////////////////////////////////
/*!
Matrix read-write iterator
*/
template<typename _Tp>
class MatIterator_ : public MatConstIterator_<_Tp>
{
public:
typedef _Tp* pointer;
typedef _Tp& reference;
#ifndef OPENCV_NOSTL
typedef std::random_access_iterator_tag iterator_category;
#endif
//! the default constructor
MatIterator_();
//! constructor that sets the iterator to the beginning of the matrix
MatIterator_(Mat_<_Tp>* _m);
//! constructor that sets the iterator to the specified element of the matrix
MatIterator_(Mat_<_Tp>* _m, int _row, int _col=0);
//! constructor that sets the iterator to the specified element of the matrix
MatIterator_(const Mat_<_Tp>* _m, Point _pt);
//! constructor that sets the iterator to the specified element of the matrix
MatIterator_(const Mat_<_Tp>* _m, const int* _idx);
//! copy constructor
MatIterator_(const MatIterator_& it);
//! copy operator
MatIterator_& operator = (const MatIterator_<_Tp>& it );
//! returns the current matrix element
_Tp& operator *() const;
//! returns the i-th matrix element, relative to the current
_Tp& operator [](ptrdiff_t i) const;
//! shifts the iterator forward by the specified number of elements
MatIterator_& operator += (ptrdiff_t ofs);
//! shifts the iterator backward by the specified number of elements
MatIterator_& operator -= (ptrdiff_t ofs);
//! decrements the iterator
MatIterator_& operator --();
//! decrements the iterator
MatIterator_ operator --(int);
//! increments the iterator
MatIterator_& operator ++();
//! increments the iterator
MatIterator_ operator ++(int);
};
/////////////////////////////// SparseMatConstIterator ///////////////////////////////
/*!
Read-Only Sparse Matrix Iterator.
Here is how to use the iterator to compute the sum of floating-point sparse matrix elements:
\code
SparseMatConstIterator it = m.begin(), it_end = m.end();
double s = 0;
CV_Assert( m.type() == CV_32F );
for( ; it != it_end; ++it )
s += it.value<float>();
\endcode
*/
class CV_EXPORTS SparseMatConstIterator
{
public:
//! the default constructor
SparseMatConstIterator();
//! the full constructor setting the iterator to the first sparse matrix element
SparseMatConstIterator(const SparseMat* _m);
//! the copy constructor
SparseMatConstIterator(const SparseMatConstIterator& it);
//! the assignment operator
SparseMatConstIterator& operator = (const SparseMatConstIterator& it);
//! template method returning the current matrix element
template<typename _Tp> const _Tp& value() const;
//! returns the current node of the sparse matrix. it.node->idx is the current element index
const SparseMat::Node* node() const;
//! moves iterator to the previous element
SparseMatConstIterator& operator --();
//! moves iterator to the previous element
SparseMatConstIterator operator --(int);
//! moves iterator to the next element
SparseMatConstIterator& operator ++();
//! moves iterator to the next element
SparseMatConstIterator operator ++(int);
//! moves iterator to the element after the last element
void seekEnd();
const SparseMat* m;
size_t hashidx;
uchar* ptr;
};
////////////////////////////////// SparseMatIterator /////////////////////////////////
/*!
Read-write Sparse Matrix Iterator
The class is similar to cv::SparseMatConstIterator,
but can be used for in-place modification of the matrix elements.
*/
class CV_EXPORTS SparseMatIterator : public SparseMatConstIterator
{
public:
//! the default constructor
SparseMatIterator();
//! the full constructor setting the iterator to the first sparse matrix element
SparseMatIterator(SparseMat* _m);
//! the full constructor setting the iterator to the specified sparse matrix element
SparseMatIterator(SparseMat* _m, const int* idx);
//! the copy constructor
SparseMatIterator(const SparseMatIterator& it);
//! the assignment operator
SparseMatIterator& operator = (const SparseMatIterator& it);
//! returns read-write reference to the current sparse matrix element
template<typename _Tp> _Tp& value() const;
//! returns pointer to the current sparse matrix node. it.node->idx is the index of the current element (do not modify it!)
SparseMat::Node* node() const;
//! moves iterator to the next element
SparseMatIterator& operator ++();
//! moves iterator to the next element
SparseMatIterator operator ++(int);
};
/////////////////////////////// SparseMatConstIterator_ //////////////////////////////
/*!
Template Read-Only Sparse Matrix Iterator Class.
This is the derived from SparseMatConstIterator class that
introduces more convenient operator *() for accessing the current element.
*/
template<typename _Tp> class SparseMatConstIterator_ : public SparseMatConstIterator
{
public:
#ifndef OPENCV_NOSTL
typedef std::forward_iterator_tag iterator_category;
#endif
//! the default constructor
SparseMatConstIterator_();
//! the full constructor setting the iterator to the first sparse matrix element
SparseMatConstIterator_(const SparseMat_<_Tp>* _m);
//! the copy constructor
SparseMatConstIterator_(const SparseMatConstIterator_& it);
//! the assignment operator
SparseMatConstIterator_& operator = (const SparseMatConstIterator_& it);
//! the element access operator
const _Tp& operator *() const;
//! moves iterator to the next element
SparseMatConstIterator_& operator ++();
//! moves iterator to the next element
SparseMatConstIterator_ operator ++(int);
};
///////////////////////////////// SparseMatIterator_ /////////////////////////////////
/*!
Template Read-Write Sparse Matrix Iterator Class.
This is the derived from cv::SparseMatConstIterator_ class that
introduces more convenient operator *() for accessing the current element.
*/
template<typename _Tp> class CV_EXPORTS SparseMatIterator_ : public SparseMatConstIterator_<_Tp>
{
public:
#ifndef OPENCV_NOSTL
typedef std::forward_iterator_tag iterator_category;
#endif
//! the default constructor
SparseMatIterator_();
//! the full constructor setting the iterator to the first sparse matrix element
SparseMatIterator_(SparseMat_<_Tp>* _m);
//! the copy constructor
SparseMatIterator_(const SparseMatIterator_& it);
//! the assignment operator
SparseMatIterator_& operator = (const SparseMatIterator_& it);
//! returns the reference to the current element
_Tp& operator *() const;
//! moves the iterator to the next element
SparseMatIterator_& operator ++();
//! moves the iterator to the next element
SparseMatIterator_ operator ++(int);
};
/////////////////////////////////// NAryMatIterator //////////////////////////////////
/*!
n-Dimensional Dense Matrix Iterator Class.
The class cv::NAryMatIterator is used for iterating over one or more n-dimensional dense arrays (cv::Mat's).
The iterator is completely different from cv::Mat_ and cv::SparseMat_ iterators.
It iterates through the slices (or planes), not the elements, where "slice" is a continuous part of the arrays.
Here is the example on how the iterator can be used to normalize 3D histogram:
\code
void normalizeColorHist(Mat& hist)
{
#if 1
// intialize iterator (the style is different from STL).
// after initialization the iterator will contain
// the number of slices or planes
// the iterator will go through
Mat* arrays[] = { &hist, 0 };
Mat planes[1];
NAryMatIterator it(arrays, planes);
double s = 0;
// iterate through the matrix. on each iteration
// it.planes[i] (of type Mat) will be set to the current plane of
// i-th n-dim matrix passed to the iterator constructor.
for(int p = 0; p < it.nplanes; p++, ++it)
s += sum(it.planes[0])[0];
it = NAryMatIterator(hist);
s = 1./s;
for(int p = 0; p < it.nplanes; p++, ++it)
it.planes[0] *= s;
#elif 1
// this is a shorter implementation of the above
// using built-in operations on Mat
double s = sum(hist)[0];
hist.convertTo(hist, hist.type(), 1./s, 0);
#else
// and this is even shorter one
// (assuming that the histogram elements are non-negative)
normalize(hist, hist, 1, 0, NORM_L1);
#endif
}
\endcode
You can iterate through several matrices simultaneously as long as they have the same geometry
(dimensionality and all the dimension sizes are the same), which is useful for binary
and n-ary operations on such matrices. Just pass those matrices to cv::MatNDIterator.
Then, during the iteration it.planes[0], it.planes[1], ... will
be the slices of the corresponding matrices
*/
class CV_EXPORTS NAryMatIterator
{
public:
//! the default constructor
NAryMatIterator();
//! the full constructor taking arbitrary number of n-dim matrices
NAryMatIterator(const Mat** arrays, uchar** ptrs, int narrays=-1);
//! the full constructor taking arbitrary number of n-dim matrices
NAryMatIterator(const Mat** arrays, Mat* planes, int narrays=-1);
//! the separate iterator initialization method
void init(const Mat** arrays, Mat* planes, uchar** ptrs, int narrays=-1);
//! proceeds to the next plane of every iterated matrix
NAryMatIterator& operator ++();
//! proceeds to the next plane of every iterated matrix (postfix increment operator)
NAryMatIterator operator ++(int);
//! the iterated arrays
const Mat** arrays;
//! the current planes
Mat* planes;
//! data pointers
uchar** ptrs;
//! the number of arrays
int narrays;
//! the number of hyper-planes that the iterator steps through
size_t nplanes;
//! the size of each segment (in elements)
size_t size;
protected:
int iterdepth;
size_t idx;
};
///////////////////////////////// Matrix Expressions /////////////////////////////////
class CV_EXPORTS MatOp
{
public:
MatOp();
virtual ~MatOp();
virtual bool elementWise(const MatExpr& expr) const;
virtual void assign(const MatExpr& expr, Mat& m, int type=-1) const = 0;
virtual void roi(const MatExpr& expr, const Range& rowRange,
const Range& colRange, MatExpr& res) const;
virtual void diag(const MatExpr& expr, int d, MatExpr& res) const;
virtual void augAssignAdd(const MatExpr& expr, Mat& m) const;
virtual void augAssignSubtract(const MatExpr& expr, Mat& m) const;
virtual void augAssignMultiply(const MatExpr& expr, Mat& m) const;
virtual void augAssignDivide(const MatExpr& expr, Mat& m) const;
virtual void augAssignAnd(const MatExpr& expr, Mat& m) const;
virtual void augAssignOr(const MatExpr& expr, Mat& m) const;
virtual void augAssignXor(const MatExpr& expr, Mat& m) const;
virtual void add(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const;
virtual void add(const MatExpr& expr1, const Scalar& s, MatExpr& res) const;
virtual void subtract(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const;
virtual void subtract(const Scalar& s, const MatExpr& expr, MatExpr& res) const;
virtual void multiply(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res, double scale=1) const;
virtual void multiply(const MatExpr& expr1, double s, MatExpr& res) const;
virtual void divide(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res, double scale=1) const;
virtual void divide(double s, const MatExpr& expr, MatExpr& res) const;
virtual void abs(const MatExpr& expr, MatExpr& res) const;
virtual void transpose(const MatExpr& expr, MatExpr& res) const;
virtual void matmul(const MatExpr& expr1, const MatExpr& expr2, MatExpr& res) const;
virtual void invert(const MatExpr& expr, int method, MatExpr& res) const;
virtual Size size(const MatExpr& expr) const;
virtual int type(const MatExpr& expr) const;
};
class CV_EXPORTS MatExpr
{
public:
MatExpr();
explicit MatExpr(const Mat& m);
MatExpr(const MatOp* _op, int _flags, const Mat& _a = Mat(), const Mat& _b = Mat(),
const Mat& _c = Mat(), double _alpha = 1, double _beta = 1, const Scalar& _s = Scalar());
operator Mat() const;
template<typename _Tp> operator Mat_<_Tp>() const;
Size size() const;
int type() const;
MatExpr row(int y) const;
MatExpr col(int x) const;
MatExpr diag(int d = 0) const;
MatExpr operator()( const Range& rowRange, const Range& colRange ) const;
MatExpr operator()( const Rect& roi ) const;
MatExpr t() const;
MatExpr inv(int method = DECOMP_LU) const;
MatExpr mul(const MatExpr& e, double scale=1) const;
MatExpr mul(const Mat& m, double scale=1) const;
Mat cross(const Mat& m) const;
double dot(const Mat& m) const;
const MatOp* op;
int flags;
Mat a, b, c;
double alpha, beta;
Scalar s;
};
CV_EXPORTS MatExpr operator + (const Mat& a, const Mat& b);
CV_EXPORTS MatExpr operator + (const Mat& a, const Scalar& s);
CV_EXPORTS MatExpr operator + (const Scalar& s, const Mat& a);
CV_EXPORTS MatExpr operator + (const MatExpr& e, const Mat& m);
CV_EXPORTS MatExpr operator + (const Mat& m, const MatExpr& e);
CV_EXPORTS MatExpr operator + (const MatExpr& e, const Scalar& s);
CV_EXPORTS MatExpr operator + (const Scalar& s, const MatExpr& e);
CV_EXPORTS MatExpr operator + (const MatExpr& e1, const MatExpr& e2);
CV_EXPORTS MatExpr operator - (const Mat& a, const Mat& b);
CV_EXPORTS MatExpr operator - (const Mat& a, const Scalar& s);
CV_EXPORTS MatExpr operator - (const Scalar& s, const Mat& a);
CV_EXPORTS MatExpr operator - (const MatExpr& e, const Mat& m);
CV_EXPORTS MatExpr operator - (const Mat& m, const MatExpr& e);
CV_EXPORTS MatExpr operator - (const MatExpr& e, const Scalar& s);
CV_EXPORTS MatExpr operator - (const Scalar& s, const MatExpr& e);
CV_EXPORTS MatExpr operator - (const MatExpr& e1, const MatExpr& e2);
CV_EXPORTS MatExpr operator - (const Mat& m);
CV_EXPORTS MatExpr operator - (const MatExpr& e);
CV_EXPORTS MatExpr operator * (const Mat& a, const Mat& b);
CV_EXPORTS MatExpr operator * (const Mat& a, double s);
CV_EXPORTS MatExpr operator * (double s, const Mat& a);
CV_EXPORTS MatExpr operator * (const MatExpr& e, const Mat& m);
CV_EXPORTS MatExpr operator * (const Mat& m, const MatExpr& e);
CV_EXPORTS MatExpr operator * (const MatExpr& e, double s);
CV_EXPORTS MatExpr operator * (double s, const MatExpr& e);
CV_EXPORTS MatExpr operator * (const MatExpr& e1, const MatExpr& e2);
CV_EXPORTS MatExpr operator / (const Mat& a, const Mat& b);
CV_EXPORTS MatExpr operator / (const Mat& a, double s);
CV_EXPORTS MatExpr operator / (double s, const Mat& a);
CV_EXPORTS MatExpr operator / (const MatExpr& e, const Mat& m);
CV_EXPORTS MatExpr operator / (const Mat& m, const MatExpr& e);
CV_EXPORTS MatExpr operator / (const MatExpr& e, double s);
CV_EXPORTS MatExpr operator / (double s, const MatExpr& e);
CV_EXPORTS MatExpr operator / (const MatExpr& e1, const MatExpr& e2);
CV_EXPORTS MatExpr operator < (const Mat& a, const Mat& b);
CV_EXPORTS MatExpr operator < (const Mat& a, double s);
CV_EXPORTS MatExpr operator < (double s, const Mat& a);
CV_EXPORTS MatExpr operator <= (const Mat& a, const Mat& b);
CV_EXPORTS MatExpr operator <= (const Mat& a, double s);
CV_EXPORTS MatExpr operator <= (double s, const Mat& a);
CV_EXPORTS MatExpr operator == (const Mat& a, const Mat& b);
CV_EXPORTS MatExpr operator == (const Mat& a, double s);
CV_EXPORTS MatExpr operator == (double s, const Mat& a);
CV_EXPORTS MatExpr operator != (const Mat& a, const Mat& b);
CV_EXPORTS MatExpr operator != (const Mat& a, double s);
CV_EXPORTS MatExpr operator != (double s, const Mat& a);
CV_EXPORTS MatExpr operator >= (const Mat& a, const Mat& b);
CV_EXPORTS MatExpr operator >= (const Mat& a, double s);
CV_EXPORTS MatExpr operator >= (double s, const Mat& a);
CV_EXPORTS MatExpr operator > (const Mat& a, const Mat& b);
CV_EXPORTS MatExpr operator > (const Mat& a, double s);
CV_EXPORTS MatExpr operator > (double s, const Mat& a);
CV_EXPORTS MatExpr operator & (const Mat& a, const Mat& b);
CV_EXPORTS MatExpr operator & (const Mat& a, const Scalar& s);
CV_EXPORTS MatExpr operator & (const Scalar& s, const Mat& a);
CV_EXPORTS MatExpr operator | (const Mat& a, const Mat& b);
CV_EXPORTS MatExpr operator | (const Mat& a, const Scalar& s);
CV_EXPORTS MatExpr operator | (const Scalar& s, const Mat& a);
CV_EXPORTS MatExpr operator ^ (const Mat& a, const Mat& b);
CV_EXPORTS MatExpr operator ^ (const Mat& a, const Scalar& s);
CV_EXPORTS MatExpr operator ^ (const Scalar& s, const Mat& a);
CV_EXPORTS MatExpr operator ~(const Mat& m);
CV_EXPORTS MatExpr min(const Mat& a, const Mat& b);
CV_EXPORTS MatExpr min(const Mat& a, double s);
CV_EXPORTS MatExpr min(double s, const Mat& a);
CV_EXPORTS MatExpr max(const Mat& a, const Mat& b);
CV_EXPORTS MatExpr max(const Mat& a, double s);
CV_EXPORTS MatExpr max(double s, const Mat& a);
CV_EXPORTS MatExpr abs(const Mat& m);
CV_EXPORTS MatExpr abs(const MatExpr& e);
} // cv
#include "opencv2/core/mat.inl.hpp"
#endif // __OPENCV_CORE_MAT_HPP__

File diff suppressed because it is too large Load Diff

View File

@ -234,6 +234,110 @@ Matx<_Tp, n, l> Matx<_Tp, m, n>::solve(const Matx<_Tp, m, l>& rhs, int method) c
}
////////////////////////////// Augmenting algebraic & logical operations //////////////////////////////////
#define CV_MAT_AUG_OPERATOR1(op, cvop, A, B) \
static inline A& operator op (A& a, const B& b) { cvop; return a; }
#define CV_MAT_AUG_OPERATOR(op, cvop, A, B) \
CV_MAT_AUG_OPERATOR1(op, cvop, A, B) \
CV_MAT_AUG_OPERATOR1(op, cvop, const A, B)
#define CV_MAT_AUG_OPERATOR_T(op, cvop, A, B) \
template<typename _Tp> CV_MAT_AUG_OPERATOR1(op, cvop, A, B) \
template<typename _Tp> CV_MAT_AUG_OPERATOR1(op, cvop, const A, B)
CV_MAT_AUG_OPERATOR (+=, cv::add(a,b,a), Mat, Mat)
CV_MAT_AUG_OPERATOR (+=, cv::add(a,b,a), Mat, Scalar)
CV_MAT_AUG_OPERATOR_T(+=, cv::add(a,b,a), Mat_<_Tp>, Mat)
CV_MAT_AUG_OPERATOR_T(+=, cv::add(a,b,a), Mat_<_Tp>, Scalar)
CV_MAT_AUG_OPERATOR_T(+=, cv::add(a,b,a), Mat_<_Tp>, Mat_<_Tp>)
CV_MAT_AUG_OPERATOR (-=, cv::subtract(a,b,a), Mat, Mat)
CV_MAT_AUG_OPERATOR (-=, cv::subtract(a,b,a), Mat, Scalar)
CV_MAT_AUG_OPERATOR_T(-=, cv::subtract(a,b,a), Mat_<_Tp>, Mat)
CV_MAT_AUG_OPERATOR_T(-=, cv::subtract(a,b,a), Mat_<_Tp>, Scalar)
CV_MAT_AUG_OPERATOR_T(-=, cv::subtract(a,b,a), Mat_<_Tp>, Mat_<_Tp>)
CV_MAT_AUG_OPERATOR (*=, cv::gemm(a, b, 1, Mat(), 0, a, 0), Mat, Mat)
CV_MAT_AUG_OPERATOR_T(*=, cv::gemm(a, b, 1, Mat(), 0, a, 0), Mat_<_Tp>, Mat)
CV_MAT_AUG_OPERATOR_T(*=, cv::gemm(a, b, 1, Mat(), 0, a, 0), Mat_<_Tp>, Mat_<_Tp>)
CV_MAT_AUG_OPERATOR (*=, a.convertTo(a, -1, b), Mat, double)
CV_MAT_AUG_OPERATOR_T(*=, a.convertTo(a, -1, b), Mat_<_Tp>, double)
CV_MAT_AUG_OPERATOR (/=, cv::divide(a,b,a), Mat, Mat)
CV_MAT_AUG_OPERATOR_T(/=, cv::divide(a,b,a), Mat_<_Tp>, Mat)
CV_MAT_AUG_OPERATOR_T(/=, cv::divide(a,b,a), Mat_<_Tp>, Mat_<_Tp>)
CV_MAT_AUG_OPERATOR (/=, a.convertTo((Mat&)a, -1, 1./b), Mat, double)
CV_MAT_AUG_OPERATOR_T(/=, a.convertTo((Mat&)a, -1, 1./b), Mat_<_Tp>, double)
CV_MAT_AUG_OPERATOR (&=, cv::bitwise_and(a,b,a), Mat, Mat)
CV_MAT_AUG_OPERATOR (&=, cv::bitwise_and(a,b,a), Mat, Scalar)
CV_MAT_AUG_OPERATOR_T(&=, cv::bitwise_and(a,b,a), Mat_<_Tp>, Mat)
CV_MAT_AUG_OPERATOR_T(&=, cv::bitwise_and(a,b,a), Mat_<_Tp>, Scalar)
CV_MAT_AUG_OPERATOR_T(&=, cv::bitwise_and(a,b,a), Mat_<_Tp>, Mat_<_Tp>)
CV_MAT_AUG_OPERATOR (|=, cv::bitwise_or(a,b,a), Mat, Mat)
CV_MAT_AUG_OPERATOR (|=, cv::bitwise_or(a,b,a), Mat, Scalar)
CV_MAT_AUG_OPERATOR_T(|=, cv::bitwise_or(a,b,a), Mat_<_Tp>, Mat)
CV_MAT_AUG_OPERATOR_T(|=, cv::bitwise_or(a,b,a), Mat_<_Tp>, Scalar)
CV_MAT_AUG_OPERATOR_T(|=, cv::bitwise_or(a,b,a), Mat_<_Tp>, Mat_<_Tp>)
CV_MAT_AUG_OPERATOR (^=, cv::bitwise_xor(a,b,a), Mat, Mat)
CV_MAT_AUG_OPERATOR (^=, cv::bitwise_xor(a,b,a), Mat, Scalar)
CV_MAT_AUG_OPERATOR_T(^=, cv::bitwise_xor(a,b,a), Mat_<_Tp>, Mat)
CV_MAT_AUG_OPERATOR_T(^=, cv::bitwise_xor(a,b,a), Mat_<_Tp>, Scalar)
CV_MAT_AUG_OPERATOR_T(^=, cv::bitwise_xor(a,b,a), Mat_<_Tp>, Mat_<_Tp>)
#undef CV_MAT_AUG_OPERATOR_T
#undef CV_MAT_AUG_OPERATOR
#undef CV_MAT_AUG_OPERATOR1
///////////////////////////////////////////// SVD //////////////////////////////////////////////////////
inline SVD::SVD() {}
inline SVD::SVD( InputArray m, int flags ) { operator ()(m, flags); }
inline void SVD::solveZ( InputArray m, OutputArray _dst )
{
Mat mtx = m.getMat();
SVD svd(mtx, (mtx.rows >= mtx.cols ? 0 : SVD::FULL_UV));
_dst.create(svd.vt.cols, 1, svd.vt.type());
Mat dst = _dst.getMat();
svd.vt.row(svd.vt.rows-1).reshape(1,svd.vt.cols).copyTo(dst);
}
template<typename _Tp, int m, int n, int nm> inline void
SVD::compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w, Matx<_Tp, m, nm>& u, Matx<_Tp, n, nm>& vt )
{
CV_StaticAssert( nm == MIN(m, n), "Invalid size of output vector.");
Mat _a(a, false), _u(u, false), _w(w, false), _vt(vt, false);
SVD::compute(_a, _w, _u, _vt);
CV_Assert(_w.data == (uchar*)&w.val[0] && _u.data == (uchar*)&u.val[0] && _vt.data == (uchar*)&vt.val[0]);
}
template<typename _Tp, int m, int n, int nm> inline void
SVD::compute( const Matx<_Tp, m, n>& a, Matx<_Tp, nm, 1>& w )
{
CV_StaticAssert( nm == MIN(m, n), "Invalid size of output vector.");
Mat _a(a, false), _w(w, false);
SVD::compute(_a, _w);
CV_Assert(_w.data == (uchar*)&w.val[0]);
}
template<typename _Tp, int m, int n, int nm, int nb> inline void
SVD::backSubst( const Matx<_Tp, nm, 1>& w, const Matx<_Tp, m, nm>& u,
const Matx<_Tp, n, nm>& vt, const Matx<_Tp, m, nb>& rhs,
Matx<_Tp, n, nb>& dst )
{
CV_StaticAssert( nm == MIN(m, n), "Invalid size of output vector.");
Mat _u(u, false), _w(w, false), _vt(vt, false), _rhs(rhs, false), _dst(dst, false);
SVD::backSubst(_w, _u, _vt, _rhs, _dst);
CV_Assert(_dst.data == (uchar*)&dst.val[0]);
}
//////////////////////////////// Vector ////////////////////////////////
// template vector class. It is similar to STL's vector,
@ -500,6 +604,13 @@ inline Point LineIterator::pos() const
return p;
}
//! returns the next unifomly-distributed random number of the specified type
template<typename _Tp> static inline _Tp randu()
{
return (_Tp)theRNG();
}
//////////////////////////////////////// XML & YAML I/O ////////////////////////////////////
CV_EXPORTS_W void write( FileStorage& fs, const String& name, int value );

View File

@ -220,6 +220,10 @@ static inline bool isInitializer(const MatExpr& e) { return e.op == &g_MatOp_Ini
/////////////////////////////////////////////////////////////////////////////////////////////////////
MatOp::MatOp() {}
MatOp::~MatOp() {}
bool MatOp::elementWise(const MatExpr& /*expr*/) const
{
return false;

View File

@ -262,9 +262,10 @@ void Mat::deallocate()
}
Mat::Mat(const Mat& m, const Range& _rowRange, const Range& _colRange) : size(&rows)
Mat::Mat(const Mat& m, const Range& _rowRange, const Range& _colRange)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), refcount(0), datastart(0), dataend(0),
datalimit(0), allocator(0), size(&rows)
{
initEmpty();
CV_Assert( m.dims >= 2 );
if( m.dims > 2 )
{
@ -335,9 +336,10 @@ Mat::Mat(const Mat& m, const Rect& roi)
}
Mat::Mat(int _dims, const int* _sizes, int _type, void* _data, const size_t* _steps) : size(&rows)
Mat::Mat(int _dims, const int* _sizes, int _type, void* _data, const size_t* _steps)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), refcount(0), datastart(0), dataend(0),
datalimit(0), allocator(0), size(&rows)
{
initEmpty();
flags |= CV_MAT_TYPE(_type);
data = datastart = (uchar*)_data;
setSize(*this, _dims, _sizes, _steps, true);
@ -345,9 +347,10 @@ Mat::Mat(int _dims, const int* _sizes, int _type, void* _data, const size_t* _st
}
Mat::Mat(const Mat& m, const Range* ranges) : size(&rows)
Mat::Mat(const Mat& m, const Range* ranges)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), refcount(0), datastart(0), dataend(0),
datalimit(0), allocator(0), size(&rows)
{
initEmpty();
int i, d = m.dims;
CV_Assert(ranges);
@ -833,6 +836,18 @@ Mat Mat::reshape(int new_cn, int new_rows) const
return hdr;
}
Mat Mat::diag(const Mat& d)
{
CV_Assert( d.cols == 1 || d.rows == 1 );
int len = d.rows + d.cols - 1;
Mat m(len, len, d.type(), Scalar(0));
Mat md = m.diag();
if( d.cols == 1 )
d.copyTo(md);
else
transpose(d, md);
return m;
}
int Mat::checkVector(int _elemChannels, int _depth, bool _requireContinuous) const
{
@ -3407,16 +3422,6 @@ void MatConstIterator::seek(const int* _idx, bool relative)
seek(ofs, relative);
}
ptrdiff_t operator - (const MatConstIterator& b, const MatConstIterator& a)
{
if( a.m != b.m )
return INT_MAX;
if( a.sliceEnd == b.sliceEnd )
return (b.ptr - a.ptr)/b.elemSize;
return b.lpos() - a.lpos();
}
//////////////////////////////// SparseMat ////////////////////////////////
template<typename T1, typename T2> void