Merge remote-tracking branch 'upstream/3.4' into merge-3.4

pull/18662/head
Alexander Alekhin 4 years ago
commit f345ed564a
  1. 562
      modules/core/include/opencv2/core/mat.inl.hpp
  2. 280
      modules/core/src/matrix.cpp
  3. 88
      modules/core/src/matrix_sparse.cpp
  4. 146
      modules/core/src/umatrix.cpp
  5. 2
      modules/js/src/make_umd.py
  6. 19
      modules/objdetect/include/opencv2/objdetect.hpp
  7. 1683
      modules/objdetect/src/qrcode.cpp
  8. 95
      modules/objdetect/test/test_qrcode.cpp
  9. 16
      modules/stitching/src/blenders.cpp

@ -458,158 +458,6 @@ CV__DEBUG_NS_END
//////////////////////////////////////////// Mat //////////////////////////////////////////
inline
Mat::Mat()
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
{}
inline
Mat::Mat(int _rows, int _cols, int _type)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
{
create(_rows, _cols, _type);
}
inline
Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
{
create(_rows, _cols, _type);
*this = _s;
}
inline
Mat::Mat(Size _sz, int _type)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
{
create( _sz.height, _sz.width, _type );
}
inline
Mat::Mat(Size _sz, int _type, const Scalar& _s)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
{
create(_sz.height, _sz.width, _type);
*this = _s;
}
inline
Mat::Mat(int _dims, const int* _sz, int _type)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
{
create(_dims, _sz, _type);
}
inline
Mat::Mat(int _dims, const int* _sz, int _type, const Scalar& _s)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
{
create(_dims, _sz, _type);
*this = _s;
}
inline
Mat::Mat(const std::vector<int>& _sz, int _type)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
{
create(_sz, _type);
}
inline
Mat::Mat(const std::vector<int>& _sz, int _type, const Scalar& _s)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
{
create(_sz, _type);
*this = _s;
}
inline
Mat::Mat(const Mat& m)
: flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data),
datastart(m.datastart), dataend(m.dataend), datalimit(m.datalimit), allocator(m.allocator),
u(m.u), size(&rows), step(0)
{
if( u )
CV_XADD(&u->refcount, 1);
if( m.dims <= 2 )
{
step[0] = m.step[0]; step[1] = m.step[1];
}
else
{
dims = 0;
copySize(m);
}
}
inline
Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)
: flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_rows), cols(_cols),
data((uchar*)_data), datastart((uchar*)_data), dataend(0), datalimit(0),
allocator(0), u(0), size(&rows)
{
CV_Assert(total() == 0 || data != NULL);
size_t esz = CV_ELEM_SIZE(_type), esz1 = CV_ELEM_SIZE1(_type);
size_t minstep = cols * esz;
if( _step == AUTO_STEP )
{
_step = minstep;
}
else
{
CV_DbgAssert( _step >= minstep );
if (_step % esz1 != 0)
{
CV_Error(Error::BadStep, "Step must be a multiple of esz1");
}
}
step[0] = _step;
step[1] = esz;
datalimit = datastart + _step * rows;
dataend = datalimit - _step + minstep;
updateContinuityFlag();
}
inline
Mat::Mat(Size _sz, int _type, void* _data, size_t _step)
: flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_sz.height), cols(_sz.width),
data((uchar*)_data), datastart((uchar*)_data), dataend(0), datalimit(0),
allocator(0), u(0), size(&rows)
{
CV_Assert(total() == 0 || data != NULL);
size_t esz = CV_ELEM_SIZE(_type), esz1 = CV_ELEM_SIZE1(_type);
size_t minstep = cols*esz;
if( _step == AUTO_STEP )
{
_step = minstep;
}
else
{
CV_DbgAssert( _step >= minstep );
if (_step % esz1 != 0)
{
CV_Error(Error::BadStep, "Step must be a multiple of esz1");
}
}
step[0] = _step;
step[1] = esz;
datalimit = datastart + _step*rows;
dataend = datalimit - _step + minstep;
updateContinuityFlag();
}
template<typename _Tp> inline
Mat::Mat(const std::vector<_Tp>& vec, bool copyData)
: flags(MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows((int)vec.size()),
@ -743,43 +591,6 @@ Mat::Mat(const MatCommaInitializer_<_Tp>& commaInitializer)
*this = commaInitializer.operator Mat_<_Tp>();
}
inline
Mat::~Mat()
{
release();
if( step.p != step.buf )
fastFree(step.p);
}
inline
Mat& Mat::operator = (const Mat& m)
{
if( this != &m )
{
if( m.u )
CV_XADD(&m.u->refcount, 1);
release();
flags = m.flags;
if( dims <= 2 && m.dims <= 2 )
{
dims = m.dims;
rows = m.rows;
cols = m.cols;
step[0] = m.step[0];
step[1] = m.step[1];
}
else
copySize(m);
data = m.data;
datastart = m.datastart;
dataend = m.dataend;
datalimit = m.datalimit;
allocator = m.allocator;
u = m.u;
}
return *this;
}
inline
Mat Mat::row(int y) const
{
@ -816,67 +627,6 @@ Mat Mat::colRange(const Range& r) const
return Mat(*this, Range::all(), r);
}
inline
Mat Mat::clone() const
{
Mat m;
copyTo(m);
return m;
}
inline
void Mat::assignTo( Mat& m, int _type ) const
{
if( _type < 0 )
m = *this;
else
convertTo(m, _type);
}
inline
void Mat::create(int _rows, int _cols, int _type)
{
_type &= TYPE_MASK;
if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && data )
return;
int sz[] = {_rows, _cols};
create(2, sz, _type);
}
inline
void Mat::create(Size _sz, int _type)
{
create(_sz.height, _sz.width, _type);
}
inline
void Mat::addref()
{
if( u )
CV_XADD(&u->refcount, 1);
}
inline
void Mat::release()
{
if( u && CV_XADD(&u->refcount, -1) == 1 )
deallocate();
u = NULL;
datastart = dataend = datalimit = data = 0;
for(int i = 0; i < dims; i++)
size.p[i] = 0;
#ifdef _DEBUG
flags = MAGIC_VAL;
dims = rows = cols = 0;
if(step.p != step.buf)
{
fastFree(step.p);
step.p = step.buf;
size.p = &rows;
}
#endif
}
inline
Mat Mat::operator()( Range _rowRange, Range _colRange ) const
{
@ -945,40 +695,6 @@ int Mat::channels() const
return CV_MAT_CN(flags);
}
inline
size_t Mat::step1(int i) const
{
return step.p[i] / elemSize1();
}
inline
bool Mat::empty() const
{
return data == 0 || total() == 0 || dims == 0;
}
inline
size_t Mat::total() const
{
if( dims <= 2 )
return (size_t)rows * cols;
size_t p = 1;
for( int i = 0; i < dims; i++ )
p *= size[i];
return p;
}
inline
size_t Mat::total(int startDim, int endDim) const
{
CV_Assert( 0 <= startDim && startDim <= endDim);
size_t p = 1;
int endDim_ = endDim <= dims ? endDim : dims;
for( int i = startDim; i < endDim_; i++ )
p *= size[i];
return p;
}
inline
uchar* Mat::ptr(int y)
{
@ -1503,22 +1219,6 @@ MatSize::operator const int*() const
return p;
}
inline
bool MatSize::operator == (const MatSize& sz) const
{
int d = dims();
int dsz = sz.dims();
if( d != dsz )
return false;
if( d == 2 )
return p[0] == sz.p[0] && p[1] == sz.p[1];
for( int i = 0; i < d; i++ )
if( p[i] != sz.p[i] )
return false;
return true;
}
inline
bool MatSize::operator != (const MatSize& sz) const
{
@ -1775,9 +1475,7 @@ template<typename _Tp> inline
void Mat_<_Tp>::release()
{
Mat::release();
#ifdef _DEBUG
flags = (flags & ~CV_MAT_TYPE_MASK) + traits::Type<_Tp>::value;
#endif
}
template<typename _Tp> inline
@ -2132,51 +1830,6 @@ Mat_<_Tp>::Mat_(MatExpr&& e)
///////////////////////////// SparseMat /////////////////////////////
inline
SparseMat::SparseMat()
: flags(MAGIC_VAL), hdr(0)
{}
inline
SparseMat::SparseMat(int _dims, const int* _sizes, int _type)
: flags(MAGIC_VAL), hdr(0)
{
create(_dims, _sizes, _type);
}
inline
SparseMat::SparseMat(const SparseMat& m)
: flags(m.flags), hdr(m.hdr)
{
addref();
}
inline
SparseMat::~SparseMat()
{
release();
}
inline
SparseMat& SparseMat::operator = (const SparseMat& m)
{
if( this != &m )
{
if( m.hdr )
CV_XADD(&m.hdr->refcount, 1);
release();
flags = m.flags;
hdr = m.hdr;
}
return *this;
}
inline
SparseMat& SparseMat::operator = (const Mat& m)
{
return (*this = SparseMat(m));
}
inline
SparseMat SparseMat::clone() const
{
@ -2185,30 +1838,6 @@ SparseMat SparseMat::clone() const
return temp;
}
inline
void SparseMat::assignTo( SparseMat& m, int _type ) const
{
if( _type < 0 )
m = *this;
else
convertTo(m, _type);
}
inline
void SparseMat::addref()
{
if( hdr )
CV_XADD(&hdr->refcount, 1);
}
inline
void SparseMat::release()
{
if( hdr && CV_XADD(&hdr->refcount, -1) == 1 )
delete hdr;
hdr = 0;
}
inline
size_t SparseMat::elemSize() const
{
@ -2268,36 +1897,6 @@ size_t SparseMat::nzcount() const
return hdr ? hdr->nodeCount : 0;
}
inline
size_t SparseMat::hash(int i0) const
{
return (size_t)i0;
}
inline
size_t SparseMat::hash(int i0, int i1) const
{
return (size_t)(unsigned)i0 * HASH_SCALE + (unsigned)i1;
}
inline
size_t SparseMat::hash(int i0, int i1, int i2) const
{
return ((size_t)(unsigned)i0 * HASH_SCALE + (unsigned)i1) * HASH_SCALE + (unsigned)i2;
}
inline
size_t SparseMat::hash(const int* idx) const
{
size_t h = (unsigned)idx[0];
if( !hdr )
return 0;
int d = hdr->dims;
for(int i = 1; i < d; i++ )
h = h * HASH_SCALE + (unsigned)idx[i];
return h;
}
template<typename _Tp> inline
_Tp& SparseMat::ref(int i0, size_t* hashval)
{
@ -3617,74 +3216,6 @@ const Mat_<_Tp>& operator /= (const Mat_<_Tp>& a, const MatExpr& b)
//////////////////////////////// UMat ////////////////////////////////
inline
UMat::UMat(UMatUsageFlags _usageFlags)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
{}
inline
UMat::UMat(int _rows, int _cols, int _type, UMatUsageFlags _usageFlags)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
{
create(_rows, _cols, _type);
}
inline
UMat::UMat(int _rows, int _cols, int _type, const Scalar& _s, UMatUsageFlags _usageFlags)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
{
create(_rows, _cols, _type);
*this = _s;
}
inline
UMat::UMat(Size _sz, int _type, UMatUsageFlags _usageFlags)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
{
create( _sz.height, _sz.width, _type );
}
inline
UMat::UMat(Size _sz, int _type, const Scalar& _s, UMatUsageFlags _usageFlags)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
{
create(_sz.height, _sz.width, _type);
*this = _s;
}
inline
UMat::UMat(int _dims, const int* _sz, int _type, UMatUsageFlags _usageFlags)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
{
create(_dims, _sz, _type);
}
inline
UMat::UMat(int _dims, const int* _sz, int _type, const Scalar& _s, UMatUsageFlags _usageFlags)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
{
create(_dims, _sz, _type);
*this = _s;
}
inline
UMat::UMat(const UMat& m)
: flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), allocator(m.allocator),
usageFlags(m.usageFlags), u(m.u), offset(m.offset), size(&rows)
{
addref();
if( m.dims <= 2 )
{
step[0] = m.step[0]; step[1] = m.step[1];
}
else
{
dims = 0;
copySize(m);
}
}
template<typename _Tp> inline
UMat::UMat(const std::vector<_Tp>& vec, bool copyData)
: flags(MAGIC_VAL + traits::Type<_Tp>::value + CV_MAT_CONT_FLAG), dims(2), rows((int)vec.size()),
@ -3701,33 +3232,6 @@ cols(1), allocator(0), usageFlags(USAGE_DEFAULT), u(0), offset(0), size(&rows)
Mat((int)vec.size(), 1, traits::Type<_Tp>::value, (uchar*)&vec[0]).copyTo(*this);
}
inline
UMat& UMat::operator = (const UMat& m)
{
if( this != &m )
{
const_cast<UMat&>(m).addref();
release();
flags = m.flags;
if( dims <= 2 && m.dims <= 2 )
{
dims = m.dims;
rows = m.rows;
cols = m.cols;
step[0] = m.step[0];
step[1] = m.step[1];
}
else
copySize(m);
allocator = m.allocator;
if (usageFlags == USAGE_DEFAULT)
usageFlags = m.usageFlags;
u = m.u;
offset = m.offset;
}
return *this;
}
inline
UMat UMat::row(int y) const
{
@ -3764,55 +3268,6 @@ UMat UMat::colRange(const Range& r) const
return UMat(*this, Range::all(), r);
}
inline
UMat UMat::clone() const
{
UMat m;
copyTo(m);
return m;
}
inline
void UMat::assignTo( UMat& m, int _type ) const
{
if( _type < 0 )
m = *this;
else
convertTo(m, _type);
}
inline
void UMat::create(int _rows, int _cols, int _type, UMatUsageFlags _usageFlags)
{
_type &= TYPE_MASK;
if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && u )
return;
int sz[] = {_rows, _cols};
create(2, sz, _type, _usageFlags);
}
inline
void UMat::create(Size _sz, int _type, UMatUsageFlags _usageFlags)
{
create(_sz.height, _sz.width, _type, _usageFlags);
}
inline
void UMat::addref()
{
if( u )
CV_XADD(&(u->urefcount), 1);
}
inline void UMat::release()
{
if( u && CV_XADD(&(u->urefcount), -1) == 1 )
deallocate();
for(int i = 0; i < dims; i++)
size.p[i] = 0;
u = 0;
}
inline
UMat UMat::operator()( Range _rowRange, Range _colRange ) const
{
@ -3887,23 +3342,6 @@ size_t UMat::step1(int i) const
return step.p[i] / elemSize1();
}
inline
bool UMat::empty() const
{
return u == 0 || total() == 0 || dims == 0;
}
inline
size_t UMat::total() const
{
if( dims <= 2 )
return (size_t)rows * cols;
size_t p = 1;
for( int i = 0; i < dims; i++ )
p *= size[i];
return p;
}
inline
UMat::UMat(UMat&& m)
: flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), allocator(m.allocator),

