mirror of
https://github.com/opencv/opencv.git
synced 2026-07-29 15:23:05 +04:00
attempt to add 0d/1d mat support to OpenCV (#23473)
* attempt to add 0d/1d mat support to OpenCV * revised the patch; now 1D mat is treated as 1xN 2D mat rather than Nx1. * a step towards 'green' tests * another little step towards 'green' tests * calib test failures seem to be fixed now * more fixes _core & _dnn * another step towards green ci; even 0D mat's (a.k.a. scalars) are now partly supported! * * fixed strange bug in aruco/charuco detector, not sure why it did not work * also fixed a few remaining failures (hopefully) in dnn & core * disabled failing GAPI tests - too complex to dig into this compiler pipeline * hopefully fixed java tests * trying to fix some more tests * quick followup fix * continue to fix test failures and warnings * quick followup fix * trying to fix some more tests * partly fixed support for 0D/scalar UMat's * use updated parseReduce() from upstream * trying to fix the remaining test failures * fixed [ch]aruco tests in Python * still trying to fix tests * revert "fix" in dnn's CUDA tensor * trying to fix dnn+CUDA test failures * fixed 1D umat creation * hopefully fixed remaining cuda test failures * removed training whitespaces
This commit is contained in:
@@ -309,7 +309,10 @@ UMat::UMat(const UMat& m)
|
||||
addref();
|
||||
if( m.dims <= 2 )
|
||||
{
|
||||
step[0] = m.step[0]; step[1] = m.step[1];
|
||||
int _1d = dims <= 1;
|
||||
step.buf[0] = m.step.buf[0]; step.buf[1] = m.step.buf[1];
|
||||
step.p = &step.buf[_1d];
|
||||
size.p = &rows + _1d;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -330,8 +333,11 @@ UMat& UMat::operator=(const UMat& m)
|
||||
dims = m.dims;
|
||||
rows = m.rows;
|
||||
cols = m.cols;
|
||||
step[0] = m.step[0];
|
||||
step[1] = m.step[1];
|
||||
int _1d = dims <= 1;
|
||||
step.buf[0] = m.step.buf[0];
|
||||
step.buf[1] = m.step.buf[1];
|
||||
step.p = &step.buf[_1d];
|
||||
size.p = &rows + _1d;
|
||||
}
|
||||
else
|
||||
copySize(m);
|
||||
@@ -369,6 +375,13 @@ void UMat::create(Size _sz, int _type, UMatUsageFlags _usageFlags)
|
||||
create(_sz.height, _sz.width, _type, _usageFlags);
|
||||
}
|
||||
|
||||
void UMat::createSameSize(InputArray arr, int _type, UMatUsageFlags _usageFlags)
|
||||
{
|
||||
int arr_size[CV_MAX_DIM];
|
||||
int ndims = arr.sizend(arr_size);
|
||||
create(ndims, arr_size, _type, _usageFlags);
|
||||
}
|
||||
|
||||
void UMat::addref()
|
||||
{
|
||||
if( u )
|
||||
@@ -386,7 +399,7 @@ void UMat::release()
|
||||
|
||||
bool UMat::empty() const
|
||||
{
|
||||
return u == 0 || total() == 0 || dims == 0;
|
||||
return u == 0 || total() == 0;
|
||||
}
|
||||
|
||||
size_t UMat::total() const
|
||||
@@ -406,12 +419,15 @@ UMat::UMat(UMat&& m)
|
||||
{
|
||||
if (m.dims <= 2) // move new step/size info
|
||||
{
|
||||
step[0] = m.step[0];
|
||||
step[1] = m.step[1];
|
||||
int _1d = m.dims <= 1;
|
||||
step.buf[0] = m.step.buf[0];
|
||||
step.buf[1] = m.step.buf[1];
|
||||
step.p = &step.buf[_1d];
|
||||
size.p = &rows + _1d;
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_DbgAssert(m.step.p != m.step.buf);
|
||||
CV_DbgAssert(m.step.p != m.step.buf && m.step.p != m.step.buf+1);
|
||||
step.p = m.step.p;
|
||||
size.p = m.size.p;
|
||||
m.step.p = m.step.buf;
|
||||
@@ -432,25 +448,28 @@ UMat& UMat::operator=(UMat&& m)
|
||||
allocator = m.allocator; usageFlags = m.usageFlags;
|
||||
u = m.u;
|
||||
offset = m.offset;
|
||||
if (step.p != step.buf) // release self step/size
|
||||
if (step.p != step.buf && step.p != step.buf+1) // release self step/size
|
||||
{
|
||||
fastFree(step.p);
|
||||
step.p = step.buf;
|
||||
size.p = &rows;
|
||||
}
|
||||
step.p = step.buf;
|
||||
size.p = &rows;
|
||||
if (m.dims <= 2) // move new step/size info
|
||||
{
|
||||
step[0] = m.step[0];
|
||||
step[1] = m.step[1];
|
||||
int _1d = dims <= 1;
|
||||
step.buf[0] = m.step.buf[0];
|
||||
step.buf[1] = m.step.buf[1];
|
||||
step.p = &step.buf[_1d];
|
||||
size.p = &rows + _1d;
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_DbgAssert(m.step.p != m.step.buf);
|
||||
CV_DbgAssert(m.step.p != m.step.buf && m.step.p != m.step.buf+1);
|
||||
step.p = m.step.p;
|
||||
size.p = m.size.p;
|
||||
m.step.p = m.step.buf;
|
||||
m.size.p = &m.rows;
|
||||
}
|
||||
m.step.p = m.step.buf;
|
||||
m.size.p = &m.rows;
|
||||
m.flags = MAGIC_VAL;
|
||||
m.usageFlags = USAGE_DEFAULT;
|
||||
m.dims = m.rows = m.cols = 0;
|
||||
@@ -485,32 +504,34 @@ void swap( UMat& a, UMat& b )
|
||||
std::swap(a.step.buf[0], b.step.buf[0]);
|
||||
std::swap(a.step.buf[1], b.step.buf[1]);
|
||||
|
||||
if( a.step.p == b.step.buf )
|
||||
if(a.dims <= 2)
|
||||
{
|
||||
a.step.p = a.step.buf;
|
||||
a.size.p = &a.rows;
|
||||
int a_1d = a.dims <= 1;
|
||||
a.step.p = &a.step.buf[a_1d];
|
||||
a.size.p = &a.rows + a_1d;
|
||||
}
|
||||
|
||||
if( b.step.p == a.step.buf )
|
||||
if( b.dims <= 2)
|
||||
{
|
||||
b.step.p = b.step.buf;
|
||||
b.size.p = &b.rows;
|
||||
int b_1d = b.dims <= 1;
|
||||
b.step.p = &b.step.buf[b_1d];
|
||||
b.size.p = &b.rows + b_1d;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void setSize( UMat& m, int _dims, const int* _sz,
|
||||
const size_t* _steps, bool autoSteps )
|
||||
const size_t* _steps, bool autoSteps )
|
||||
{
|
||||
CV_Assert( 0 <= _dims && _dims <= CV_MAX_DIM );
|
||||
if( m.dims != _dims )
|
||||
{
|
||||
if( m.step.p != m.step.buf )
|
||||
if( m.step.p != m.step.buf && m.step.p != m.step.buf+1 )
|
||||
{
|
||||
fastFree(m.step.p);
|
||||
m.step.p = m.step.buf;
|
||||
m.size.p = &m.rows;
|
||||
}
|
||||
m.step.p = m.step.buf;
|
||||
m.size.p = &m.rows;
|
||||
if( _dims > 2 )
|
||||
{
|
||||
m.step.p = (size_t*)fastMalloc(_dims*sizeof(m.step.p[0]) + (_dims+1)*sizeof(m.size.p[0]));
|
||||
@@ -521,34 +542,37 @@ void setSize( UMat& m, int _dims, const int* _sz,
|
||||
}
|
||||
|
||||
m.dims = _dims;
|
||||
if( !_sz )
|
||||
return;
|
||||
|
||||
size_t esz = CV_ELEM_SIZE(m.flags), total = esz;
|
||||
int i;
|
||||
for( i = _dims-1; i >= 0; i-- )
|
||||
{
|
||||
int s = _sz[i];
|
||||
CV_Assert( s >= 0 );
|
||||
m.size.p[i] = s;
|
||||
|
||||
if( _steps )
|
||||
m.step.p[i] = i < _dims-1 ? _steps[i] : esz;
|
||||
else if( autoSteps )
|
||||
if (_sz != 0) {
|
||||
int i;
|
||||
for( i = _dims-1; i >= 0; i-- )
|
||||
{
|
||||
m.step.p[i] = total;
|
||||
int64 total1 = (int64)total*s;
|
||||
if( (uint64)total1 != (size_t)total1 )
|
||||
CV_Error( CV_StsOutOfRange, "The total matrix size does not fit to \"size_t\" type" );
|
||||
total = (size_t)total1;
|
||||
int s = _sz[i];
|
||||
CV_Assert( s >= 0 );
|
||||
m.size.p[i] = s;
|
||||
|
||||
if( _steps )
|
||||
m.step.p[i] = i < _dims-1 ? _steps[i] : esz;
|
||||
else if( autoSteps )
|
||||
{
|
||||
m.step.p[i] = total;
|
||||
int64 total1 = (int64)total*s;
|
||||
if( (uint64)total1 != (size_t)total1 )
|
||||
CV_Error( CV_StsOutOfRange, "The total matrix size does not fit to \"size_t\" type" );
|
||||
total = (size_t)total1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if( _dims == 1 )
|
||||
if( _dims < 2 )
|
||||
{
|
||||
m.dims = 2;
|
||||
m.cols = 1;
|
||||
m.step[1] = esz;
|
||||
m.cols = _dims >= 1 && _sz ? _sz[0] : 1;
|
||||
m.rows = 1;
|
||||
m.size.p = &m.cols;
|
||||
m.step.buf[0] = m.cols*esz;
|
||||
m.step.buf[1] = esz;
|
||||
m.step.p = &m.step.buf[1];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -650,9 +674,14 @@ UMat Mat::getUMat(AccessFlag accessFlags, UMatUsageFlags usageFlags) const
|
||||
|
||||
}
|
||||
|
||||
void UMat::create(int d, const int* _sizes, int _type, UMatUsageFlags _usageFlags)
|
||||
void UMat::create(int d0, const int* _sizes, int _type, UMatUsageFlags _usageFlags)
|
||||
{
|
||||
int sz1 = 1, d = d0;
|
||||
int i;
|
||||
if (d == 0) {
|
||||
d = 1;
|
||||
_sizes = (const int*)&sz1;
|
||||
}
|
||||
CV_Assert(0 <= d && d <= CV_MAX_DIM && _sizes);
|
||||
_type = CV_MAT_TYPE(_type);
|
||||
|
||||
@@ -665,12 +694,12 @@ void UMat::create(int d, const int* _sizes, int _type, UMatUsageFlags _usageFlag
|
||||
_usageFlags = usageFlags;
|
||||
}
|
||||
|
||||
if( u && (d == dims || (d == 1 && dims <= 2)) && _type == type() && _usageFlags == usageFlags )
|
||||
if( u && d == dims && _type == type() && _usageFlags == usageFlags )
|
||||
{
|
||||
for( i = 0; i < d; i++ )
|
||||
if( size[i] != _sizes[i] )
|
||||
break;
|
||||
if( i == d && (d > 1 || size[1] == 1))
|
||||
if( i == d )
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -714,6 +743,7 @@ void UMat::create(int d, const int* _sizes, int _type, UMatUsageFlags _usageFlag
|
||||
|
||||
finalizeHdr(*this);
|
||||
addref();
|
||||
dims = d0;
|
||||
}
|
||||
|
||||
void UMat::create(const std::vector<int>& _sizes, int _type, UMatUsageFlags _usageFlags)
|
||||
@@ -735,7 +765,7 @@ void UMat::copySize(const UMat& m)
|
||||
UMat::~UMat()
|
||||
{
|
||||
release();
|
||||
if( step.p != step.buf )
|
||||
if( step.p != step.buf && step.p != step.buf+1 )
|
||||
fastFree(step.p);
|
||||
}
|
||||
|
||||
@@ -919,7 +949,7 @@ void UMat::locateROI( Size& wholeSize, Point& ofs ) const
|
||||
|
||||
UMat& UMat::adjustROI( int dtop, int dbottom, int dleft, int dright )
|
||||
{
|
||||
CV_Assert( dims <= 2 && step[0] > 0 );
|
||||
CV_Assert( dims == 2 && step[0] > 0 );
|
||||
Size wholeSize; Point ofs;
|
||||
size_t esz = elemSize();
|
||||
locateROI( wholeSize, ofs );
|
||||
@@ -978,7 +1008,7 @@ UMat UMat::reshape(int new_cn, int new_rows) const
|
||||
"is not divisible by the new number of rows" );
|
||||
|
||||
hdr.rows = new_rows;
|
||||
hdr.step[0] = total_width * elemSize1();
|
||||
hdr.step.buf[0] = total_width * elemSize1();
|
||||
}
|
||||
|
||||
int new_width = total_width / new_cn;
|
||||
@@ -987,9 +1017,12 @@ UMat UMat::reshape(int new_cn, int new_rows) const
|
||||
CV_Error( CV_BadNumChannels,
|
||||
"The total width is not divisible by the new number of channels" );
|
||||
|
||||
hdr.dims = 2;
|
||||
hdr.cols = new_width;
|
||||
hdr.flags = (hdr.flags & ~CV_MAT_CN_MASK) | ((new_cn-1) << CV_CN_SHIFT);
|
||||
hdr.step[1] = CV_ELEM_SIZE(hdr.flags);
|
||||
hdr.step.buf[1] = CV_ELEM_SIZE(hdr.flags);
|
||||
hdr.step.p = &hdr.step.buf[0];
|
||||
hdr.size.p = &hdr.rows;
|
||||
return hdr;
|
||||
}
|
||||
|
||||
@@ -1010,7 +1043,7 @@ int UMat::checkVector(int _elemChannels, int _depth, bool _requireContinuous) co
|
||||
{
|
||||
return (depth() == _depth || _depth <= 0) &&
|
||||
(isContinuous() || !_requireContinuous) &&
|
||||
((dims == 2 && (((rows == 1 || cols == 1) && channels() == _elemChannels) ||
|
||||
((dims <= 2 && (((rows == 1 || cols == 1) && channels() == _elemChannels) ||
|
||||
(cols == _elemChannels && channels() == 1))) ||
|
||||
(dims == 3 && channels() == 1 && size.p[2] == _elemChannels && (size.p[0] == 1 || size.p[1] == 1) &&
|
||||
(isContinuous() || step.p[1] == step.p[2]*size.p[2])))
|
||||
@@ -1156,12 +1189,14 @@ void UMat::copyTo(OutputArray _dst) const
|
||||
return;
|
||||
}
|
||||
|
||||
size_t i, sz[CV_MAX_DIM] = {0}, srcofs[CV_MAX_DIM], dstofs[CV_MAX_DIM], esz = elemSize();
|
||||
for( i = 0; i < (size_t)dims; i++ )
|
||||
size_t sz[CV_MAX_DIM] = {1}, srcofs[CV_MAX_DIM]={0}, dstofs[CV_MAX_DIM]={0};
|
||||
size_t esz = elemSize();
|
||||
int i, d = std::max(dims, 1);
|
||||
for( i = 0; i < d; i++ )
|
||||
sz[i] = size.p[i];
|
||||
sz[dims-1] *= esz;
|
||||
sz[d-1] *= esz;
|
||||
ndoffset(srcofs);
|
||||
srcofs[dims-1] *= esz;
|
||||
srcofs[d-1] *= esz;
|
||||
|
||||
_dst.create( dims, size.p, type() );
|
||||
if( _dst.isUMat() )
|
||||
@@ -1175,13 +1210,13 @@ void UMat::copyTo(OutputArray _dst) const
|
||||
{
|
||||
dst.ndoffset(dstofs);
|
||||
dstofs[dims-1] *= esz;
|
||||
u->currAllocator->copy(u, dst.u, dims, sz, srcofs, step.p, dstofs, dst.step.p, false);
|
||||
u->currAllocator->copy(u, dst.u, d, sz, srcofs, step.p, dstofs, dst.step.p, false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Mat dst = _dst.getMat();
|
||||
u->currAllocator->download(u, dst.ptr(), dims, sz, srcofs, step.p, dst.step.p);
|
||||
u->currAllocator->download(u, dst.ptr(), d, sz, srcofs, step.p, dst.step.p);
|
||||
}
|
||||
|
||||
void UMat::copyTo(OutputArray _dst, InputArray _mask) const
|
||||
|
||||
Reference in New Issue
Block a user