made createContinuous & ensureSizeIsEnough generic (OutputArray support)
This commit is contained in:
parent
f17b836d24
commit
1db4afac6a
@ -252,11 +252,11 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
//! creates continuous GPU matrix
|
//! creates continuous GPU matrix
|
||||||
CV_EXPORTS void createContinuous(int rows, int cols, int type, GpuMat& m);
|
CV_EXPORTS void createContinuous(int rows, int cols, int type, OutputArray arr);
|
||||||
|
|
||||||
//! ensures that size of the given matrix is not less than (rows, cols) size
|
//! ensures that size of the given matrix is not less than (rows, cols) size
|
||||||
//! and matrix type is match specified one too
|
//! and matrix type is match specified one too
|
||||||
CV_EXPORTS void ensureSizeIsEnough(int rows, int cols, int type, GpuMat& m);
|
CV_EXPORTS void ensureSizeIsEnough(int rows, int cols, int type, OutputArray arr);
|
||||||
|
|
||||||
CV_EXPORTS GpuMat allocMatFromBuf(int rows, int cols, int type, GpuMat& mat);
|
CV_EXPORTS GpuMat allocMatFromBuf(int rows, int cols, int type, GpuMat& mat);
|
||||||
|
|
||||||
@ -296,6 +296,10 @@ public:
|
|||||||
void create(int rows, int cols, int type);
|
void create(int rows, int cols, int type);
|
||||||
void create(Size size, int type);
|
void create(Size size, int type);
|
||||||
|
|
||||||
|
//! creates alternative CudaMem header for the same data, with different
|
||||||
|
//! number of channels and/or different number of rows
|
||||||
|
CudaMem reshape(int cn, int rows = 0) const;
|
||||||
|
|
||||||
//! decrements reference counter and released memory if needed.
|
//! decrements reference counter and released memory if needed.
|
||||||
void release();
|
void release();
|
||||||
|
|
||||||
|
@ -347,9 +347,9 @@ GpuMat createContinuous(int rows, int cols, int type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
void createContinuous(Size size, int type, GpuMat& m)
|
void createContinuous(Size size, int type, OutputArray arr)
|
||||||
{
|
{
|
||||||
createContinuous(size.height, size.width, type, m);
|
createContinuous(size.height, size.width, type, arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
@ -361,9 +361,9 @@ GpuMat createContinuous(Size size, int type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
void ensureSizeIsEnough(Size size, int type, GpuMat& m)
|
void ensureSizeIsEnough(Size size, int type, OutputArray arr)
|
||||||
{
|
{
|
||||||
ensureSizeIsEnough(size.height, size.width, type, m);
|
ensureSizeIsEnough(size.height, size.width, type, arr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline
|
static inline
|
||||||
|
@ -121,6 +121,49 @@ void cv::gpu::CudaMem::create(int rows_, int cols_, int type_)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CudaMem cv::gpu::CudaMem::reshape(int new_cn, int new_rows) const
|
||||||
|
{
|
||||||
|
CudaMem hdr = *this;
|
||||||
|
|
||||||
|
int cn = channels();
|
||||||
|
if (new_cn == 0)
|
||||||
|
new_cn = cn;
|
||||||
|
|
||||||
|
int total_width = cols * cn;
|
||||||
|
|
||||||
|
if ((new_cn > total_width || total_width % new_cn != 0) && new_rows == 0)
|
||||||
|
new_rows = rows * total_width / new_cn;
|
||||||
|
|
||||||
|
if (new_rows != 0 && new_rows != rows)
|
||||||
|
{
|
||||||
|
int total_size = total_width * rows;
|
||||||
|
|
||||||
|
if (!isContinuous())
|
||||||
|
CV_Error(cv::Error::BadStep, "The matrix is not continuous, thus its number of rows can not be changed");
|
||||||
|
|
||||||
|
if ((unsigned)new_rows > (unsigned)total_size)
|
||||||
|
CV_Error(cv::Error::StsOutOfRange, "Bad new number of rows");
|
||||||
|
|
||||||
|
total_width = total_size / new_rows;
|
||||||
|
|
||||||
|
if (total_width * new_rows != total_size)
|
||||||
|
CV_Error(cv::Error::StsBadArg, "The total number of matrix elements is not divisible by the new number of rows");
|
||||||
|
|
||||||
|
hdr.rows = new_rows;
|
||||||
|
hdr.step = total_width * elemSize1();
|
||||||
|
}
|
||||||
|
|
||||||
|
int new_width = total_width / new_cn;
|
||||||
|
|
||||||
|
if (new_width * new_cn != total_width)
|
||||||
|
CV_Error(cv::Error::BadNumChannels, "The total width is not divisible by the new number of channels");
|
||||||
|
|
||||||
|
hdr.cols = new_width;
|
||||||
|
hdr.flags = (hdr.flags & ~CV_MAT_CN_MASK) | ((new_cn - 1) << CV_CN_SHIFT);
|
||||||
|
|
||||||
|
return hdr;
|
||||||
|
}
|
||||||
|
|
||||||
void cv::gpu::CudaMem::release()
|
void cv::gpu::CudaMem::release()
|
||||||
{
|
{
|
||||||
#ifdef HAVE_CUDA
|
#ifdef HAVE_CUDA
|
||||||
|
@ -1022,48 +1022,95 @@ GpuMat& cv::gpu::GpuMat::adjustROI(int dtop, int dbottom, int dleft, int dright)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cv::gpu::createContinuous(int rows, int cols, int type, GpuMat& m)
|
namespace
|
||||||
{
|
{
|
||||||
const int area = rows * cols;
|
template <class ObjType>
|
||||||
|
void createContinuousImpl(int rows, int cols, int type, ObjType& obj)
|
||||||
|
{
|
||||||
|
const int area = rows * cols;
|
||||||
|
|
||||||
if (m.empty() || m.type() != type || !m.isContinuous() || m.size().area() < area)
|
if (obj.empty() || obj.type() != type || !obj.isContinuous() || obj.size().area() < area)
|
||||||
m.create(1, area, type);
|
obj.create(1, area, type);
|
||||||
|
|
||||||
m.cols = cols;
|
obj = obj.reshape(obj.channels(), rows);
|
||||||
m.rows = rows;
|
}
|
||||||
m.step = m.elemSize() * cols;
|
|
||||||
m.flags |= Mat::CONTINUOUS_FLAG;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void cv::gpu::ensureSizeIsEnough(int rows, int cols, int type, GpuMat& m)
|
void cv::gpu::createContinuous(int rows, int cols, int type, OutputArray arr)
|
||||||
{
|
{
|
||||||
if (m.empty() || m.type() != type || m.data != m.datastart)
|
switch (arr.kind())
|
||||||
{
|
{
|
||||||
m.create(rows, cols, type);
|
case _InputArray::MAT:
|
||||||
|
::createContinuousImpl(rows, cols, type, arr.getMatRef());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case _InputArray::GPU_MAT:
|
||||||
|
::createContinuousImpl(rows, cols, type, arr.getGpuMatRef());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case _InputArray::CUDA_MEM:
|
||||||
|
::createContinuousImpl(rows, cols, type, arr.getCudaMemRef());
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
arr.create(rows, cols, type);
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
template <class ObjType>
|
||||||
|
void ensureSizeIsEnoughImpl(int rows, int cols, int type, ObjType& obj)
|
||||||
{
|
{
|
||||||
const size_t esz = m.elemSize();
|
if (obj.empty() || obj.type() != type || obj.data != obj.datastart)
|
||||||
const ptrdiff_t delta2 = m.dataend - m.datastart;
|
|
||||||
|
|
||||||
const size_t minstep = m.cols * esz;
|
|
||||||
|
|
||||||
Size wholeSize;
|
|
||||||
wholeSize.height = std::max(static_cast<int>((delta2 - minstep) / m.step + 1), m.rows);
|
|
||||||
wholeSize.width = std::max(static_cast<int>((delta2 - m.step * (wholeSize.height - 1)) / esz), m.cols);
|
|
||||||
|
|
||||||
if (wholeSize.height < rows || wholeSize.width < cols)
|
|
||||||
{
|
{
|
||||||
m.create(rows, cols, type);
|
obj.create(rows, cols, type);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m.cols = cols;
|
const size_t esz = obj.elemSize();
|
||||||
m.rows = rows;
|
const ptrdiff_t delta2 = obj.dataend - obj.datastart;
|
||||||
|
|
||||||
|
const size_t minstep = obj.cols * esz;
|
||||||
|
|
||||||
|
Size wholeSize;
|
||||||
|
wholeSize.height = std::max(static_cast<int>((delta2 - minstep) / static_cast<size_t>(obj.step) + 1), obj.rows);
|
||||||
|
wholeSize.width = std::max(static_cast<int>((delta2 - static_cast<size_t>(obj.step) * (wholeSize.height - 1)) / esz), obj.cols);
|
||||||
|
|
||||||
|
if (wholeSize.height < rows || wholeSize.width < cols)
|
||||||
|
{
|
||||||
|
obj.create(rows, cols, type);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
obj.cols = cols;
|
||||||
|
obj.rows = rows;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cv::gpu::ensureSizeIsEnough(int rows, int cols, int type, OutputArray arr)
|
||||||
|
{
|
||||||
|
switch (arr.kind())
|
||||||
|
{
|
||||||
|
case _InputArray::MAT:
|
||||||
|
::ensureSizeIsEnoughImpl(rows, cols, type, arr.getMatRef());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case _InputArray::GPU_MAT:
|
||||||
|
::ensureSizeIsEnoughImpl(rows, cols, type, arr.getGpuMatRef());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case _InputArray::CUDA_MEM:
|
||||||
|
::ensureSizeIsEnoughImpl(rows, cols, type, arr.getCudaMemRef());
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
arr.create(rows, cols, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
GpuMat cv::gpu::allocMatFromBuf(int rows, int cols, int type, GpuMat& mat)
|
GpuMat cv::gpu::allocMatFromBuf(int rows, int cols, int type, GpuMat& mat)
|
||||||
{
|
{
|
||||||
if (!mat.empty() && mat.type() == type && mat.rows >= rows && mat.cols >= cols)
|
if (!mat.empty() && mat.type() == type && mat.rows >= rows && mat.cols >= cols)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user