@ -204,6 +204,21 @@ MatAllocator* Mat::getStdAllocator()
//==================================================================================================
bool MatSize::operator==(const MatSize& sz) const
{
int d = dims();
int dsz = sz.dims();
if( d != dsz )
return false;
if( d == 2 )
return p[0] == sz.p[0] && p[1] == sz.p[1];
for( int i = 0; i < d; i++ )
if( p[i] != sz.p[i] )
return false;
return true;
}
void setSize( Mat& m, int _dims, const int* _sz, const size_t* _steps, bool autoSteps)
{
CV_Assert( 0 <= _dims && _dims <= CV_MAX_DIM );
@ -320,7 +335,270 @@ void finalizeHdr(Mat& m)
m.dataend = m.datalimit = 0;
}
//==================================================================================================
//======================================= Mat ======================================================
Mat::Mat()
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
{}
Mat::Mat(int _rows, int _cols, int _type)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
{
create(_rows, _cols, _type);
}
Mat::Mat(int _rows, int _cols, int _type, const Scalar& _s)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
{
create(_rows, _cols, _type);
*this = _s;
}
Mat::Mat(Size _sz, int _type)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
{
create( _sz.height, _sz.width, _type );
}
Mat::Mat(Size _sz, int _type, const Scalar& _s)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
{
create(_sz.height, _sz.width, _type);
*this = _s;
}
Mat::Mat(int _dims, const int* _sz, int _type)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
{
create(_dims, _sz, _type);
}
Mat::Mat(int _dims, const int* _sz, int _type, const Scalar& _s)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
{
create(_dims, _sz, _type);
*this = _s;
}
Mat::Mat(const std::vector<int>& _sz, int _type)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
{
create(_sz, _type);
}
Mat::Mat(const std::vector<int>& _sz, int _type, const Scalar& _s)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), data(0), datastart(0), dataend(0),
datalimit(0), allocator(0), u(0), size(&rows), step(0)
{
create(_sz, _type);
*this = _s;
}
Mat::Mat(const Mat& m)
: flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), data(m.data),
datastart(m.datastart), dataend(m.dataend), datalimit(m.datalimit), allocator(m.allocator),
u(m.u), size(&rows), step(0)
{
if( u )
CV_XADD(&u->refcount, 1);
if( m.dims <= 2 )
{
step[0] = m.step[0]; step[1] = m.step[1];
}
else
{
dims = 0;
copySize(m);
}
}
Mat::Mat(int _rows, int _cols, int _type, void* _data, size_t _step)
: flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_rows), cols(_cols),
data((uchar*)_data), datastart((uchar*)_data), dataend(0), datalimit(0),
allocator(0), u(0), size(&rows)
{
CV_Assert(total() == 0 || data != NULL);
size_t esz = CV_ELEM_SIZE(_type), esz1 = CV_ELEM_SIZE1(_type);
size_t minstep = cols * esz;
if( _step == AUTO_STEP )
{
_step = minstep;
}
else
{
CV_Assert( _step >= minstep );
if (_step % esz1 != 0)
{
CV_Error(Error::BadStep, "Step must be a multiple of esz1");
}
}
step[0] = _step;
step[1] = esz;
datalimit = datastart + _step * rows;
dataend = datalimit - _step + minstep;
updateContinuityFlag();
}
Mat::Mat(Size _sz, int _type, void* _data, size_t _step)
: flags(MAGIC_VAL + (_type & TYPE_MASK)), dims(2), rows(_sz.height), cols(_sz.width),
data((uchar*)_data), datastart((uchar*)_data), dataend(0), datalimit(0),
allocator(0), u(0), size(&rows)
{
CV_Assert(total() == 0 || data != NULL);
size_t esz = CV_ELEM_SIZE(_type), esz1 = CV_ELEM_SIZE1(_type);
size_t minstep = cols*esz;
if( _step == AUTO_STEP )
{
_step = minstep;
}
else
{
CV_Assert(_step >= minstep);
if (_step % esz1 != 0)
{
CV_Error(Error::BadStep, "Step must be a multiple of esz1");
}
}
step[0] = _step;
step[1] = esz;
datalimit = datastart + _step*rows;
dataend = datalimit - _step + minstep;
updateContinuityFlag();
}
Mat::~Mat()
{
release();
if( step.p != step.buf )
fastFree(step.p);
}
Mat& Mat::operator=(const Mat& m)
{
if( this != &m )
{
if( m.u )
CV_XADD(&m.u->refcount, 1);
release();
flags = m.flags;
if( dims <= 2 && m.dims <= 2 )
{
dims = m.dims;
rows = m.rows;
cols = m.cols;
step[0] = m.step[0];
step[1] = m.step[1];
}
else
copySize(m);
data = m.data;
datastart = m.datastart;
dataend = m.dataend;
datalimit = m.datalimit;
allocator = m.allocator;
u = m.u;
}
return *this;
}
Mat Mat::clone() const
{
Mat m;
copyTo(m);
return m;
}
void Mat::assignTo( Mat& m, int _type ) const
{
if( _type < 0 )
m = *this;
else
convertTo(m, _type);
}
void Mat::create(int _rows, int _cols, int _type)
{
_type &= TYPE_MASK;
if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && data )
return;
int sz[] = {_rows, _cols};
create(2, sz, _type);
}
void Mat::create(Size _sz, int _type)
{
create(_sz.height, _sz.width, _type);
}
void Mat::addref()
{
if( u )
CV_XADD(&u->refcount, 1);
}
void Mat::release()
{
if( u && CV_XADD(&u->refcount, -1) == 1 )
deallocate();
u = NULL;
datastart = dataend = datalimit = data = 0;
for(int i = 0; i < dims; i++)
size.p[i] = 0;
#ifdef _DEBUG
flags = MAGIC_VAL;
dims = rows = cols = 0;
if(step.p != step.buf)
{
fastFree(step.p);
step.p = step.buf;
size.p = &rows;
}
#endif
}
size_t Mat::step1(int i) const
{
return step.p[i] / elemSize1();
}
bool Mat::empty() const
{
return data == 0 || total() == 0 || dims == 0;
}
size_t Mat::total() const
{
if( dims <= 2 )
return (size_t)rows * cols;
size_t p = 1;
for( int i = 0; i < dims; i++ )
p *= size[i];
return p;
}
size_t Mat::total(int startDim, int endDim) const
{
CV_Assert( 0 <= startDim && startDim <= endDim);
size_t p = 1;
int endDim_ = endDim <= dims ? endDim : dims;
for( int i = startDim; i < endDim_; i++ )
p *= size[i];
return p;
}
void Mat::create(int d, const int* _sizes, int _type)
{

@ -176,6 +176,94 @@ void SparseMat::Hdr::clear()
nodeCount = freeList = 0;
}
///////////////////////////// SparseMat /////////////////////////////
SparseMat::SparseMat()
: flags(MAGIC_VAL), hdr(0)
{}
SparseMat::SparseMat(int _dims, const int* _sizes, int _type)
: flags(MAGIC_VAL), hdr(0)
{
create(_dims, _sizes, _type);
}
SparseMat::SparseMat(const SparseMat& m)
: flags(m.flags), hdr(m.hdr)
{
addref();
}
SparseMat::~SparseMat()
{
release();
}
SparseMat& SparseMat::operator = (const SparseMat& m)
{
if( this != &m )
{
if( m.hdr )
CV_XADD(&m.hdr->refcount, 1);
release();
flags = m.flags;
hdr = m.hdr;
}
return *this;
}
SparseMat& SparseMat::operator=(const Mat& m)
{
return (*this = SparseMat(m));
}
void SparseMat::assignTo(SparseMat& m, int _type) const
{
if( _type < 0 )
m = *this;
else
convertTo(m, _type);
}
void SparseMat::addref()
{
if( hdr )
CV_XADD(&hdr->refcount, 1);
}
void SparseMat::release()
{
if( hdr && CV_XADD(&hdr->refcount, -1) == 1 )
delete hdr;
hdr = 0;
}
size_t SparseMat::hash(int i0) const
{
return (size_t)i0;
}
size_t SparseMat::hash(int i0, int i1) const
{
return (size_t)(unsigned)i0 * HASH_SCALE + (unsigned)i1;
}
size_t SparseMat::hash(int i0, int i1, int i2) const
{
return ((size_t)(unsigned)i0 * HASH_SCALE + (unsigned)i1) * HASH_SCALE + (unsigned)i2;
}
size_t SparseMat::hash(const int* idx) const
{
size_t h = (unsigned)idx[0];
if( !hdr )
return 0;
int d = hdr->dims;
for(int i = 1; i < d; i++ )
h = h * HASH_SCALE + (unsigned)idx[i];
return h;
}
SparseMat::SparseMat(const Mat& m)
: flags(MAGIC_VAL), hdr(0)

