opencv异常提示之 (channels() == CV_MAT_CN(dtype)) in copyTo (暂未解决,提供源码)
2016-05-01 23:11
761 查看
OpenCV Error: Assertion failed (channels() == CV_MAT_CN(dtype)) in copyTo, file /home/tau/opencv/opencv-3.1.0/modules/core/src/copy.cpp, line 257
terminate called after throwing an instance of 'cv::Exception'
what(): /home/tau/opencv/opencv-3.1.0/modules/core/src/copy.cpp:257: error: (-215) channels() == CV_MAT_CN(dtype) in function copyTo
这个错误是使用fitLine时遇到的
问题出在
void cv::fitLine( InputArray _points, OutputArray _line, int distType,
double param, double reps, double aeps )
最后一行
Mat(npoints2 >= 0 ? 4 : 6, 1, CV_32F, linebuf).copyTo(_line);
而弹出错误的在下面这行
if( _dst.fixedType() && dtype != type() )
{
CV_Assert( channels() == CV_MAT_CN(dtype) );
convertTo( _dst, dtype );
return;
}
先来看看fixedType()
bool _OutputArray::fixedType() const
{
return (flags & FIXED_TYPE) == FIXED_TYPE;
}
其中查到 FIXED_TYPE = 0x8000 << KIND_SHIFT , KIND_SHIFT =16, = 运算优先级 低于 <<
故 FIXED_TYPE 左移16位
flags 是int 变量, 目前没有找到默认初始化的值, 莫非初始化的值是 0 ?
是0的话和肯定就与FIXED_TYPE不相等了, 返回0;
对于Mat dtype就是CV_8U, CV_32F之类的像素值类型
type 就是CV_8UC1,CV_8UC2,CV_8UC3 像素值类型 + 通道
但是下面有定义
int dtype = _dst.type()
type() 返回值是什么? CV_32F?
如果按这个条件推测, if( _dst.fixedType() && dtype != type() )
应该是dtype == type()
而我定义的
不知道_dst.type()是多少
现在, 问题到底出在哪里?
试了很多遍, 高度怀疑此处存在bug, opencv 版本 3.1.0, ubuntu + qt(虽然感觉只和版本有关系)
另外要说参考了opencv内置相关的test函数, OutputArray定义为 std::vector<float>, 然而根本无法调通
class CV_EXPORTS _InputArray
{
public:
enum {
KIND_SHIFT = 16,
FIXED_TYPE = 0x8000 << KIND_SHIFT,
FIXED_SIZE = 0x4000 << KIND_SHIFT,
KIND_MASK = 31 << KIND_SHIFT,
NONE = 0 << KIND_SHIFT,
MAT = 1 << KIND_SHIFT,
MATX = 2 << KIND_SHIFT,
STD_VECTOR = 3 << KIND_SHIFT,
STD_VECTOR_VECTOR = 4 << KIND_SHIFT,
STD_VECTOR_MAT = 5 << KIND_SHIFT,
EXPR = 6 << KIND_SHIFT,
OPENGL_BUFFER = 7 << KIND_SHIFT,
CUDA_HOST_MEM = 8 << KIND_SHIFT,
CUDA_GPU_MAT = 9 << KIND_SHIFT,
UMAT =10 << KIND_SHIFT,
STD_VECTOR_UMAT =11 << KIND_SHIFT,
STD_BOOL_VECTOR =12 << KIND_SHIFT,
STD_VECTOR_CUDA_GPU_MAT = 13 << KIND_SHIFT
};
_InputArray();
_InputArray(int _flags, void* _obj);
_InputArray(const Mat& m);
_InputArray(const MatExpr& expr);
_InputArray(const std::vector<Mat>& vec);
template<typename _Tp> _InputArray(const Mat_<_Tp>& m);
template<typename _Tp> _InputArray(const std::vector<_Tp>& vec);
_InputArray(const std::vector<bool>& vec);
template<typename _Tp> _InputArray(const std::vector<std::vector<_Tp> >& vec);
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 double& val);
_InputArray(const cuda::GpuMat& d_mat);
_InputArray(const std::vector<cuda::GpuMat>& d_mat_array);
_InputArray(const ogl::Buffer& buf);
_InputArray(const cuda::HostMem& cuda_mem);
template<typename _Tp> _InputArray(const cudev::GpuMat_<_Tp>& m);
_InputArray(const UMat& um);
_InputArray(const std::vector<UMat>& umv);
Mat getMat(int idx=-1) const;
Mat getMat_(int idx=-1) const;
UMat getUMat(int idx=-1) const;
void getMatVector(std::vector<Mat>& mv) const;
void getUMatVector(std::vector<UMat>& umv) const;
void getGpuMatVector(std::vector<cuda::GpuMat>& gpumv) const;
cuda::GpuMat getGpuMat() const;
ogl::Buffer getOGlBuffer() const;
int getFlags() const;
void* getObj() const;
Size getSz() const;
int kind() const;
int dims(int i=-1) const;
int cols(int i=-1) const;
int rows(int i=-1) const;
Size size(int i=-1) const;
int sizend(int* sz, int i=-1) const;
bool sameSize(const _InputArray& arr) const;
size_t total(int i=-1) const;
int type(int i=-1) const;
int depth(int i=-1) const;
int channels(int i=-1) const;
bool isContinuous(int i=-1) const;
bool isSubmatrix(int i=-1) const;
bool empty() const;
void copyTo(const _OutputArray& arr) const;
void copyTo(const _OutputArray& arr, const _InputArray & mask) const;
size_t offset(int i=-1) const;
size_t step(int i=-1) const;
bool isMat() const;
bool isUMat() const;
bool isMatVector() const;
bool isUMatVector() const;
bool isMatx() const;
bool isVector() const;
bool isGpuMatVector() const;
~_InputArray();
protected:
int flags;
void* obj;
Size sz;
void init(int _flags, const void* _obj);
void init(int _flags, const void* _obj, Size _sz);
};
copyTo是在 Module/core/copy.cpp中定义
源码
void Mat::copyTo( OutputArray _dst ) const
{
int dtype = _dst.type();
if( _dst.fixedType() && dtype != type() )
{
CV_Assert( channels() == CV_MAT_CN(dtype) );
convertTo( _dst, dtype );
return;
}
if( empty() )
{
_dst.release();
return;
}
if( _dst.isUMat() )
{
_dst.create( dims, size.p, type() );
UMat dst = _dst.getUMat();
size_t i, sz[CV_MAX_DIM], dstofs[CV_MAX_DIM], esz = elemSize();
for( i = 0; i < (size_t)dims; i++ )
sz[i] = size.p[i];
sz[dims-1] *= esz;
dst.ndoffset(dstofs);
dstofs[dims-1] *= esz;
dst.u->currAllocator->upload(dst.u, data, dims, sz, dstofs, dst.step.p, step.p);
return;
}
if( dims <= 2 )
{
_dst.create( rows, cols, type() );
Mat dst = _dst.getMat();
if( data == dst.data )
return;
if( rows > 0 && cols > 0 )
{
// For some cases (with vector) dst.size != src.size, so force to column-based form
// It prevents memory corruption in case of column-based src
if (_dst.isVector())
dst = dst.reshape(0, (int)dst.total());
const uchar* sptr = data;
uchar* dptr = dst.data;
CV_IPP_RUN(
(size_t)cols*elemSize() <= (size_t)INT_MAX &&
(size_t)step <= (size_t)INT_MAX &&
(size_t)dst.step <= (size_t)INT_MAX
,
ippiCopy_8u_C1R(sptr, (int)step, dptr, (int)dst.step, ippiSize((int)(cols*elemSize()), rows)) >= 0
)
Size sz = getContinuousSize(*this, dst);
size_t len = sz.width*elemSize();
for( ; sz.height--; sptr += step, dptr += dst.step )
memcpy( dptr, sptr, len );
}
return;
}
_dst.create( dims, size, type() );
Mat dst = _dst.getMat();
if( data == dst.data )
return;
if( total() != 0 )
{
const Mat* arrays[] = { this, &dst };
uchar* ptrs[2];
NAryMatIterator it(arrays, ptrs, 2);
size_t sz = it.size*elemSize();
for( size_t i = 0; i < it.nplanes; i++, ++it )
memcpy(ptrs[1], ptrs[0], sz);
}
}
void Mat::copyTo( OutputArray _dst, InputArray _mask ) const
{
Mat mask = _mask.getMat();
if( !mask.data )
{
copyTo(_dst);
return;
}
int cn = channels(), mcn = mask.channels();
CV_Assert( mask.depth() == CV_8U && (mcn == 1 || mcn == cn) );
bool colorMask = mcn > 1;
size_t esz = colorMask ? elemSize1() : elemSize();
BinaryFunc copymask = getCopyMaskFunc(esz);
uchar* data0 = _dst.getMat().data;
_dst.create( dims, size, type() );
Mat dst = _dst.getMat();
if( dst.data != data0 ) // do not leave dst uninitialized
dst = Scalar(0);
if( dims <= 2 )
{
CV_Assert( size() == mask.size() );
Size sz = getContinuousSize(*this, dst, mask, mcn);
copymask(data, step, mask.data, mask.step, dst.data, dst.step, sz, &esz);
return;
}
const Mat* arrays[] = { this, &dst, &mask, 0 };
uchar* ptrs[3];
NAryMatIterator it(arrays, ptrs);
Size sz((int)(it.size*mcn), 1);
for( size_t i = 0; i < it.nplanes; i++, ++it )
copymask(ptrs[0], 0, ptrs[2], 0, ptrs[1], 0, sz, &esz);
}
terminate called after throwing an instance of 'cv::Exception'
what(): /home/tau/opencv/opencv-3.1.0/modules/core/src/copy.cpp:257: error: (-215) channels() == CV_MAT_CN(dtype) in function copyTo
这个错误是使用fitLine时遇到的
问题出在
void cv::fitLine( InputArray _points, OutputArray _line, int distType,
double param, double reps, double aeps )
最后一行
Mat(npoints2 >= 0 ? 4 : 6, 1, CV_32F, linebuf).copyTo(_line);
而弹出错误的在下面这行
if( _dst.fixedType() && dtype != type() )
{
CV_Assert( channels() == CV_MAT_CN(dtype) );
convertTo( _dst, dtype );
return;
}
先来看看fixedType()
bool _OutputArray::fixedType() const
{
return (flags & FIXED_TYPE) == FIXED_TYPE;
}
其中查到 FIXED_TYPE = 0x8000 << KIND_SHIFT , KIND_SHIFT =16, = 运算优先级 低于 <<
故 FIXED_TYPE 左移16位
flags 是int 变量, 目前没有找到默认初始化的值, 莫非初始化的值是 0 ?
是0的话和肯定就与FIXED_TYPE不相等了, 返回0;
对于Mat dtype就是CV_8U, CV_32F之类的像素值类型
type 就是CV_8UC1,CV_8UC2,CV_8UC3 像素值类型 + 通道
但是下面有定义
int dtype = _dst.type()
type() 返回值是什么? CV_32F?
如果按这个条件推测, if( _dst.fixedType() && dtype != type() )
应该是dtype == type()
而我定义的
std::vector<cv::Vec4f> lines (lines对应_line)
不知道_dst.type()是多少
现在, 问题到底出在哪里?
试了很多遍, 高度怀疑此处存在bug, opencv 版本 3.1.0, ubuntu + qt(虽然感觉只和版本有关系)
另外要说参考了opencv内置相关的test函数, OutputArray定义为 std::vector<float>, 然而根本无法调通
class CV_EXPORTS _InputArray
{
public:
enum {
KIND_SHIFT = 16,
FIXED_TYPE = 0x8000 << KIND_SHIFT,
FIXED_SIZE = 0x4000 << KIND_SHIFT,
KIND_MASK = 31 << KIND_SHIFT,
NONE = 0 << KIND_SHIFT,
MAT = 1 << KIND_SHIFT,
MATX = 2 << KIND_SHIFT,
STD_VECTOR = 3 << KIND_SHIFT,
STD_VECTOR_VECTOR = 4 << KIND_SHIFT,
STD_VECTOR_MAT = 5 << KIND_SHIFT,
EXPR = 6 << KIND_SHIFT,
OPENGL_BUFFER = 7 << KIND_SHIFT,
CUDA_HOST_MEM = 8 << KIND_SHIFT,
CUDA_GPU_MAT = 9 << KIND_SHIFT,
UMAT =10 << KIND_SHIFT,
STD_VECTOR_UMAT =11 << KIND_SHIFT,
STD_BOOL_VECTOR =12 << KIND_SHIFT,
STD_VECTOR_CUDA_GPU_MAT = 13 << KIND_SHIFT
};
_InputArray();
_InputArray(int _flags, void* _obj);
_InputArray(const Mat& m);
_InputArray(const MatExpr& expr);
_InputArray(const std::vector<Mat>& vec);
template<typename _Tp> _InputArray(const Mat_<_Tp>& m);
template<typename _Tp> _InputArray(const std::vector<_Tp>& vec);
_InputArray(const std::vector<bool>& vec);
template<typename _Tp> _InputArray(const std::vector<std::vector<_Tp> >& vec);
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 double& val);
_InputArray(const cuda::GpuMat& d_mat);
_InputArray(const std::vector<cuda::GpuMat>& d_mat_array);
_InputArray(const ogl::Buffer& buf);
_InputArray(const cuda::HostMem& cuda_mem);
template<typename _Tp> _InputArray(const cudev::GpuMat_<_Tp>& m);
_InputArray(const UMat& um);
_InputArray(const std::vector<UMat>& umv);
Mat getMat(int idx=-1) const;
Mat getMat_(int idx=-1) const;
UMat getUMat(int idx=-1) const;
void getMatVector(std::vector<Mat>& mv) const;
void getUMatVector(std::vector<UMat>& umv) const;
void getGpuMatVector(std::vector<cuda::GpuMat>& gpumv) const;
cuda::GpuMat getGpuMat() const;
ogl::Buffer getOGlBuffer() const;
int getFlags() const;
void* getObj() const;
Size getSz() const;
int kind() const;
int dims(int i=-1) const;
int cols(int i=-1) const;
int rows(int i=-1) const;
Size size(int i=-1) const;
int sizend(int* sz, int i=-1) const;
bool sameSize(const _InputArray& arr) const;
size_t total(int i=-1) const;
int type(int i=-1) const;
int depth(int i=-1) const;
int channels(int i=-1) const;
bool isContinuous(int i=-1) const;
bool isSubmatrix(int i=-1) const;
bool empty() const;
void copyTo(const _OutputArray& arr) const;
void copyTo(const _OutputArray& arr, const _InputArray & mask) const;
size_t offset(int i=-1) const;
size_t step(int i=-1) const;
bool isMat() const;
bool isUMat() const;
bool isMatVector() const;
bool isUMatVector() const;
bool isMatx() const;
bool isVector() const;
bool isGpuMatVector() const;
~_InputArray();
protected:
int flags;
void* obj;
Size sz;
void init(int _flags, const void* _obj);
void init(int _flags, const void* _obj, Size _sz);
};
copyTo是在 Module/core/copy.cpp中定义
源码
void Mat::copyTo( OutputArray _dst ) const
{
int dtype = _dst.type();
if( _dst.fixedType() && dtype != type() )
{
CV_Assert( channels() == CV_MAT_CN(dtype) );
convertTo( _dst, dtype );
return;
}
if( empty() )
{
_dst.release();
return;
}
if( _dst.isUMat() )
{
_dst.create( dims, size.p, type() );
UMat dst = _dst.getUMat();
size_t i, sz[CV_MAX_DIM], dstofs[CV_MAX_DIM], esz = elemSize();
for( i = 0; i < (size_t)dims; i++ )
sz[i] = size.p[i];
sz[dims-1] *= esz;
dst.ndoffset(dstofs);
dstofs[dims-1] *= esz;
dst.u->currAllocator->upload(dst.u, data, dims, sz, dstofs, dst.step.p, step.p);
return;
}
if( dims <= 2 )
{
_dst.create( rows, cols, type() );
Mat dst = _dst.getMat();
if( data == dst.data )
return;
if( rows > 0 && cols > 0 )
{
// For some cases (with vector) dst.size != src.size, so force to column-based form
// It prevents memory corruption in case of column-based src
if (_dst.isVector())
dst = dst.reshape(0, (int)dst.total());
const uchar* sptr = data;
uchar* dptr = dst.data;
CV_IPP_RUN(
(size_t)cols*elemSize() <= (size_t)INT_MAX &&
(size_t)step <= (size_t)INT_MAX &&
(size_t)dst.step <= (size_t)INT_MAX
,
ippiCopy_8u_C1R(sptr, (int)step, dptr, (int)dst.step, ippiSize((int)(cols*elemSize()), rows)) >= 0
)
Size sz = getContinuousSize(*this, dst);
size_t len = sz.width*elemSize();
for( ; sz.height--; sptr += step, dptr += dst.step )
memcpy( dptr, sptr, len );
}
return;
}
_dst.create( dims, size, type() );
Mat dst = _dst.getMat();
if( data == dst.data )
return;
if( total() != 0 )
{
const Mat* arrays[] = { this, &dst };
uchar* ptrs[2];
NAryMatIterator it(arrays, ptrs, 2);
size_t sz = it.size*elemSize();
for( size_t i = 0; i < it.nplanes; i++, ++it )
memcpy(ptrs[1], ptrs[0], sz);
}
}
void Mat::copyTo( OutputArray _dst, InputArray _mask ) const
{
Mat mask = _mask.getMat();
if( !mask.data )
{
copyTo(_dst);
return;
}
int cn = channels(), mcn = mask.channels();
CV_Assert( mask.depth() == CV_8U && (mcn == 1 || mcn == cn) );
bool colorMask = mcn > 1;
size_t esz = colorMask ? elemSize1() : elemSize();
BinaryFunc copymask = getCopyMaskFunc(esz);
uchar* data0 = _dst.getMat().data;
_dst.create( dims, size, type() );
Mat dst = _dst.getMat();
if( dst.data != data0 ) // do not leave dst uninitialized
dst = Scalar(0);
if( dims <= 2 )
{
CV_Assert( size() == mask.size() );
Size sz = getContinuousSize(*this, dst, mask, mcn);
copymask(data, step, mask.data, mask.step, dst.data, dst.step, sz, &esz);
return;
}
const Mat* arrays[] = { this, &dst, &mask, 0 };
uchar* ptrs[3];
NAryMatIterator it(arrays, ptrs);
Size sz((int)(it.size*mcn), 1);
for( size_t i = 0; i < it.nplanes; i++, ++it )
copymask(ptrs[0], 0, ptrs[2], 0, ptrs[1], 0, sz, &esz);
}
相关文章推荐
- CentOS6.5系统挂载NTFS分区的移动硬盘
- SM2算法第六篇:Linux Socket编程(不限于Linux)
- Linux内核分析课程总结
- CentOS6.5系统挂载NTFS分区的移动硬盘
- 【BZOJ4582】【Usaco2016 open】Diamond Collector 贪心
- nginx详细配置说明
- Ubuntu12.04编译openwrt过程中遇到的一些问题及处理方法
- linux错误:root@localhost's password
- CentOS SSH安装与配置
- PHP 新特性 linux安装ssh2
- CentOS修改系统的默认启动模式为命令号界面
- Linux内核学习总结
- [Modern OpenGL系列(一)]十步搞定OpenGL开发环境
- Linux下find一次查找多个指定类型文件,指定文件或者排除某类文件 *****
- opencv文件读写(二)使用多种方式及用法
- linux学习总结
- docker安装centos后没有ifconfig命令解决办法
- nova-compute 部署 instance 详解 - 每天5分钟玩转 OpenStack(28)
- nova-compute 部署 instance 详解 - 每天5分钟玩转 OpenStack(28)
- nova-compute 部署 instance 详解 - 每天5分钟玩转 OpenStack(28)