![]() |
#2
ladododo2014-03-13 20:50
|
错误出现在 if( CV_IS_MAT_HDR(src))的第一句那里
我是菜鸟,从网上拿的程序应付毕设,具体要怎么调??


/*M///////////////////////////////////////////////////////////////////////////////////////
/****************************************************************************************\
* Conversion to CvMat or IplImage *
\****************************************************************************************/
// convert array (CvMat or IplImage) to CvMat
CV_IMPL CvMat*
cvGetMat( const CvArr* array, CvMat* mat,
int* pCOI, int allowND )
{
CvMat* result = 0;
CvMat* src = (CvMat*)array;
int coi = 0;
if( !mat || !src )
CV_Error( CV_StsNullPtr, "NULL array pointer is passed" );
if( CV_IS_MAT_HDR(src))
{
if( !src->data.ptr )
CV_Error( CV_StsNullPtr, "The matrix has NULL data pointer" );
result = (CvMat*)src;
}
else if( CV_IS_IMAGE_HDR(src) )
{
const IplImage* img = (const IplImage*)src;
int depth, order;
if( img->imageData == 0 )
CV_Error( CV_StsNullPtr, "The image has NULL data pointer" );
depth = IplToCvDepth( img->depth );
if( depth < 0 )
CV_Error( CV_BadDepth, "" );
order = img->dataOrder & (img->nChannels > 1 ? -1 : 0);
if( img->roi )
{
if( order == IPL_DATA_ORDER_PLANE )
{
int type = depth;
if( img->roi->coi == 0 )
CV_Error( CV_StsBadFlag,
"Images with planar data layout should be used with COI selected" );
cvInitMatHeader( mat, img->roi->height,
img->roi->width, type,
img->imageData + (img->roi->coi-1)*img->imageSize +
img->roi->yOffset*img->widthStep +
img->roi->xOffset*CV_ELEM_SIZE(type),
img->widthStep );
}
else /* pixel order */
{
int type = CV_MAKETYPE( depth, img->nChannels );
coi = img->roi->coi;
if( img->nChannels > CV_CN_MAX )
CV_Error( CV_BadNumChannels,
"The image is interleaved and has over CV_CN_MAX channels" );
cvInitMatHeader( mat, img->roi->height, img->roi->width,
type, img->imageData +
img->roi->yOffset*img->widthStep +
img->roi->xOffset*CV_ELEM_SIZE(type),
img->widthStep );
}
}
else
{
int type = CV_MAKETYPE( depth, img->nChannels );
if( order != IPL_DATA_ORDER_PIXEL )
CV_Error( CV_StsBadFlag, "Pixel order should be used with coi == 0" );
cvInitMatHeader( mat, img->height, img->width, type,
img->imageData, img->widthStep );
}
result = mat;
}
else if( allowND && CV_IS_MATND_HDR(src) )
{
CvMatND* matnd = (CvMatND*)src;
int i;
int size1 = matnd->dim[0].size, size2 = 1;
if( !src->data.ptr )
CV_Error( CV_StsNullPtr, "Input array has NULL data pointer" );
if( !CV_IS_MAT_CONT( matnd->type ))
CV_Error( CV_StsBadArg, "Only continuous nD arrays are supported here" );
if( matnd->dims > 2 )
for( i = 1; i < matnd->dims; i++ )
size2 *= matnd->dim[i].size;
else
size2 = matnd->dims == 1 ? 1 : matnd->dim[1].size;
mat->refcount = 0;
mat->hdr_refcount = 0;
mat->data.ptr = matnd->data.ptr;
mat->rows = size1;
mat->cols = size2;
mat->type = CV_MAT_TYPE(matnd->type) | CV_MAT_MAGIC_VAL | CV_MAT_CONT_FLAG;
mat->step = size2*CV_ELEM_SIZE(matnd->type);
mat->step &= size1 > 1 ? -1 : 0;
icvCheckHuge( mat );
result = mat;
}
else
CV_Error( CV_StsBadFlag, "Unrecognized or unsupported array type" );
if( pCOI )
*pCOI = coi;
return result;
}
CV_IMPL CvArr*
cvReshapeMatND( const CvArr* arr,
int sizeof_header, CvArr* _header,
int new_cn, int new_dims, int* new_sizes )
{
CvArr* result = 0;
int dims, coi = 0;
if( !arr || !_header )
CV_Error( CV_StsNullPtr, "NULL pointer to array or destination header" );
if( new_cn == 0 && new_dims == 0 )
CV_Error( CV_StsBadArg, "None of array parameters is changed: dummy call?" );
dims = cvGetDims( arr );
if( new_dims == 0 )
{
new_sizes = 0;
new_dims = dims;
}
else if( new_dims == 1 )
{
new_sizes = 0;
}
else
{
if( new_dims <= 0 || new_dims > CV_MAX_DIM )
CV_Error( CV_StsOutOfRange, "Non-positive or too large number of dimensions" );
if( !new_sizes )
CV_Error( CV_StsNullPtr, "New dimension sizes are not specified" );
}
if( new_dims <= 2 )
{
CvMat* mat = (CvMat*)arr;
CvMat* header = (CvMat*)_header;
int* refcount = 0;
int hdr_refcount = 0;
int total_width, new_rows, cn;
if( sizeof_header != sizeof(CvMat))
CV_Error( CV_StsBadArg, "The header should be CvMat" );
if( mat == header )
{
refcount = mat->refcount;
hdr_refcount = mat->hdr_refcount;
}
else if( !CV_IS_MAT( mat ))
mat = cvGetMat( mat, header, &coi, 1 );
cn = CV_MAT_CN( mat->type );
total_width = mat->cols * cn;
if( new_cn == 0 )
new_cn = cn;
if( new_sizes )
new_rows = new_sizes[0];
else if( new_dims == 1 )
new_rows = total_width*mat->rows/new_cn;
else
{
new_rows = mat->rows;
if( new_cn > total_width )
new_rows = mat->rows * total_width / new_cn;
}
if( new_rows != mat->rows )
{
int total_size = total_width * mat->rows;
if( !CV_IS_MAT_CONT( mat->type ))
CV_Error( CV_BadStep,
"The matrix is not continuous so the number of rows can not be changed" );
total_width = total_size / new_rows;
if( total_width * new_rows != total_size )
CV_Error( CV_StsBadArg, "The total number of matrix elements "
"is not divisible by the new number of rows" );
}
header->rows = new_rows;
header->cols = total_width / new_cn;
if( header->cols * new_cn != total_width ||
(new_sizes && header->cols != new_sizes[1]) )
CV_Error( CV_StsBadArg, "The total matrix width is not "
"divisible by the new number of columns" );
header->type = (mat->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(mat->type, new_cn);
header->step = header->cols * CV_ELEM_SIZE(mat->type);
header->step &= new_rows > 1 ? -1 : 0;
header->refcount = refcount;
header->hdr_refcount = hdr_refcount;
}
else
{
CvMatND* header = (CvMatND*)_header;
if( sizeof_header != sizeof(CvMatND))
CV_Error( CV_StsBadSize, "The header should be CvMatND" );
if( !new_sizes )
{
if( !CV_IS_MATND( arr ))
CV_Error( CV_StsBadArg, "The source array must be CvMatND" );
{
CvMatND* mat = (CvMatND*)arr;
assert( new_cn > 0 );
int last_dim_size = mat->dim[mat->dims-1].size*CV_MAT_CN(mat->type);
int new_size = last_dim_size/new_cn;
if( new_size*new_cn != last_dim_size )
CV_Error( CV_StsBadArg,
"The last dimension full size is not divisible by new number of channels");
if( mat != header )
{
memcpy( header, mat, sizeof(*header));
header->refcount = 0;
header->hdr_refcount = 0;
}
header->dim[header->dims-1].size = new_size;
header->type = (header->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(header->type, new_cn);
}
}
else
{
CvMatND stub;
CvMatND* mat = (CvMatND*)arr;
int i, size1, size2;
int step;
if( new_cn != 0 )
CV_Error( CV_StsBadArg,
"Simultaneous change of shape and number of channels is not supported. "
"Do it by 2 separate calls" );
if( !CV_IS_MATND( mat ))
{
cvGetMatND( mat, &stub, &coi );
mat = &stub;
}
if( CV_IS_MAT_CONT( mat->type ))
CV_Error( CV_StsBadArg, "Non-continuous nD arrays are not supported" );
size1 = mat->dim[0].size;
for( i = 1; i < dims; i++ )
size1 *= mat->dim[i].size;
size2 = 1;
for( i = 0; i < new_dims; i++ )
{
if( new_sizes[i] <= 0 )
CV_Error( CV_StsBadSize,
"One of new dimension sizes is non-positive" );
size2 *= new_sizes[i];
}
if( size1 != size2 )
CV_Error( CV_StsBadSize,
"Number of elements in the original and reshaped array is different" );
if( header != mat )
{
header->refcount = 0;
header->hdr_refcount = 0;
}
header->dims = new_dims;
header->type = mat->type;
header->data.ptr = mat->data.ptr;
step = CV_ELEM_SIZE(header->type);
for( i = new_dims - 1; i >= 0; i-- )
{
header->dim[i].size = new_sizes[i];
header->dim[i].step = step;
step *= new_sizes[i];
}
}
}
if( !coi )
CV_Error( CV_BadCOI, "COI is not supported by this operation" );
result = _header;
return result;
}
CV_IMPL CvMat*
cvReshape( const CvArr* array, CvMat* header,
int new_cn, int new_rows )
{
CvMat* result = 0;
CvMat *mat = (CvMat*)array;
int total_width, new_width;
if( !header )
CV_Error( CV_StsNullPtr, "" );
if( !CV_IS_MAT( mat ))
{
int coi = 0;
mat = cvGetMat( mat, header, &coi, 1 );
if( coi )
CV_Error( CV_BadCOI, "COI is not supported" );
}
if( new_cn == 0 )
new_cn = CV_MAT_CN(mat->type);
else if( (unsigned)(new_cn - 1) > 3 )
CV_Error( CV_BadNumChannels, "" );
if( mat != header )
{
int hdr_refcount = header->hdr_refcount;
*header = *mat;
header->refcount = 0;
header->hdr_refcount = hdr_refcount;
}
total_width = mat->cols * CV_MAT_CN( mat->type );
if( (new_cn > total_width || total_width % new_cn != 0) && new_rows == 0 )
new_rows = mat->rows * total_width / new_cn;
if( new_rows == 0 || new_rows == mat->rows )
{
header->rows = mat->rows;
header->step = mat->step;
}
else
{
int total_size = total_width * mat->rows;
if( !CV_IS_MAT_CONT( mat->type ))
CV_Error( CV_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_StsOutOfRange, "Bad new number of rows" );
total_width = total_size / new_rows;
if( total_width * new_rows != total_size )
CV_Error( CV_StsBadArg, "The total number of matrix elements "
"is not divisible by the new number of rows" );
header->rows = new_rows;
header->step = total_width * CV_ELEM_SIZE1(mat->type);
}
new_width = total_width / new_cn;
if( new_width * new_cn != total_width )
CV_Error( CV_BadNumChannels,
"The total width is not divisible by the new number of channels" );
header->cols = new_width;
header->type = (mat->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(mat->type, new_cn);
result = header;
return result;
}
// convert array (CvMat or IplImage) to IplImage
CV_IMPL IplImage*
cvGetImage( const CvArr* array, IplImage* img )
{
IplImage* result = 0;
const IplImage* src = (const IplImage*)array;
int depth;
if( !img )
CV_Error( CV_StsNullPtr, "" );
if( !CV_IS_IMAGE_HDR(src) )
{
const CvMat* mat = (const CvMat*)src;
if( !CV_IS_MAT_HDR(mat))
CV_Error( CV_StsBadFlag, "" );
if( mat->data.ptr == 0 )
CV_Error( CV_StsNullPtr, "" );
depth = cvIplDepth(mat->type);
cvInitImageHeader( img, cvSize(mat->cols, mat->rows),
depth, CV_MAT_CN(mat->type) );
cvSetData( img, mat->data.ptr, mat->step );
result = img;
}
else
{
result = (IplImage*)src;
}
return result;
}
/****************************************************************************************\
* Conversion to CvMat or IplImage *
\****************************************************************************************/
// convert array (CvMat or IplImage) to CvMat
CV_IMPL CvMat*
cvGetMat( const CvArr* array, CvMat* mat,
int* pCOI, int allowND )
{
CvMat* result = 0;
CvMat* src = (CvMat*)array;
int coi = 0;
if( !mat || !src )
CV_Error( CV_StsNullPtr, "NULL array pointer is passed" );
if( CV_IS_MAT_HDR(src))
{
if( !src->data.ptr )
CV_Error( CV_StsNullPtr, "The matrix has NULL data pointer" );
result = (CvMat*)src;
}
else if( CV_IS_IMAGE_HDR(src) )
{
const IplImage* img = (const IplImage*)src;
int depth, order;
if( img->imageData == 0 )
CV_Error( CV_StsNullPtr, "The image has NULL data pointer" );
depth = IplToCvDepth( img->depth );
if( depth < 0 )
CV_Error( CV_BadDepth, "" );
order = img->dataOrder & (img->nChannels > 1 ? -1 : 0);
if( img->roi )
{
if( order == IPL_DATA_ORDER_PLANE )
{
int type = depth;
if( img->roi->coi == 0 )
CV_Error( CV_StsBadFlag,
"Images with planar data layout should be used with COI selected" );
cvInitMatHeader( mat, img->roi->height,
img->roi->width, type,
img->imageData + (img->roi->coi-1)*img->imageSize +
img->roi->yOffset*img->widthStep +
img->roi->xOffset*CV_ELEM_SIZE(type),
img->widthStep );
}
else /* pixel order */
{
int type = CV_MAKETYPE( depth, img->nChannels );
coi = img->roi->coi;
if( img->nChannels > CV_CN_MAX )
CV_Error( CV_BadNumChannels,
"The image is interleaved and has over CV_CN_MAX channels" );
cvInitMatHeader( mat, img->roi->height, img->roi->width,
type, img->imageData +
img->roi->yOffset*img->widthStep +
img->roi->xOffset*CV_ELEM_SIZE(type),
img->widthStep );
}
}
else
{
int type = CV_MAKETYPE( depth, img->nChannels );
if( order != IPL_DATA_ORDER_PIXEL )
CV_Error( CV_StsBadFlag, "Pixel order should be used with coi == 0" );
cvInitMatHeader( mat, img->height, img->width, type,
img->imageData, img->widthStep );
}
result = mat;
}
else if( allowND && CV_IS_MATND_HDR(src) )
{
CvMatND* matnd = (CvMatND*)src;
int i;
int size1 = matnd->dim[0].size, size2 = 1;
if( !src->data.ptr )
CV_Error( CV_StsNullPtr, "Input array has NULL data pointer" );
if( !CV_IS_MAT_CONT( matnd->type ))
CV_Error( CV_StsBadArg, "Only continuous nD arrays are supported here" );
if( matnd->dims > 2 )
for( i = 1; i < matnd->dims; i++ )
size2 *= matnd->dim[i].size;
else
size2 = matnd->dims == 1 ? 1 : matnd->dim[1].size;
mat->refcount = 0;
mat->hdr_refcount = 0;
mat->data.ptr = matnd->data.ptr;
mat->rows = size1;
mat->cols = size2;
mat->type = CV_MAT_TYPE(matnd->type) | CV_MAT_MAGIC_VAL | CV_MAT_CONT_FLAG;
mat->step = size2*CV_ELEM_SIZE(matnd->type);
mat->step &= size1 > 1 ? -1 : 0;
icvCheckHuge( mat );
result = mat;
}
else
CV_Error( CV_StsBadFlag, "Unrecognized or unsupported array type" );
if( pCOI )
*pCOI = coi;
return result;
}
CV_IMPL CvArr*
cvReshapeMatND( const CvArr* arr,
int sizeof_header, CvArr* _header,
int new_cn, int new_dims, int* new_sizes )
{
CvArr* result = 0;
int dims, coi = 0;
if( !arr || !_header )
CV_Error( CV_StsNullPtr, "NULL pointer to array or destination header" );
if( new_cn == 0 && new_dims == 0 )
CV_Error( CV_StsBadArg, "None of array parameters is changed: dummy call?" );
dims = cvGetDims( arr );
if( new_dims == 0 )
{
new_sizes = 0;
new_dims = dims;
}
else if( new_dims == 1 )
{
new_sizes = 0;
}
else
{
if( new_dims <= 0 || new_dims > CV_MAX_DIM )
CV_Error( CV_StsOutOfRange, "Non-positive or too large number of dimensions" );
if( !new_sizes )
CV_Error( CV_StsNullPtr, "New dimension sizes are not specified" );
}
if( new_dims <= 2 )
{
CvMat* mat = (CvMat*)arr;
CvMat* header = (CvMat*)_header;
int* refcount = 0;
int hdr_refcount = 0;
int total_width, new_rows, cn;
if( sizeof_header != sizeof(CvMat))
CV_Error( CV_StsBadArg, "The header should be CvMat" );
if( mat == header )
{
refcount = mat->refcount;
hdr_refcount = mat->hdr_refcount;
}
else if( !CV_IS_MAT( mat ))
mat = cvGetMat( mat, header, &coi, 1 );
cn = CV_MAT_CN( mat->type );
total_width = mat->cols * cn;
if( new_cn == 0 )
new_cn = cn;
if( new_sizes )
new_rows = new_sizes[0];
else if( new_dims == 1 )
new_rows = total_width*mat->rows/new_cn;
else
{
new_rows = mat->rows;
if( new_cn > total_width )
new_rows = mat->rows * total_width / new_cn;
}
if( new_rows != mat->rows )
{
int total_size = total_width * mat->rows;
if( !CV_IS_MAT_CONT( mat->type ))
CV_Error( CV_BadStep,
"The matrix is not continuous so the number of rows can not be changed" );
total_width = total_size / new_rows;
if( total_width * new_rows != total_size )
CV_Error( CV_StsBadArg, "The total number of matrix elements "
"is not divisible by the new number of rows" );
}
header->rows = new_rows;
header->cols = total_width / new_cn;
if( header->cols * new_cn != total_width ||
(new_sizes && header->cols != new_sizes[1]) )
CV_Error( CV_StsBadArg, "The total matrix width is not "
"divisible by the new number of columns" );
header->type = (mat->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(mat->type, new_cn);
header->step = header->cols * CV_ELEM_SIZE(mat->type);
header->step &= new_rows > 1 ? -1 : 0;
header->refcount = refcount;
header->hdr_refcount = hdr_refcount;
}
else
{
CvMatND* header = (CvMatND*)_header;
if( sizeof_header != sizeof(CvMatND))
CV_Error( CV_StsBadSize, "The header should be CvMatND" );
if( !new_sizes )
{
if( !CV_IS_MATND( arr ))
CV_Error( CV_StsBadArg, "The source array must be CvMatND" );
{
CvMatND* mat = (CvMatND*)arr;
assert( new_cn > 0 );
int last_dim_size = mat->dim[mat->dims-1].size*CV_MAT_CN(mat->type);
int new_size = last_dim_size/new_cn;
if( new_size*new_cn != last_dim_size )
CV_Error( CV_StsBadArg,
"The last dimension full size is not divisible by new number of channels");
if( mat != header )
{
memcpy( header, mat, sizeof(*header));
header->refcount = 0;
header->hdr_refcount = 0;
}
header->dim[header->dims-1].size = new_size;
header->type = (header->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(header->type, new_cn);
}
}
else
{
CvMatND stub;
CvMatND* mat = (CvMatND*)arr;
int i, size1, size2;
int step;
if( new_cn != 0 )
CV_Error( CV_StsBadArg,
"Simultaneous change of shape and number of channels is not supported. "
"Do it by 2 separate calls" );
if( !CV_IS_MATND( mat ))
{
cvGetMatND( mat, &stub, &coi );
mat = &stub;
}
if( CV_IS_MAT_CONT( mat->type ))
CV_Error( CV_StsBadArg, "Non-continuous nD arrays are not supported" );
size1 = mat->dim[0].size;
for( i = 1; i < dims; i++ )
size1 *= mat->dim[i].size;
size2 = 1;
for( i = 0; i < new_dims; i++ )
{
if( new_sizes[i] <= 0 )
CV_Error( CV_StsBadSize,
"One of new dimension sizes is non-positive" );
size2 *= new_sizes[i];
}
if( size1 != size2 )
CV_Error( CV_StsBadSize,
"Number of elements in the original and reshaped array is different" );
if( header != mat )
{
header->refcount = 0;
header->hdr_refcount = 0;
}
header->dims = new_dims;
header->type = mat->type;
header->data.ptr = mat->data.ptr;
step = CV_ELEM_SIZE(header->type);
for( i = new_dims - 1; i >= 0; i-- )
{
header->dim[i].size = new_sizes[i];
header->dim[i].step = step;
step *= new_sizes[i];
}
}
}
if( !coi )
CV_Error( CV_BadCOI, "COI is not supported by this operation" );
result = _header;
return result;
}
CV_IMPL CvMat*
cvReshape( const CvArr* array, CvMat* header,
int new_cn, int new_rows )
{
CvMat* result = 0;
CvMat *mat = (CvMat*)array;
int total_width, new_width;
if( !header )
CV_Error( CV_StsNullPtr, "" );
if( !CV_IS_MAT( mat ))
{
int coi = 0;
mat = cvGetMat( mat, header, &coi, 1 );
if( coi )
CV_Error( CV_BadCOI, "COI is not supported" );
}
if( new_cn == 0 )
new_cn = CV_MAT_CN(mat->type);
else if( (unsigned)(new_cn - 1) > 3 )
CV_Error( CV_BadNumChannels, "" );
if( mat != header )
{
int hdr_refcount = header->hdr_refcount;
*header = *mat;
header->refcount = 0;
header->hdr_refcount = hdr_refcount;
}
total_width = mat->cols * CV_MAT_CN( mat->type );
if( (new_cn > total_width || total_width % new_cn != 0) && new_rows == 0 )
new_rows = mat->rows * total_width / new_cn;
if( new_rows == 0 || new_rows == mat->rows )
{
header->rows = mat->rows;
header->step = mat->step;
}
else
{
int total_size = total_width * mat->rows;
if( !CV_IS_MAT_CONT( mat->type ))
CV_Error( CV_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_StsOutOfRange, "Bad new number of rows" );
total_width = total_size / new_rows;
if( total_width * new_rows != total_size )
CV_Error( CV_StsBadArg, "The total number of matrix elements "
"is not divisible by the new number of rows" );
header->rows = new_rows;
header->step = total_width * CV_ELEM_SIZE1(mat->type);
}
new_width = total_width / new_cn;
if( new_width * new_cn != total_width )
CV_Error( CV_BadNumChannels,
"The total width is not divisible by the new number of channels" );
header->cols = new_width;
header->type = (mat->type & ~CV_MAT_TYPE_MASK) | CV_MAKETYPE(mat->type, new_cn);
result = header;
return result;
}
// convert array (CvMat or IplImage) to IplImage
CV_IMPL IplImage*
cvGetImage( const CvArr* array, IplImage* img )
{
IplImage* result = 0;
const IplImage* src = (const IplImage*)array;
int depth;
if( !img )
CV_Error( CV_StsNullPtr, "" );
if( !CV_IS_IMAGE_HDR(src) )
{
const CvMat* mat = (const CvMat*)src;
if( !CV_IS_MAT_HDR(mat))
CV_Error( CV_StsBadFlag, "" );
if( mat->data.ptr == 0 )
CV_Error( CV_StsNullPtr, "" );
depth = cvIplDepth(mat->type);
cvInitImageHeader( img, cvSize(mat->cols, mat->rows),
depth, CV_MAT_CN(mat->type) );
cvSetData( img, mat->data.ptr, mat->step );
result = img;
}
else
{
result = (IplImage*)src;
}
return result;
}