@ -228,6 +228,152 @@ UMatDataAutoLock::~UMatDataAutoLock()
getUMatDataAutoLocker().release(u1, u2);
}
//////////////////////////////// UMat ////////////////////////////////
UMat::UMat(UMatUsageFlags _usageFlags)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
{}
UMat::UMat(int _rows, int _cols, int _type, UMatUsageFlags _usageFlags)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
{
create(_rows, _cols, _type);
}
UMat::UMat(int _rows, int _cols, int _type, const Scalar& _s, UMatUsageFlags _usageFlags)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
{
create(_rows, _cols, _type);
*this = _s;
}
UMat::UMat(Size _sz, int _type, UMatUsageFlags _usageFlags)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
{
create( _sz.height, _sz.width, _type );
}
UMat::UMat(Size _sz, int _type, const Scalar& _s, UMatUsageFlags _usageFlags)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
{
create(_sz.height, _sz.width, _type);
*this = _s;
}
UMat::UMat(int _dims, const int* _sz, int _type, UMatUsageFlags _usageFlags)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
{
create(_dims, _sz, _type);
}
UMat::UMat(int _dims, const int* _sz, int _type, const Scalar& _s, UMatUsageFlags _usageFlags)
: flags(MAGIC_VAL), dims(0), rows(0), cols(0), allocator(0), usageFlags(_usageFlags), u(0), offset(0), size(&rows)
{
create(_dims, _sz, _type);
*this = _s;
}
UMat::UMat(const UMat& m)
: flags(m.flags), dims(m.dims), rows(m.rows), cols(m.cols), allocator(m.allocator),
usageFlags(m.usageFlags), u(m.u), offset(m.offset), size(&rows)
{
addref();
if( m.dims <= 2 )
{
step[0] = m.step[0]; step[1] = m.step[1];
}
else
{
dims = 0;
copySize(m);
}
}
UMat& UMat::operator=(const UMat& m)
{
if( this != &m )
{
const_cast<UMat&>(m).addref();
release();
flags = m.flags;
if( dims <= 2 && m.dims <= 2 )
{
dims = m.dims;
rows = m.rows;
cols = m.cols;
step[0] = m.step[0];
step[1] = m.step[1];
}
else
copySize(m);
allocator = m.allocator;
if (usageFlags == USAGE_DEFAULT)
usageFlags = m.usageFlags;
u = m.u;
offset = m.offset;
}
return *this;
}
UMat UMat::clone() const
{
UMat m;
copyTo(m);
return m;
}
void UMat::assignTo(UMat& m, int _type) const
{
if( _type < 0 )
m = *this;
else
convertTo(m, _type);
}
void UMat::create(int _rows, int _cols, int _type, UMatUsageFlags _usageFlags)
{
_type &= TYPE_MASK;
if( dims <= 2 && rows == _rows && cols == _cols && type() == _type && u )
return;
int sz[] = {_rows, _cols};
create(2, sz, _type, _usageFlags);
}
void UMat::create(Size _sz, int _type, UMatUsageFlags _usageFlags)
{
create(_sz.height, _sz.width, _type, _usageFlags);
}
void UMat::addref()
{
if( u )
CV_XADD(&(u->urefcount), 1);
}
void UMat::release()
{
if( u && CV_XADD(&(u->urefcount), -1) == 1 )
deallocate();
for(int i = 0; i < dims; i++)
size.p[i] = 0;
u = 0;
}
bool UMat::empty() const
{
return u == 0 || total() == 0 || dims == 0;
}
size_t UMat::total() const
{
if( dims <= 2 )
return (size_t)rows * cols;
size_t p = 1;
for( int i = 0; i < dims; i++ )
p *= size[i];
return p;
}
MatAllocator* UMat::getStdAllocator()
{

@ -103,7 +103,7 @@ def make_umd(opencvjs, cvjs):
Module = {};
return cv(Module);
}));
""" % (content)).lstrip())
""" % (content)).lstrip().encode())
if __name__ == "__main__":
if len(sys.argv) > 2:

