made createContinuous & ensureSizeIsEnough generic (OutputArray support)
This commit is contained in:
parent
f17b836d24
commit
1db4afac6a
@ -252,11 +252,11 @@ public:
|
||||
};
|
||||
|
||||
//! 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
|
||||
//! 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);
|
||||
|
||||
@ -296,6 +296,10 @@ public:
|
||||
void create(int rows, int cols, 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.
|
||||
void release();
|
||||
|
||||
|
@ -347,9 +347,9 @@ GpuMat createContinuous(int rows, int cols, int type)
|
||||
}
|
||||
|
||||
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
|
||||
@ -361,9 +361,9 @@ GpuMat createContinuous(Size size, int type)
|
||||
}
|
||||
|
||||
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
|
||||
|
@ -121,6 +121,49 @@ void cv::gpu::CudaMem::create(int rows_, int cols_, int type_)
|
||||
#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()
|
||||
{
|
||||
#ifdef HAVE_CUDA
|
||||
|
@ -1022,48 +1022,95 @@ GpuMat& cv::gpu::GpuMat::adjustROI(int dtop, int dbottom, int dleft, int dright)
|
||||
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)
|
||||
m.create(1, area, type);
|
||||
if (obj.empty() || obj.type() != type || !obj.isContinuous() || obj.size().area() < area)
|
||||
obj.create(1, area, type);
|
||||
|
||||
m.cols = cols;
|
||||
m.rows = rows;
|
||||
m.step = m.elemSize() * cols;
|
||||
m.flags |= Mat::CONTINUOUS_FLAG;
|
||||
obj = obj.reshape(obj.channels(), rows);
|
||||
}
|
||||
}
|
||||
|
||||
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();
|
||||
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)
|
||||
if (obj.empty() || obj.type() != type || obj.data != obj.datastart)
|
||||
{
|
||||
m.create(rows, cols, type);
|
||||
obj.create(rows, cols, type);
|
||||
}
|
||||
else
|
||||
{
|
||||
m.cols = cols;
|
||||
m.rows = rows;
|
||||
const size_t esz = obj.elemSize();
|
||||
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)
|
||||
{
|
||||
if (!mat.empty() && mat.type() == type && mat.rows >= rows && mat.cols >= cols)
|
||||
|
Loading…
x
Reference in New Issue
Block a user