@ -699,6 +699,15 @@ public:
*/
CV_WRAP std::string decode(InputArray img, InputArray points, OutputArray straight_qrcode = noArray());
/** @brief Decodes QR code on a curved surface in image once it's found by the detect() method.
Returns UTF8-encoded output string or empty string if the code cannot be decoded.
@param img grayscale or color (BGR) image containing QR code.
@param points Quadrangle vertices found by detect() method (or some other algorithm).
@param straight_qrcode The optional output image containing rectified and binarized QR code
*/
CV_WRAP cv::String decodeCurved(InputArray img, InputArray points, OutputArray straight_qrcode = noArray());
/** @brief Both detects and decodes QR code
@param img grayscale or color (BGR) image containing QR code.
@ -707,6 +716,16 @@ public:
*/
CV_WRAP std::string detectAndDecode(InputArray img, OutputArray points=noArray(),
OutputArray straight_qrcode = noArray());
/** @brief Both detects and decodes QR code on a curved surface
@param img grayscale or color (BGR) image containing QR code.
@param points optional output array of vertices of the found QR code quadrangle. Will be empty if not found.
@param straight_qrcode The optional output image containing rectified and binarized QR code
*/
CV_WRAP std::string detectAndDecodeCurved(InputArray img, OutputArray points=noArray(),
OutputArray straight_qrcode = noArray());
/** @brief Detects QR codes in image and returns the vector of the quadrangles containing the codes.
@param img grayscale or color (BGR) image containing (or not) QR codes.
@param points Output vector of vector of vertices of the minimum-area quadrangle containing the codes.

File diff suppressed because it is too large Load Diff

@ -21,6 +21,9 @@ std::string qrcode_images_close[] = {
std::string qrcode_images_monitor[] = {
"monitor_1.png", "monitor_2.png", "monitor_3.png", "monitor_4.png", "monitor_5.png"
};
std::string qrcode_images_curved[] = {
"curved_1.jpg", "curved_2.jpg", "curved_3.jpg", "curved_4.jpg", "curved_5.jpg", "curved_6.jpg", "curved_7.jpg", "curved_8.jpg"
};
std::string qrcode_images_multiple[] = {
"2_qrcodes.png", "3_close_qrcodes.png", "3_qrcodes.png", "4_qrcodes.png",
"5_qrcodes.png", "6_qrcodes.png", "7_qrcodes.png", "8_close_qrcodes.png"
@ -137,7 +140,38 @@ TEST(Objdetect_QRCode_Monitor, generate_test_data)
file_config << "]";
file_config.release();
}
TEST(Objdetect_QRCode_Curved, generate_test_data)
{
const std::string root = "qrcode/curved/";
const std::string dataset_config = findDataFile(root + "dataset_config.json");
FileStorage file_config(dataset_config, FileStorage::WRITE);
file_config << "test_images" << "[";
size_t images_count = sizeof(qrcode_images_curved) / sizeof(qrcode_images_curved[0]);
for (size_t i = 0; i < images_count; i++)
{
file_config << "{:" << "image_name" << qrcode_images_curved[i];
std::string image_path = findDataFile(root + qrcode_images_curved[i]);
std::vector<Point> corners;
Mat src = imread(image_path, IMREAD_GRAYSCALE), straight_barcode;
std::string decoded_info;
ASSERT_FALSE(src.empty()) << "Can't read image: " << image_path;
EXPECT_TRUE(detectQRCode(src, corners));
#ifdef HAVE_QUIRC
EXPECT_TRUE(decodeCurvedQRCode(src, corners, decoded_info, straight_barcode));
#endif
file_config << "x" << "[:";
for (size_t j = 0; j < corners.size(); j++) { file_config << corners[j].x; }
file_config << "]";
file_config << "y" << "[:";
for (size_t j = 0; j < corners.size(); j++) { file_config << corners[j].y; }
file_config << "]";
file_config << "info" << decoded_info;
file_config << "}";
}
file_config << "]";
file_config.release();
}
TEST(Objdetect_QRCode_Multi, generate_test_data)
{
const std::string root = "qrcode/multiple/";
@ -390,6 +424,66 @@ TEST_P(Objdetect_QRCode_Monitor, regression)
}
}
typedef testing::TestWithParam< std::string > Objdetect_QRCode_Curved;
TEST_P(Objdetect_QRCode_Curved, regression)
{
const std::string name_current_image = GetParam();
const std::string root = "qrcode/curved/";
const int pixels_error = 3;
std::string image_path = findDataFile(root + name_current_image);
Mat src = imread(image_path, IMREAD_GRAYSCALE), straight_barcode;
ASSERT_FALSE(src.empty()) << "Can't read image: " << image_path;
std::vector<Point> corners;
std::string decoded_info;
QRCodeDetector qrcode;
#ifdef HAVE_QUIRC
decoded_info = qrcode.detectAndDecodeCurved(src, corners, straight_barcode);
ASSERT_FALSE(corners.empty());
ASSERT_FALSE(decoded_info.empty());
#else
ASSERT_TRUE(qrcode.detect(src, corners));
#endif
const std::string dataset_config = findDataFile(root + "dataset_config.json");
FileStorage file_config(dataset_config, FileStorage::READ);
ASSERT_TRUE(file_config.isOpened()) << "Can't read validation data: " << dataset_config;
{
FileNode images_list = file_config["test_images"];
size_t images_count = static_cast<size_t>(images_list.size());
ASSERT_GT(images_count, 0u) << "Can't find validation data entries in 'test_images': " << dataset_config;
for (size_t index = 0; index < images_count; index++)
{
FileNode config = images_list[(int)index];
std::string name_test_image = config["image_name"];
if (name_test_image == name_current_image)
{
for (int i = 0; i < 4; i++)
{
int x = config["x"][i];
int y = config["y"][i];
EXPECT_NEAR(x, corners[i].x, pixels_error);
EXPECT_NEAR(y, corners[i].y, pixels_error);
}
#ifdef HAVE_QUIRC
std::string original_info = config["info"];
EXPECT_EQ(decoded_info, original_info);
#endif
return; // done
}
}
std::cerr
<< "Not found results for '" << name_current_image
<< "' image in config file:" << dataset_config << std::endl
<< "Re-run tests with enabled UPDATE_QRCODE_TEST_DATA macro to update test data."
<< std::endl;
}
}
typedef testing::TestWithParam < std::string > Objdetect_QRCode_Multi;
TEST_P(Objdetect_QRCode_Multi, regression)
{
@ -478,6 +572,7 @@ TEST_P(Objdetect_QRCode_Multi, regression)
INSTANTIATE_TEST_CASE_P(/**/, Objdetect_QRCode, testing::ValuesIn(qrcode_images_name));
INSTANTIATE_TEST_CASE_P(/**/, Objdetect_QRCode_Close, testing::ValuesIn(qrcode_images_close));
INSTANTIATE_TEST_CASE_P(/**/, Objdetect_QRCode_Monitor, testing::ValuesIn(qrcode_images_monitor));
INSTANTIATE_TEST_CASE_P(/**/, Objdetect_QRCode_Curved, testing::ValuesIn(qrcode_images_curved));
INSTANTIATE_TEST_CASE_P(/**/, Objdetect_QRCode_Multi, testing::ValuesIn(qrcode_images_multiple));
TEST(Objdetect_QRCode_decodeMulti, decode_regression_16491)

@ -218,7 +218,7 @@ MultiBandBlender::MultiBandBlender(int try_gpu, int num_bands, int weight_type)
num_bands_ = 0;
setNumBands(num_bands);
#if defined(HAVE_OPENCV_CUDAARITHM) && defined(HAVE_OPENCV_CUDAWARPING)
#if defined(HAVE_CUDA) && defined(HAVE_OPENCV_CUDAARITHM) && defined(HAVE_OPENCV_CUDAWARPING)
can_use_gpu_ = try_gpu && cuda::getCudaEnabledDeviceCount();
gpu_feed_idx_ = 0;
#else
@ -244,7 +244,7 @@ void MultiBandBlender::prepare(Rect dst_roi)
Blender::prepare(dst_roi);
#if defined(HAVE_OPENCV_CUDAARITHM) && defined(HAVE_OPENCV_CUDAWARPING)
#if defined(HAVE_CUDA) && defined(HAVE_OPENCV_CUDAARITHM) && defined(HAVE_OPENCV_CUDAWARPING)
if (can_use_gpu_)
{
gpu_initialized_ = false;
@ -330,7 +330,7 @@ void MultiBandBlender::feed(InputArray _img, InputArray mask, Point tl)
UMat img;
#if defined(HAVE_OPENCV_CUDAARITHM) && defined(HAVE_OPENCV_CUDAWARPING)
#if defined(HAVE_CUDA) && defined(HAVE_OPENCV_CUDAARITHM) && defined(HAVE_OPENCV_CUDAWARPING)
// If using gpu save the top left coordinate when running first time after prepare
if (can_use_gpu_)
{
@ -351,7 +351,7 @@ void MultiBandBlender::feed(InputArray _img, InputArray mask, Point tl)
{
img = _img.getUMat();
}
#if defined(HAVE_OPENCV_CUDAARITHM) && defined(HAVE_OPENCV_CUDAWARPING)
#if defined(HAVE_CUDA) && defined(HAVE_OPENCV_CUDAARITHM) && defined(HAVE_OPENCV_CUDAWARPING)
else
{
gpu_img_ = _img.getGpuMat();
@ -392,7 +392,7 @@ void MultiBandBlender::feed(InputArray _img, InputArray mask, Point tl)
int bottom = br_new.y - tl.y - img.rows;
int right = br_new.x - tl.x - img.cols;
#if defined(HAVE_OPENCV_CUDAARITHM) && defined(HAVE_OPENCV_CUDAWARPING)
#if defined(HAVE_CUDA) && defined(HAVE_OPENCV_CUDAARITHM) && defined(HAVE_OPENCV_CUDAWARPING)
if (can_use_gpu_)
{
if (!gpu_initialized_)
@ -601,7 +601,7 @@ void MultiBandBlender::feed(InputArray _img, InputArray mask, Point tl)
void MultiBandBlender::blend(InputOutputArray dst, InputOutputArray dst_mask)
{
Rect dst_rc(0, 0, dst_roi_final_.width, dst_roi_final_.height);
#if defined(HAVE_OPENCV_CUDAARITHM) && defined(HAVE_OPENCV_CUDAWARPING)
#if defined(HAVE_CUDA) && defined(HAVE_OPENCV_CUDAARITHM) && defined(HAVE_OPENCV_CUDAWARPING)
if (can_use_gpu_)
{
if (!gpu_initialized_)
@ -836,7 +836,7 @@ void createLaplacePyr(InputArray img, int num_levels, std::vector<UMat> &pyr)
void createLaplacePyrGpu(InputArray img, int num_levels, std::vector<UMat> &pyr)
{
#if defined(HAVE_OPENCV_CUDAARITHM) && defined(HAVE_OPENCV_CUDAWARPING)
#if defined(HAVE_CUDA) && defined(HAVE_OPENCV_CUDAARITHM) && defined(HAVE_OPENCV_CUDAWARPING)
pyr.resize(num_levels + 1);
std::vector<cuda::GpuMat> gpu_pyr(num_levels + 1);
@ -877,7 +877,7 @@ void restoreImageFromLaplacePyr(std::vector<UMat> &pyr)
void restoreImageFromLaplacePyrGpu(std::vector<UMat> &pyr)
{
#if defined(HAVE_OPENCV_CUDAARITHM) && defined(HAVE_OPENCV_CUDAWARPING)
#if defined(HAVE_CUDA) && defined(HAVE_OPENCV_CUDAARITHM) && defined(HAVE_OPENCV_CUDAWARPING)
if (pyr.empty())
return;

Loading…
Cancel
Save