2D point with integer coordinates
typedef struct CvPoint { int x; /* x-coordinate, usually zero-based */ int y; /* y-coordinate, usually zero-based */ } CvPoint; /* the constructor function */ inline CvPoint cvPoint( int x, int y ); /* conversion from CvPoint2D32f */ inline CvPoint cvPointFrom32f( CvPoint2D32f point );
2D point with floating-point coordinates
typedef struct CvPoint2D32f { float x; /* x-coordinate, usually zero-based */ float y; /* y-coordinate, usually zero-based */ } CvPoint2D32f; /* the constructor function */ inline CvPoint2D32f cvPoint2D32f( double x, double y ); /* conversion from CvPoint */ inline CvPoint2D32f cvPointTo32f( CvPoint point );
3D point with floating-point coordinates
typedef struct CvPoint3D32f { float x; /* x-coordinate, usually zero-based */ float y; /* y-coordinate, usually zero-based */ float z; /* z-coordinate, usually zero-based */ } CvPoint3D32f; /* the constructor function */ inline CvPoint3D32f cvPoint3D32f( double x, double y, double z );
2D point with double precision floating-point coordinates
typedef struct CvPoint2D64f { double x; /* x-coordinate, usually zero-based */ double y; /* y-coordinate, usually zero-based */ } CvPoint2D64f; /* the constructor function */ inline CvPoint2D64f cvPoint2D64f( double x, double y ); /* conversion from CvPoint */ inline CvPoint2D64f cvPointTo64f( CvPoint point );
3D point with double precision floating-point coordinates
typedef struct CvPoint3D64f { double x; /* x-coordinate, usually zero-based */ double y; /* y-coordinate, usually zero-based */ double z; /* z-coordinate, usually zero-based */ } CvPoint3D64f; /* the constructor function */ inline CvPoint3D64f cvPoint3D64f( double x, double y, double z );
pixel-accurate size of a rectangle
typedef struct CvSize { int width; /* width of the rectangle */ int height; /* height of the rectangle */ } CvSize; /* the constructor function */ inline CvSize cvSize( int width, int height );
sub-pixel accurate size of a rectangle
typedef struct CvSize2D32f { float width; /* width of the box */ float height; /* height of the box */ } CvSize2D32f; /* the constructor function */ inline CvSize2D32f cvSize2D32f( double width, double height );
offset and size of a rectangle
typedef struct CvRect { int x; /* x-coordinate of the left-most rectangle corner[s] */ int y; /* y-coordinate of the top-most or bottom-most rectangle corner[s] */ int width; /* width of the rectangle */ int height; /* height of the rectangle */ } CvRect; /* the constructor function */ inline CvRect cvRect( int x, int y, int width, int height );
A container for 1-,2-,3- or 4-tuples of numbers
typedef struct CvScalar { double val[4]; } CvScalar; /* the constructor function: initializes val[0] with val0, val[1] with val1 etc. */ inline CvScalar cvScalar( double val0, double val1=0, double val2=0, double val3=0 ); /* the constructor function: initializes val[0]...val[3] with val0123 */ inline CvScalar cvScalarAll( double val0123 ); /* the constructor function: initializes val[0] with val0, val[1]...val[3] with zeros */ inline CvScalar cvRealScalar( double val0 );
Termination criteria for iterative algorithms
#define CV_TERMCRIT_ITER 1 #define CV_TERMCRIT_NUMBER CV_TERMCRIT_ITER #define CV_TERMCRIT_EPS 2 typedef struct CvTermCriteria { int type; /* a combination of CV_TERMCRIT_ITER and CV_TERMCRIT_EPS */ int max_iter; /* maximum number of iterations */ double epsilon; /* accuracy to achieve */ } CvTermCriteria; /* the constructor function */ inline CvTermCriteria cvTermCriteria( int type, int max_iter, double epsilon ); /* check termination criteria and transform it so that type=CV_TERMCRIT_ITER+CV_TERMCRIT_EPS, and both max_iter and epsilon are valid */ CvTermCriteria cvCheckTermCriteria( CvTermCriteria criteria, double default_eps, int default_max_iters );
Multi-channel matrix
typedef struct CvMat { int type; /* CvMat signature (CV_MAT_MAGIC_VAL), element type and flags */ int step; /* full row length in bytes */ int* refcount; /* underlying data reference counter */ union { uchar* ptr; short* s; int* i; float* fl; double* db; } data; /* data pointers */ #ifdef __cplusplus union { int rows; int height; }; union { int cols; int width; }; #else int rows; /* number of rows */ int cols; /* number of columns */ #endif } CvMat;
Multi-dimensional dense multi-channel array
typedef struct CvMatND { int type; /* CvMatND signature (CV_MATND_MAGIC_VAL), element type and flags */ int dims; /* number of array dimensions */ int* refcount; /* underlying data reference counter */ union { uchar* ptr; short* s; int* i; float* fl; double* db; } data; /* data pointers */ /* pairs (number of elements, distance between elements in bytes) for every dimension */ struct { int size; int step; } dim[CV_MAX_DIM]; } CvMatND;
Multi-dimensional sparse multi-channel array
typedef struct CvSparseMat { int type; /* CvSparseMat signature (CV_SPARSE_MAT_MAGIC_VAL), element type and flags */ int dims; /* number of dimensions */ int* refcount; /* reference counter - not used */ struct CvSet* heap; /* a pool of hashtable nodes */ void** hashtable; /* hashtable: each entry has a list of nodes having the same "hashvalue modulo hashsize" */ int hashsize; /* size of hashtable */ int total; /* total number of sparse array nodes */ int valoffset; /* value offset in bytes for the array nodes */ int idxoffset; /* index offset in bytes for the array nodes */ int size[CV_MAX_DIM]; /* arr of dimension sizes */ } CvSparseMat;
IPL image header
typedef struct _IplImage { int nSize; /* sizeof(IplImage) */ int ID; /* version (=0)*/ int nChannels; /* Most of OpenCV functions support 1,2,3 or 4 channels */ int alphaChannel; /* ignored by OpenCV */ int depth; /* pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U, IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_64F are supported */ char colorModel[4]; /* ignored by OpenCV */ char channelSeq[4]; /* ditto */ int dataOrder; /* 0 - interleaved color channels, 1 - separate color channels. cvCreateImage can only create interleaved images */ int origin; /* 0 - top-left origin, 1 - bottom-left origin (Windows bitmaps style) */ int align; /* Alignment of image rows (4 or 8). OpenCV ignores it and uses widthStep instead */ int width; /* image width in pixels */ int height; /* image height in pixels */ struct _IplROI *roi;/* image ROI. when it is not NULL, this specifies image region to process */ struct _IplImage *maskROI; /* must be NULL in OpenCV */ void *imageId; /* ditto */ struct _IplTileInfo *tileInfo; /* ditto */ int imageSize; /* image data size in bytes (=image->height*image->widthStep in case of interleaved data)*/ char *imageData; /* pointer to aligned image data */ int widthStep; /* size of aligned image row in bytes */ int BorderMode[4]; /* border completion mode, ignored by OpenCV */ int BorderConst[4]; /* ditto */ char *imageDataOrigin; /* pointer to a very origin of image data (not necessarily aligned) - it is needed for correct image deallocation */ } IplImage;
The structure IplImage
came from Intel Image Processing Library where
the format is native. OpenCV supports only a subset of possible IplImage
formats:
alphaChannel
is ignored by OpenCV.
colorModel
and channelSeq
are ignored by OpenCV. The single OpenCV function
cvCvtColor working with color spaces takes the source and destination color spaces
as a parameter.
dataOrder
must be IPL_DATA_ORDER_PIXEL (the color channels are interleaved), however
selected channels of planar images can be processed as well if COI is set.
align
is ignored by OpenCV, while widthStep
is used to access to subsequent image rows.
maskROI
is not supported. The function that can work with mask take it as a
separate parameter. Also the mask in OpenCV is 8-bit, whereas in IPL it is 1-bit.
tileInfo
is not supported.
BorderMode
and BorderConst
are not supported. Every OpenCV function
working with a pixel neigborhood uses a single hard-coded border mode (most often, replication).
Arbitrary array
typedef void CvArr;
The metatype CvArr*
is used only as a function parameter to
specify that the function accepts arrays of more than a
single type, for example IplImage*, CvMat* or even CvSeq*. The particular array
type is determined at runtime by analyzing the first 4 bytes of the header.
Creates header and allocates data
IplImage* cvCreateImage( CvSize size, int depth, int channels );
The function cvCreateImage
creates the header and allocates data. This call is a
shortened form of
header = cvCreateImageHeader(size,depth,channels); cvCreateData(header);
Allocates, initializes, and returns structure IplImage
IplImage* cvCreateImageHeader( CvSize size, int depth, int channels );
The function cvCreateImageHeader
allocates, initializes, and returns the structure
IplImage
. This call is an analogue of
iplCreateImageHeader( channels, 0, depth, channels == 1 ? "GRAY" : "RGB", channels == 1 ? "GRAY" : channels == 3 ? "BGR" : channels == 4 ? "BGRA" : "", IPL_DATA_ORDER_PIXEL, IPL_ORIGIN_TL, 4, size.width, size.height, 0,0,0,0);though it does not use IPL functions by default (see also
CV_TURN_ON_IPL_COMPATIBILITY
macro)
Releases header
void cvReleaseImageHeader( IplImage** image );
The function cvReleaseImageHeader
releases the header.
This call is an analogue of
if( image ) { iplDeallocate( *image, IPL_IMAGE_HEADER | IPL_IMAGE_ROI ); *image = 0; }though it does not use IPL functions by default (see also
CV_TURN_ON_IPL_COMPATIBILITY
)
Releases header and image data
void cvReleaseImage( IplImage** image );
The function cvReleaseImage
releases the header and the image data. This call is a
shortened form of
if( *image ) { cvReleaseData( *image ); cvReleaseImageHeader( image ); }
Initializes allocated by user image header
IplImage* cvInitImageHeader( IplImage* image, CvSize size, int depth, int channels, int origin=0, int align=4 );
IPL_ORIGIN_TL
or IPL_ORIGIN_BL
.
The function cvInitImageHeader
initializes the image header structure,
pointer to which is passed by the user, and returns the pointer.
Makes a full copy of image
IplImage* cvCloneImage( const IplImage* image );
The function cvCloneImage
makes a full copy of the image including
header, ROI and data
Sets channel of interest to given value
void cvSetImageCOI( IplImage* image, int coi );
The function cvSetImageCOI
sets the channel of interest
to a given value. Value 0 means that all channels are selected,
1 means that the first channel is selected etc.
If ROI is NULL
and coi != 0
, ROI is allocated.
Note that most of OpenCV functions do not support COI, so
to process separate image/matrix channel one may copy (via cvCopy or
cvSplit) the channel to separate image/matrix,
process it and copy the result back (via cvCopy or cvCvtPlaneToPix)
if need.
Returns index of channel of interest
int cvGetImageCOI( const IplImage* image );
The function cvGetImageCOI
returns channel of interest of
the image (it returns 0 if all the channels are selected).
Sets image ROI to given rectangle
void cvSetImageROI( IplImage* image, CvRect rect );
The function cvSetImageROI
sets the image ROI to a given rectangle. If ROI is NULL
and the value of the parameter rect
is not equal to the whole image, ROI is
allocated. Unlike COI, most of OpenCV functions do support ROI and treat
it in a way as it would be a separate image (for example, all the pixel
coordinates are counted from top-left or bottom-left
(depending on the image origin) corner of ROI)
Releases image ROI
void cvResetImageROI( IplImage* image );
The function cvResetImageROI
releases image ROI. After that the whole image
is considered selected. The similar result can be achieved by
cvSetImageROI( image, cvRect( 0, 0, image->width, image->height )); cvSetImageCOI( image, 0 );
But the latter variant does not deallocate image->roi
.
Returns image ROI coordinates
CvRect cvGetImageROI( const IplImage* image );
The function cvGetImageROI
returns image ROI coordinates.
The rectangle cvRect(0,0,image->width,image->height) is returned if
there is no ROI
Creates new matrix
CvMat* cvCreateMat( int rows, int cols, int type );
CV_<bit_depth>(S|U|F)C<number_of_channels>
, for example:CV_8UC1
means an 8-bit unsigned single-channel matrix,
CV_32SC2
means a 32-bit signed matrix with two channels.
The function cvCreateMat
allocates header for the new matrix and underlying data,
and returns a pointer to the created matrix. It is a short form for:
CvMat* mat = cvCreateMatHeader( rows, cols, type ); cvCreateData( mat );
Matrices are stored row by row. All the rows are aligned by 4 bytes.
Creates new matrix header
CvMat* cvCreateMatHeader( int rows, int cols, int type );
The function cvCreateMatHeader
allocates new matrix header and returns pointer to
it. The matrix data can further be allocated using cvCreateData or set
explicitly to user-allocated data via cvSetData.
Deallocates matrix
void cvReleaseMat( CvMat** mat );
The function cvReleaseMat
decrements the matrix data reference counter and
releases matrix header:
if( *mat ) cvDecRefData( *mat ); cvFree( (void**)mat );
Initializes matrix header
CvMat* cvInitMatHeader( CvMat* mat, int rows, int cols, int type, void* data=NULL, int step=CV_AUTOSTEP );
The function cvInitMatHeader
initializes already allocated CvMat structure. It can
be used to process raw data with OpenCV matrix functions.
For example, the following code computes matrix product of two matrices, stored as ordinary arrays.
Calculating Product of Two Matrices
double a[] = { 1, 2, 3, 4 5, 6, 7, 8, 9, 10, 11, 12 }; double b[] = { 1, 5, 9, 2, 6, 10, 3, 7, 11, 4, 8, 12 }; double c[9]; CvMat Ma, Mb, Mc ; cvInitMatHeader( &Ma, 3, 4, CV_64FC1, a ); cvInitMatHeader( &Mb, 4, 3, CV_64FC1, b ); cvInitMatHeader( &Mc, 3, 3, CV_64FC1, c ); cvMatMulAdd( &Ma, &Mb, 0, &Mc ); // c array now contains product of a(3x4) and b(4x3) matrices
Initializes matrix header (light-weight variant)
CvMat cvMat( int rows, int cols, int type, void* data=NULL );
The function cvMat
is a fast inline substitution for cvInitMatHeader.
Namely, it is equivalent to:
CvMat mat; cvInitMatHeader( &mat, rows, cols, type, data, CV_AUTOSTEP );
Creates matrix copy
CvMat* cvCloneMat( const CvMat* mat );
The function cvCloneMat
creates a copy of input matrix and returns the pointer to
it.
Creates multi-dimensional dense array
CvMatND* cvCreateMatND( int dims, const int* sizes, int type );
The function cvCreateMatND
allocates header for multi-dimensional dense array
and the underlying data, and returns pointer to the created array. It is a short form for:
CvMatND* mat = cvCreateMatNDHeader( dims, sizes, type ); cvCreateData( mat );
Array data is stored row by row. All the rows are aligned by 4 bytes.
Creates new matrix header
CvMatND* cvCreateMatNDHeader( int dims, const int* sizes, int type );
The function cvCreateMatND
allocates header for multi-dimensional dense array.
The array data can further be allocated using cvCreateData or set
explicitly to user-allocated data via cvSetData.
Deallocates multi-dimensional array
void cvReleaseMatND( CvMatND** mat );
The function cvReleaseMatND
decrements the array data reference counter and
releases the array header:
if( *mat ) cvDecRefData( *mat ); cvFree( (void**)mat );
Initializes multi-dimensional array header
CvMatND* cvInitMatNDHeader( CvMatND* mat, int dims, const int* sizes, int type, void* data=NULL );
The function cvInitMatNDHeader
initializes CvMatND structure allocated by
the user.
Creates full copy of multi-dimensional array
CvMatND* cvCloneMatND( const CvMatND* mat );
The function cvCloneMatND
creates a copy of input array and returns pointer to
it.
Decrements array data reference counter
void cvDecRefData( CvArr* arr );
The function cvDecRefData
decrements CvMat or CvMatND data reference counter if the
reference counter pointer is not NULL and deallocates the data if the counter reaches zero.
In the current implementation the reference counter is not NULL only if the data was allocated using
cvCreateData function, in other cases such as:
external data was assigned to the header using cvSetData
the matrix header presents a part of a larger matrix or image
the matrix header was converted from image or n-dimensional matrix header
the reference counter is set to NULL and thus it is not decremented.
Whenever the data is deallocated or not,
the data pointer and reference counter pointers are cleared by the function.
Increments array data reference counter
int cvIncRefData( CvArr* arr );
The function cvIncRefData
increments CvMat or CvMatND data reference counter and
returns the new counter value if the reference counter pointer is not NULL, otherwise it returns zero.
Allocates array data
void cvCreateData( CvArr* arr );
The function cvCreateData
allocates image, matrix or multi-dimensional array data.
Note that in case of matrix types OpenCV allocation functions are used and
in case of IplImage they are used too unless CV_TURN_ON_IPL_COMPATIBILITY
was called.
In the latter case IPL functions are used to allocate the data
Releases array data
void cvReleaseData( CvArr* arr );
The function cvReleaseData
releases the array data.
In case of CvMat or CvMatND it simply calls cvDecRefData(), that is
the function can not deallocate external data. See also the note to cvCreateData.
Assigns user data to the array header
void cvSetData( CvArr* arr, void* data, int step );
The function cvSetData
assigns user data to the array header.
Header should be initialized before using cvCreate*Header,
cvInit*Header or cvMat (in case of matrix) function.
Retrieves low-level information about the array
void cvGetRawData( const CvArr* arr, uchar** data, int* step=NULL, CvSize* roi_size=NULL );
The function cvGetRawData
fills output variables with low-level
information about the array data.
All output parameters are optional, so some of the pointers
may be set to NULL
.
If the array is IplImage
with ROI set,
parameters of ROI are returned.
The following example shows how to get access to array elements using this function.
Using GetRawData to calculate absolute value of elements of a single-channel floating-point array.
float* data; int step; CvSize size; int x, y; cvGetRawData( array, (uchar**)&data, &step, &size ); step /= sizeof(data[0]); for( y = 0; y < size.height; y++, data += step ) for( x = 0; x < size.width; x++ ) data[x] = (float)fabs(data[x]);
Returns matrix header for arbitrary array
CvMat* cvGetMat( const CvArr* arr, CvMat* header, int* coi=NULL, int allowND=0 );
The function cvGetMat
returns matrix header for the input array that can be
matrix - CvMat, image - IplImage
or multi-dimensional dense array - CvMatND*
(latter case is allowed only if allowND != 0
) .
In the case of matrix the function simply returns the input pointer.
In the case of IplImage*
or CvMatND* it initializes header
structure
with parameters of the current image ROI and returns pointer to this temporary
structure. Because COI is not supported by CvMat, it is returned separately.
The function provides an easy way to handle both types of array - IplImage
and
CvMat -, using the same code. Reverse transform from CvMat to IplImage
can be
done using cvGetImage function.
Input array must have underlying data allocated or attached, otherwise the function fails.
If the input array isIplImage
with planar data layout and COI set, the function
returns pointer to the selected plane and COI = 0. It enables per-plane
processing of multi-channel images with planar data layout using OpenCV
functions.
Returns image header for arbitrary array
IplImage* cvGetImage( const CvArr* arr, IplImage* image_header );
IplImage
structure used as a temporary buffer.
The function cvGetImage
returns image header for the input array that can be
matrix - CvMat*, or image - IplImage*
. In the case of image the function simply
returns the input pointer. In the case of CvMat* it initializes image_header
structure
with parameters of the input matrix. Note that if we transform IplImage
to CvMat and then transform
CvMat back to IplImage, we can get different headers if the ROI is set, and thus some IPL functions
that calculate image stride from its width and align may fail on the resultant image.
Creates sparse array
CvSparseMat* cvCreateSparseMat( int dims, const int* sizes, int type );
The function cvCreateSparseMat
allocates multi-dimensional sparse array.
Initially the array contain no elements, that is cvGet*D or
cvGetReal*D return zero for every index
Deallocates sparse array
void cvReleaseSparseMat( CvSparseMat** mat );
The function cvReleaseSparseMat
releases the sparse array and clears the array pointer upon exit
Creates full copy of sparse array
CvSparseMat* cvCloneSparseMat( const CvSparseMat* mat );
The function cvCloneSparseMat
creates a copy of the input array and returns pointer to the copy.
Returns matrix header corresponding to the rectangular sub-array of input image or matrix
CvMat* cvGetSubRect( const CvArr* arr, CvMat* submat, CvRect rect );
The function cvGetSubRect
returns header, corresponding
to a specified rectangle of the input array.
In other words, it allows the user to treat a rectangular part
of input array as a stand-alone array. ROI is taken into account by the function
so the sub-array of ROI is actually extracted.
Returns array row or row span
CvMat* cvGetRow( const CvArr* arr, CvMat* submat, int row ); CvMat* cvGetRows( const CvArr* arr, CvMat* submat, int start_row, int end_row, int delta_row=1 );
delta_row
-th
row from start_row
and up to (but not including) end_row
.
The functions GetRow
and GetRows
return the header, corresponding to a specified
row/row span of the input array. Note that GetRow
is a shortcut for cvGetRows:
cvGetRow( arr, submat, row ) ~ cvGetRows( arr, submat, row, row + 1, 1 );
Returns array column or column span
CvMat* cvGetCol( const CvArr* arr, CvMat* submat, int col ); CvMat* cvGetCols( const CvArr* arr, CvMat* submat, int start_col, int end_col );
The functions GetCol
and GetCols
return the header, corresponding to a specified
column/column span of the input array. Note that GetCol
is a shortcut for cvGetCols:
cvGetCol( arr, submat, col ); // ~ cvGetCols( arr, submat, col, col + 1 );
Returns one of array diagonals
CvMat* cvGetDiag( const CvArr* arr, CvMat* submat, int diag=0 );
The function cvGetDiag
returns the header, corresponding to a specified
diagonal of the input array.
Returns size of matrix or image ROI
CvSize cvGetSize( const CvArr* arr );
The function cvGetSize
returns number of rows (CvSize::height) and number of columns
(CvSize::width) of the input matrix or image. In case of image the size of ROI is returned.
Initializes sparse array elements iterator
CvSparseNode* cvInitSparseMatIterator( const CvSparseMat* mat, CvSparseMatIterator* mat_iterator );
The function cvInitSparseMatIterator
initializes iterator of sparse array elements and
returns pointer to the first element, or NULL if the array is empty.
Initializes sparse array elements iterator
CvSparseNode* cvGetNextSparseNode( CvSparseMatIterator* mat_iterator );
The function cvGetNextSparseNode
moves iterator to the next sparse matrix element and returns
pointer to it. In the current version there is no any particular order of the elements, because they
are stored in hash table. The sample below demonstrates how to iterate through the sparse matrix:
Using cvInitSparseMatIterator and cvGetNextSparseNode to calculate sum of floating-point sparse array.
double sum; int i, dims = cvGetDims( array ); CvSparseMatIterator mat_iterator; CvSparseNode* node = cvInitSparseMatIterator( array, &mat_iterator ); for( ; node != 0; node = cvGetNextSparseNode( &mat_iterator )) { const int* idx = CV_NODE_IDX( array, node ); /* get pointer to the element indices */ float val = *(float*)CV_NODE_VAL( array, node ); /* get value of the element (assume that the type is CV_32FC1) */ printf( "(" ); for( i = 0; i < dims; i++ ) printf( "%4d%s", idx[i], i < dims - 1 "," : "): " ); printf( "%g\n", val ); sum += val; } printf( "\nTotal sum = %g\n", sum );
Returns type of array elements
int cvGetElemType( const CvArr* arr );
The functions GetElemType
returns type of the array elements as it is described in
cvCreateMat discussion:
CV_8UC1 ... CV_64FC4
Return number of array dimensions and their sizes or the size of particular dimension
int cvGetDims( const CvArr* arr, int* sizes=NULL ); int cvGetDimSize( const CvArr* arr, int index );
The function cvGetDims
returns number of array dimensions and their sizes.
In case of IplImage
or CvMat it always returns 2 regardless of number of image/matrix rows.
The function cvGetDimSize
returns the particular dimension size (number of elements per that dimension).
For example, the following code calculates total number of array elements in two ways:
// via cvGetDims() int sizes[CV_MAX_DIM]; int i, total = 1; int dims = cvGetDims( arr, size ); for( i = 0; i < dims; i++ ) total *= sizes[i]; // via cvGetDims() and cvGetDimSize() int i, total = 1; int dims = cvGetDims( arr ); for( i = 0; i < dims; i++ ) total *= cvGetDimsSize( arr, i );
Return pointer to the particular array element
uchar* cvPtr1D( const CvArr* arr, int idx0, int* type=NULL ); uchar* cvPtr2D( const CvArr* arr, int idx0, int idx1, int* type=NULL ); uchar* cvPtr3D( const CvArr* arr, int idx0, int idx1, int idx2, int* type=NULL ); uchar* cvPtrND( const CvArr* arr, const int* idx, int* type=NULL, int create_node=1, unsigned* precalc_hashval=NULL );
The functions >cvPtr*D
return pointer to the particular array element.
Number of array dimension should match to the number of indices passed to the function except
for cvPtr1D
function that can be used for sequential access to 1D, 2D or nD dense arrays.
The functions can be used for sparse arrays as well - if the requested node does not exist they create it and set it to zero.
All these as well as other functions accessing array elements (cvGet*D, cvGetReal*D, cvSet*D, cvSetReal*D) raise an error in case if the element index is out of range.
Return the particular array element
CvScalar cvGet1D( const CvArr* arr, int idx0 ); CvScalar cvGet2D( const CvArr* arr, int idx0, int idx1 ); CvScalar cvGet3D( const CvArr* arr, int idx0, int idx1, int idx2 ); CvScalar cvGetND( const CvArr* arr, const int* idx );
The functions cvGet*D
return the particular array element. In case of sparse array
the functions return 0 if the requested node does not exist (no new node is created
by the functions)
Return the particular element of single-channel array
double cvGetReal1D( const CvArr* arr, int idx0 ); double cvGetReal2D( const CvArr* arr, int idx0, int idx1 ); double cvGetReal3D( const CvArr* arr, int idx0, int idx1, int idx2 ); double cvGetRealND( const CvArr* arr, const int* idx );
The functions cvGetReal*D
return the particular element of single-channel array.
If the array has multiple channels, runtime error is raised. Note that cvGet*D function
can be used safely for both single-channel and multiple-channel arrays though they are
a bit slower.
In case of sparse array the functions return 0 if the requested node does not exist (no new node is created by the functions)
Return the particular element of single-channel floating-point matrix
double cvmGet( const CvMat* mat, int row, int col );
The function cvmGet
is a fast replacement for cvGetReal2D in case of
single-channel floating-point matrices. It is faster because it is inline,
it does less checks for array type and array element type and it
checks for the row and column ranges only in debug mode.
Change the particular array element
void cvSet1D( CvArr* arr, int idx0, CvScalar value ); void cvSet2D( CvArr* arr, int idx0, int idx1, CvScalar value ); void cvSet3D( CvArr* arr, int idx0, int idx1, int idx2, CvScalar value ); void cvSetND( CvArr* arr, const int* idx, CvScalar value );
The functions cvSet*D
assign the new value to the particular element of array.
In case of sparse array the functions create the node if it does not exist yet
Change the particular array element
void cvSetReal1D( CvArr* arr, int idx0, double value ); void cvSetReal2D( CvArr* arr, int idx0, int idx1, double value ); void cvSetReal3D( CvArr* arr, int idx0, int idx1, int idx2, double value ); void cvSetRealND( CvArr* arr, const int* idx, double value );
The functions cvSetReal*D
assign the new value to the particular element of single-channel array.
If the array has multiple channels, runtime error is raised. Note that cvSet*D function
can be used safely for both single-channel and multiple-channel arrays though they are
a bit slower.
In case of sparse array the functions create the node if it does not exist yet
Return the particular element of single-channel floating-point matrix
void cvmSet( CvMat* mat, int row, int col, double value );
The function cvmSet
is a fast replacement for cvSetReal2D in case of
single-channel floating-point matrices. It is faster because it is inline,
it does less checks for array type and array element type and it
checks for the row and column ranges only in debug mode.
Clears the particular array element
void cvClearND( CvArr* arr, const int* idx );
The function cvClearND clears (sets to zero) the particular element of dense array or deletes the element of sparse array. If the element does not exists, the function does nothing.
Copies one array to another
void cvCopy( const CvArr* src, CvArr* dst, const CvArr* mask=NULL );
The function cvCopy
copies selected elements from input array to output array:
dst(I)=src(I) if mask(I)!=0.
If any of the passed arrays is of IplImage
type, then its ROI and COI fields are
used. Both arrays must have the same type, the same number of dimensions and the same size.
The function can also copy sparse arrays (mask is not supported in this case).
Sets every element of array to given value
void cvSet( CvArr* arr, CvScalar value, const CvArr* mask=NULL );
The function cvSet
copies scalar value
to every selected element of the destination
array:
arr(I)=value if mask(I)!=0
If array arr
is of IplImage
type, then is ROI used, but COI must not be
set.
Clears the array
void cvSetZero( CvArr* arr ); #define cvZero cvSetZero
The function cvSetZero
clears the array. In case of dense arrays
(CvMat, CvMatND or IplImage) cvZero(array) is equivalent to cvSet(array,cvScalarAll(0),0),
in case of sparse arrays all the elements are removed.
Initializes scaled identity matrix
void cvSetIdentity( CvArr* mat, CvScalar value=cvRealScalar(1) );
The function cvSetIdentity
initializes scaled identity matrix:
arr(i,j)=value if i=j, 0 otherwise
Fills matrix with given range of numbers
void cvRange( CvArr* mat, double start, double end );
The function cvRange
initializes the matrix as following:
arr(i,j)=(end-start)*(i*cols(arr)+j)/(cols(arr)*rows(arr))For example, the following code will initilize 1D vector with subsequent integer numbers.
CvMat* A = cvCreateMat( 1, 10, CV_32S ); cvRange( A, 0, A->cols ); // A will be initialized as [0,1,2,3,4,5,6,7,8,9]
Changes shape of matrix/image without copying data
CvMat* cvReshape( const CvArr* arr, CvMat* header, int new_cn, int new_rows=0 );
new_cn = 0
means that number of channels remains unchanged.
new_rows = 0
means that number of rows remains unchanged unless
it needs to be changed according to new_cn
value.
destination array to be changed.
The function cvReshape
initializes CvMat header so that it points to the same data as
the original array but has different shape - different number of channels,
different number of rows or both.
For example, the following code creates one image buffer and two image headers, first is for 320x240x3 image and the second is for 960x240x1 image:
IplImage* color_img = cvCreateImage( cvSize(320,240), IPL_DEPTH_8U, 3 ); CvMat gray_mat_hdr; IplImage gray_img_hdr, *gray_img; cvReshape( color_img, &gray_mat_hdr, 1 ); gray_img = cvGetImage( &gray_mat_hdr, &gray_img_hdr );
And the next example converts 3x3 matrix to a single 1x9 vector
CvMat* mat = cvCreateMat( 3, 3, CV_32F ); CvMat row_header, *row; row = cvReshape( mat, &row_header, 0, 1 );
Changes shape of multi-dimensional array w/o copying data
CvArr* cvReshapeMatND( const CvArr* arr, int sizeof_header, CvArr* header, int new_cn, int new_dims, int* new_sizes ); #define cvReshapeND( arr, header, new_cn, new_dims, new_sizes ) \ cvReshapeMatND( (arr), sizeof(*(header)), (header), \ (new_cn), (new_dims), (new_sizes))
new_cn = 0
means that number of channels remains unchanged.
new_dims = 0
means that number of dimensions remains the same.
new_dims-1
values are used, because the total number of
elements must remain the same. Thus, if new_dims = 1
, new_sizes
array is not used
The function cvReshapeMatND
is an advanced version of cvReshape that can work
with multi-dimensional arrays as well (though, it can work with ordinary images and matrices)
and change the number of dimensions. Below are the two samples
from the cvReshape description rewritten using cvReshapeMatND:
IplImage* color_img = cvCreateImage( cvSize(320,240), IPL_DEPTH_8U, 3 ); IplImage gray_img_hdr, *gray_img; gray_img = (IplImage*)cvReshapeND( color_img, &gray_img_hdr, 1, 0, 0 ); ... /* second example is modified to convert 2x2x2 array to 8x1 vector */ int size[] = { 2, 2, 2 }; CvMatND* mat = cvCreateMatND( 3, size, CV_32F ); CvMat row_header, *row; row = cvReshapeND( mat, &row_header, 0, 1, 0 );
Fill destination array with tiled source array
void cvRepeat( const CvArr* src, CvArr* dst );
The function cvRepeat
fills the destination array with source array tiled:
dst(i,j)=src(i mod rows(src), j mod cols(src))
So the destination array may be as larger as well as smaller than the source array.
Flip a 2D array around vertical, horizontall or both axises
void cvFlip( const CvArr* src, CvArr* dst=NULL, int flip_mode=0); #define cvMirror cvFlip
dst = NULL
the flipping is done inplace.
The function cvFlip
flips the array in one of different 3 ways
(row and column indices are 0-based):
dst(i,j)=src(rows(src)-i-1,j) if flip_mode = 0
dst(i,j)=src(i,cols(src1)-j-1) if flip_mode > 0
dst(i,j)=src(rows(src)-i-1,cols(src)-j-1) if flip_mode < 0
The example cenaria of the function use are:
Divides multi-channel array into several single-channel arrays or extracts a single channel from the array
void cvSplit( const CvArr* src, CvArr* dst0, CvArr* dst1, CvArr* dst2, CvArr* dst3 ); #define cvCvtPixToPlane cvSplit
The function cvSplit
divides a multi-channel array into separate single-channel arrays.
Two modes are available for the operation. If the source array has N channels then if
the first N destination channels are not NULL, all they are extracted from the source array,
otherwise if only a single destination channel of the first N is not NULL, this particular channel
is extracted, otherwise an error is raised. Rest of destination channels (beyond the first N)
must always be NULL.
For IplImage cvCopy with COI set can be also used to extract a single channel from the image.
Composes multi-channel array from several single-channel arrays or inserts a single channel into the array
void cvMerge( const CvArr* src0, const CvArr* src1, const CvArr* src2, const CvArr* src3, CvArr* dst ); #define cvCvtPlaneToPix cvMerge
The function cvMerge
is the opposite to the previous.
If the destination array has N channels then if
the first N input channels are not NULL, all they are copied to the destination array,
otherwise if only a single source channel of the first N is not NULL, this particular channel is copied
into the destination array, otherwise an error is raised. Rest of source channels (beyond the first N)
must always be NULL.
For IplImage cvCopy with COI set can be also used to insert a single channel into the image.
Copies several channels from input arrays to certain channels of output arrays
void cvMixChannels( const CvArr** src, int src_count, CvArr** dst, int dst_count, const int* from_to, int pair_count );
from_to[k*2]
is the 0-based index of the input plane,
and from_to[k*2+1]
is the index of the output plane, where the continuous numbering
of the planes over all the input and over all the output arrays is used.
When from_to[k*2]
is negative, the corresponding output plane is filled with 0's.
from_to
, or the number of the planes copied.
The function cvMixChannels
is a generalized form of cvSplit and
cvMerge and some forms of cvCvtColor.
It can be used to change the order of the planes, add/remove alpha
channel, extract or insert a single plane or multiple planes etc.
Below is the example, how to split 4-channel RGBA image into 3-channel BGR (i.e. with R&B swapped) and
separate alpha channel images:
CvMat* rgba = cvCreateMat( 100, 100, CV_8UC4 ); CvMat* bgr = cvCreateMat( rgba->rows, rgba->cols, CV_8UC3 ); CvMat* alpha = cvCreateMat( rgba->rows, rgba->cols, CV_8UC1 ); CvArr* out[] = { bgr, alpha }; int from_to[] = { 0, 2, 1, 1, 2, 0, 3, 3 }; cvSet( rgba, cvScalar(1,2,3,4) ); cvMixChannels( (const CvArr**)&rgba, 1, out, 2, from_to, 4 );
Randomly shuffles the array elements
void cvRandShuffle( CvArr* mat, CvRNG* rng, double iter_factor=1. );
The function cvRandShuffle
shuffles the matrix by swapping randomly chosen pairs
of the matrix elements on each iteration (where each element may contain several components in case of multi-channel arrays).
The number of iterations (i.e. pairs swapped) is round(iter_factor*rows(mat)*cols(mat))
, so
iter_factor=0
means that no shuffling is done,
iter_factor=1
means that the function swaps
rows(mat)*cols(mat)
random pairs etc.
Performs look-up table transform of array
void cvLUT( const CvArr* src, CvArr* dst, const CvArr* lut );
The function cvLUT
fills the destination array with values
from the look-up table. Indices of the entries are taken from the source array. That is, the
function processes each element of src
as following:
dst(I)=lut[src(I)+DELTA]where
DELTA=0
if src
has depth CV_8U
, and
DELTA=128
if src
has depth CV_8S
.
Converts one array to another with optional linear transformation
void cvConvertScale( const CvArr* src, CvArr* dst, double scale=1, double shift=0 ); #define cvCvtScale cvConvertScale #define cvScale cvConvertScale #define cvConvert( src, dst ) cvConvertScale( (src), (dst), 1, 0 )
The function cvConvertScale
has several different purposes and thus has several synonyms.
It copies one array to another with optional scaling, which is performed first, and/or optional type conversion, performed after:
dst(I)=src(I)*scale + (shift,shift,...)
All the channels of multi-channel arrays are processed independently.
The type conversion is done with rounding and saturation, that is if a result of scaling + conversion can not be represented exactly by a value of destination array element type, it is set to the nearest representable value on the real axis.
In case of scale=1, shift=0
no prescaling is done. This is a specially optimized case and it
has the appropriate cvConvert synonym. If source and destination array types have
equal types, this is also a special case that can be used to scale and shift a matrix or an image and
that fits to cvScale synonym.
Converts input array elements to 8-bit unsigned integer another with optional linear transformation
void cvConvertScaleAbs( const CvArr* src, CvArr* dst, double scale=1, double shift=0 ); #define cvCvtScaleAbs cvConvertScaleAbs
The function cvConvertScaleAbs
is similar to the previous one, but it stores absolute values
of the conversion results:
dst(I)=abs(src(I)*scale + (shift,shift,...))
The function supports only destination arrays of 8u (8-bit unsigned integers) type, for other types the function can be emulated by combination of cvConvertScale and cvAbs functions.
Computes per-element sum of two arrays
void cvAdd( const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL );
The function cvAdd
adds one array to another one:
dst(I)=src1(I)+src2(I) if mask(I)!=0
All the arrays must have the same type, except the mask, and the same size (or ROI size)
Computes sum of array and scalar
void cvAddS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL );
The function cvAddS
adds scalar value
to every element in the source array src1
and
stores the result in dst
dst(I)=src(I)+value if mask(I)!=0
All the arrays must have the same type, except the mask, and the same size (or ROI size)
Computes weighted sum of two arrays
void cvAddWeighted( const CvArr* src1, double alpha, const CvArr* src2, double beta, double gamma, CvArr* dst );
The function cvAddWeighted
calculated weighted sum
of two arrays as following:
dst(I)=src1(I)*alpha+src2(I)*beta+gamma
All the arrays must have the same type and the same size (or ROI size)
Computes per-element difference between two arrays
void cvSub( const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL );
The function cvSub
subtracts one array from another one:
dst(I)=src1(I)-src2(I) if mask(I)!=0
All the arrays must have the same type, except the mask, and the same size (or ROI size)
Computes difference between array and scalar
void cvSubS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL );
The function cvSubS
subtracts a scalar from every element of the source array:
dst(I)=src(I)-value if mask(I)!=0
All the arrays must have the same type, except the mask, and the same size (or ROI size)
Computes difference between scalar and array
void cvSubRS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL );
The function cvSubRS
subtracts every element of source array from a scalar:
dst(I)=value-src(I) if mask(I)!=0
All the arrays must have the same type, except the mask, and the same size (or ROI size)
Calculates per-element product of two arrays
void cvMul( const CvArr* src1, const CvArr* src2, CvArr* dst, double scale=1 );
The function cvMul
calculates per-element product of two arrays:
dst(I)=scale•src1(I)•src2(I)
All the arrays must have the same type, and the same size (or ROI size)
Performs per-element division of two arrays
void cvDiv( const CvArr* src1, const CvArr* src2, CvArr* dst, double scale=1 );
The function cvDiv
divides one array by another:
dst(I)=scale•src1(I)/src2(I), if src1!=NULL dst(I)=scale/src2(I), if src1=NULL
All the arrays must have the same type, and the same size (or ROI size)
Calculates per-element bit-wise conjunction of two arrays
void cvAnd( const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL );
The function cvAnd
calculates per-element bit-wise logical conjunction of two arrays:
dst(I)=src1(I)&src2(I) if mask(I)!=0
In the case of floating-point arrays their bit representations are used for the operation. All the arrays must have the same type, except the mask, and the same size
Calculates per-element bit-wise conjunction of array and scalar
void cvAndS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL );
The function AndS calculates per-element bit-wise conjunction of array and scalar:
dst(I)=src(I)&value if mask(I)!=0
Prior to the actual operation the scalar is converted to the same type as the arrays. In the case of floating-point arrays their bit representations are used for the operation. All the arrays must have the same type, except the mask, and the same size
The following sample demonstrates how to calculate absolute value of floating-point array elements by clearing the most-significant bit:
float a[] = { -1, 2, -3, 4, -5, 6, -7, 8, -9 }; CvMat A = cvMat( 3, 3, CV_32F, &a ); int i, abs_mask = 0x7fffffff; cvAndS( &A, cvRealScalar(*(float*)&abs_mask), &A, 0 ); for( i = 0; i < 9; i++ ) printf("%.1f ", a[i] );
The code should print:
1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0
Calculates per-element bit-wise disjunction of two arrays
void cvOr( const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL );
The function cvOr
calculates per-element bit-wise disjunction of two arrays:
dst(I)=src1(I)|src2(I)
In the case of floating-point arrays their bit representations are used for the operation. All the arrays must have the same type, except the mask, and the same size
Calculates per-element bit-wise disjunction of array and scalar
void cvOrS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL );
The function OrS calculates per-element bit-wise disjunction of array and scalar:
dst(I)=src(I)|value if mask(I)!=0
Prior to the actual operation the scalar is converted to the same type as the arrays. In the case of floating-point arrays their bit representations are used for the operation. All the arrays must have the same type, except the mask, and the same size
Performs per-element bit-wise "exclusive or" operation on two arrays
void cvXor( const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL );
The function cvXor
calculates per-element bit-wise logical conjunction of two arrays:
dst(I)=src1(I)^src2(I) if mask(I)!=0
In the case of floating-point arrays their bit representations are used for the operation. All the arrays must have the same type, except the mask, and the same size
Performs per-element bit-wise "exclusive or" operation on array and scalar
void cvXorS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL );
The function XorS calculates per-element bit-wise conjunction of array and scalar:
dst(I)=src(I)^value if mask(I)!=0
Prior to the actual operation the scalar is converted to the same type as the arrays. In the case of floating-point arrays their bit representations are used for the operation. All the arrays must have the same type, except the mask, and the same size
The following sample demonstrates how to conjugate complex vector by switching the most-significant bit of imaging part:
float a[] = { 1, 0, 0, 1, -1, 0, 0, -1 }; /* 1, j, -1, -j */ CvMat A = cvMat( 4, 1, CV_32FC2, &a ); int i, neg_mask = 0x80000000; cvXorS( &A, cvScalar( 0, *(float*)&neg_mask, 0, 0 ), &A, 0 ); for( i = 0; i < 4; i++ ) printf("(%.1f, %.1f) ", a[i*2], a[i*2+1] );
The code should print:
(1.0,0.0) (0.0,-1.0) (-1.0,0.0) (0.0,1.0)
Performs per-element bit-wise inversion of array elements
void cvNot( const CvArr* src, CvArr* dst );
The function Not inverses every bit of every array element:
dst(I)=~src(I)
Performs per-element comparison of two arrays
void cvCmp( const CvArr* src1, const CvArr* src2, CvArr* dst, int cmp_op );
The function cvCmp
compares the corresponding elements of two arrays and
fills the destination mask array:
dst(I)=src1(I) op src2(I),
where op
is '=', '>', '>=', '<', '<=' or '!='.
dst(I)
is set to 0xff (all '1'-bits) if the particular relation between the elements
is true and 0 otherwise.
All the arrays must have the same type, except the destination, and the same size (or ROI size)
Performs per-element comparison of array and scalar
void cvCmpS( const CvArr* src, double value, CvArr* dst, int cmp_op );
The function cvCmpS
compares the corresponding elements of array and scalar
and fills the destination mask array:
dst(I)=src(I) op scalar,
where op
is '=', '>', '>=', '<', '<=' or '!='.
dst(I)
is set to 0xff (all '1'-bits) if the particular relation between the elements
is true and 0 otherwise.
All the arrays must have the same size (or ROI size)
Checks that array elements lie between elements of two other arrays
void cvInRange( const CvArr* src, const CvArr* lower, const CvArr* upper, CvArr* dst );
The function cvInRange
does the range check for every element of the input array:
dst(I)=lower(I)_{0} <= src(I)_{0} < upper(I)_{0}
for single-channel arrays,
dst(I)=lower(I)_{0} <= src(I)_{0} < upper(I)_{0} && lower(I)_{1} <= src(I)_{1} < upper(I)_{1}
for two-channel arrays etc.
dst(I)
is set to 0xff (all '1'-bits) if src(I)
is within the range and 0 otherwise.
All the arrays must have the same type, except the destination, and the same size (or ROI size)
Checks that array elements lie between two scalars
void cvInRangeS( const CvArr* src, CvScalar lower, CvScalar upper, CvArr* dst );
The function cvInRangeS
does the range check for every element of the input array:
dst(I)=lower_{0} <= src(I)_{0} < upper_{0}
for a single-channel array,
dst(I)=lower_{0} <= src(I)_{0} < upper_{0} && lower_{1} <= src(I)_{1} < upper_{1}
for a two-channel array etc.
dst(I)
is set to 0xff (all '1'-bits) if src(I)
is within the range and 0 otherwise.
All the arrays must have the same size (or ROI size)
Finds per-element maximum of two arrays
void cvMax( const CvArr* src1, const CvArr* src2, CvArr* dst );
The function cvMax
calculates per-element maximum of two arrays:
dst(I)=max(src1(I), src2(I))
All the arrays must have a single channel, the same data type and the same size (or ROI size).
Finds per-element maximum of array and scalar
void cvMaxS( const CvArr* src, double value, CvArr* dst );
The function cvMaxS
calculates per-element maximum of array and scalar:
dst(I)=max(src(I), value)
All the arrays must have a single channel, the same data type and the same size (or ROI size).
Finds per-element minimum of two arrays
void cvMin( const CvArr* src1, const CvArr* src2, CvArr* dst );
The function cvMin
calculates per-element minimum of two arrays:
dst(I)=min(src1(I),src2(I))
All the arrays must have a single channel, the same data type and the same size (or ROI size).
Finds per-element minimum of array and scalar
void cvMinS( const CvArr* src, double value, CvArr* dst );
The function cvMinS
calculates minimum of array and scalar:
dst(I)=min(src(I), value)
All the arrays must have a single channel, the same data type and the same size (or ROI size).
Calculates absolute difference between two arrays
void cvAbsDiff( const CvArr* src1, const CvArr* src2, CvArr* dst );
The function cvAbsDiff
calculates absolute difference between two arrays.
dst(I)_{c} = abs(src1(I)_{c} - src2(I)_{c}).
All the arrays must have the same data type and the same size (or ROI size).
Calculates absolute difference between array and scalar
void cvAbsDiffS( const CvArr* src, CvArr* dst, CvScalar value ); #define cvAbs(src, dst) cvAbsDiffS(src, dst, cvScalarAll(0))
The function cvAbsDiffS
calculates absolute difference between array and scalar.
dst(I)_{c} = abs(src(I)_{c} - value_{c}).
All the arrays must have the same data type and the same size (or ROI size).
Counts non-zero array elements
int cvCountNonZero( const CvArr* arr );
The function cvCountNonZero
returns the number of non-zero elements in src1:
result = sum_{I} arr(I)!=0In case of
IplImage
both ROI and COI are supported.
Summarizes array elements
CvScalar cvSum( const CvArr* arr );
The function cvSum
calculates sum S
of array elements, independently for each channel:
S_{c} = sum_{I} arr(I)_{c}If the array is
IplImage
and COI is set, the function processes the selected channel only
and stores the sum to the first scalar component (S_{0}).
Calculates average (mean) of array elements
CvScalar cvAvg( const CvArr* arr, const CvArr* mask=NULL );
The function cvAvg
calculates the average value M
of array elements, independently for each channel:
N = sum_{I} mask(I)!=0 M_{c} = 1/N • sum_{I,mask(I)!=0} arr(I)_{c}If the array is
IplImage
and COI is set, the function processes the selected channel only
and stores the average to the first scalar component (S_{0}).
Calculates average (mean) of array elements
void cvAvgSdv( const CvArr* arr, CvScalar* mean, CvScalar* std_dev, const CvArr* mask=NULL );
The function cvAvgSdv
calculates the average value and
standard deviation of array elements, independently for each channel:
N = sum_{I} mask(I)!=0 mean_{c} = 1/N • sum_{I,mask(I)!=0} arr(I)_{c} std_dev_{c} = sqrt(1/N • sum_{I,mask(I)!=0} (arr(I)_{c} - M_{c})^{2})If the array is
IplImage
and COI is set, the function processes the selected channel only
and stores the average and standard deviation to the first compoenents of output scalars (M_{0}
and S_{0}).
Finds global minimum and maximum in array or subarray
void cvMinMaxLoc( const CvArr* arr, double* min_val, double* max_val, CvPoint* min_loc=NULL, CvPoint* max_loc=NULL, const CvArr* mask=NULL );
The function MinMaxLoc
finds minimum and maximum element values and their
positions. The extremums are searched over the whole array, selected ROI
(in case
of IplImage
) or, if mask
is not NULL
, in the specified array region.
If the array has more than one channel, it must be IplImage
with COI
set.
In case if multi-dimensional arrays min_loc->x
and max_loc->x
will contain raw (linear)
positions of the extremums.
Calculates absolute array norm, absolute difference norm or relative difference norm
double cvNorm( const CvArr* arr1, const CvArr* arr2=NULL, int norm_type=CV_L2, const CvArr* mask=NULL );
arr1
is calculated, otherwise
absolute or relative norm of arr1
-arr2
is calculated.
The function cvNorm
calculates the absolute norm of arr1
if arr2
is NULL:
norm = ||arr1||_{C} = max_{I} abs(arr1(I)), ifnormType
= CV_C norm = ||arr1||_{L1} = sum_{I} abs(arr1(I)), ifnormType
= CV_L1 norm = ||arr1||_{L2} = sqrt( sum_{I} arr1(I)^{2}), ifnormType
= CV_L2
And the function calculates absolute or relative difference norm if arr2
is not NULL:
norm = ||arr1-arr2||_{C} = max_{I} abs(arr1(I)-arr2(I)), ifnormType
= CV_C norm = ||arr1-arr2||_{L1} = sum_{I} abs(arr1(I)-arr2(I)), ifnormType
= CV_L1 norm = ||arr1-arr2||_{L2} = sqrt( sum_{I} (arr1(I)-arr2(I))^{2} ), ifnormType
= CV_L2 or norm = ||arr1-arr2||_{C}/||arr2||_{C}, ifnormType
= CV_RELATIVE_C norm = ||arr1-arr2||_{L1}/||arr2||_{L1}, ifnormType
= CV_RELATIVE_L1 norm = ||arr1-arr2||_{L2}/||arr2||_{L2}, ifnormType
= CV_RELATIVE_L2
The function Norm
returns the calculated norm.
The multiple-channel array are treated as single-channel, that is, the results for all channels
are combined.
Reduces matrix to a vector
void cvReduce( const CvArr* src, CvArr* dst, int op=CV_REDUCE_SUM );
dst
size.
CV_REDUCE_SUM
- the output is the sum of all the matrix rows/columns.CV_REDUCE_AVG
- the output is the mean vector of all the matrix rows/columns.CV_REDUCE_MAX
- the output is the maximum (column/row-wise) of all the matrix rows/columns.CV_REDUCE_MIN
- the output is the minimum (column/row-wise) of all the matrix rows/columns.
The function cvReduce
reduces matrix to a vector by treating the matrix rows/columns as a set
of 1D vectors and performing the specified operation on the vectors until a single row/column is obtained.
For example, the function can be used to compute horizontal and vertical projections of an raster image.
In case of CV_REDUCE_SUM
and CV_REDUCE_AVG
the output may have a larger
element bit-depth to preserve accuracy. And multi-channel arrays are also supported in these two reduction modes.
Calculates dot product of two arrays in Euclidian metrics
double cvDotProduct( const CvArr* src1, const CvArr* src2 );
The function cvDotProduct
calculates and returns the Euclidean dot product of two
arrays.
src1•src2 = sum_{I}(src1(I)*src2(I))
In case of multiple channel arrays the results for all channels are
accumulated. In particular, cvDotProduct(a,a)
,
where a
is a complex vector, will return ||a||^{2}
.
The function can process multi-dimensional arrays, row by row, layer by layer and so on.
Normalizes array to a certain norm or value range
void cvNormalize( const CvArr* src, CvArr* dst, double a=1, double b=0, int norm_type=CV_L2, const CvArr* mask=NULL );
CV_C
- the C-norm (maximum of absolute values) of the array is normalized.CV_L1
- the L_{1}-norm (sum of absolute values) of the array is normalized.CV_L2
- the (Euclidian) L_{2}-norm of the array is normalized.CV_MINMAX
- the array values are scaled and shifted to the specified range.
The function cvNormalize
normalizes the input array so that it's norm or value
range takes the certain value(s).
When norm_type==CV_MINMAX
:
dst(i,j)=(src(i,j)-min(src))*(b'-a')/(max(src)-min(src)) + a', if mask(i,j)!=0 dst(i,j)=src(i,j) otherwisewhere
b'=MAX(a,b)
, a'=MIN(a,b)
;min(src)
and max(src)
are the global minimum and maximum, respectively,
of the input array, computed over the whole array or the specified subset of it.
When norm_type!=CV_MINMAX
:
dst(i,j)=src(i,j)*a/cvNorm(src,0,norm_type,mask), if mask(i,j)!=0 dst(i,j)=src(i,j) otherwise
Here is the short example:
float v[3] = { 1, 2, 3 }; CvMat V = cvMat( 1, 3, CV_32F, v ); // make vector v unit-length; // equivalent to // for(int i=0;i<3;i++) v[i]/=sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]); cvNormalize( &V, &V );
Calculates cross product of two 3D vectors
void cvCrossProduct( const CvArr* src1, const CvArr* src2, CvArr* dst );
The function cvCrossProduct
calculates the cross product of two 3D vectors:
dst = src1 × src2, (dst_{1} = src1_{2}src2_{3} - src1_{3}src2_{2} , dst_{2} = src1_{3}src2_{1} - src1_{1}src2_{3} , dst_{3} = src1_{1}src2_{2} - src1_{2}src2_{1}).
Calculates sum of scaled array and another array
void cvScaleAdd( const CvArr* src1, CvScalar scale, const CvArr* src2, CvArr* dst ); #define cvMulAddS cvScaleAdd
The function cvScaleAdd
calculates sum of scaled array and another array:
dst(I)=src1(I)*scale + src2(I)
All array parameters should have the same type and the same size.
Performs generalized matrix multiplication
void cvGEMM( const CvArr* src1, const CvArr* src2, double alpha, const CvArr* src3, double beta, CvArr* dst, int tABC=0 ); #define cvMatMulAdd( src1, src2, src3, dst ) cvGEMM( src1, src2, 1, src3, 1, dst, 0 ) #define cvMatMul( src1, src2, dst ) cvMatMulAdd( src1, src2, 0, dst )
alpha*src1^{T}*src2 + beta*src^{T}
The function cvGEMM
performs generalized matrix multiplication:
dst = alpha*op(src1)*op(src2) + beta*op(src3), where op(X) is X or X^{T}
All the matrices should have the same data type and the coordinated sizes. Real or complex floating-point matrices are supported
Performs matrix transform of every array element
void cvTransform( const CvArr* src, CvArr* dst, const CvMat* transmat, const CvMat* shiftvec=NULL );
The function cvTransform
performs matrix transformation of every element of array src
and stores the results in dst
:
dst(I)=transmat*src(I) + shiftvec or dst(I)_{k}=sum_{j}(transmat(k,j)*src(I)_{j}) + shiftvec(k)
That is every element of N
-channel array src
is considered as N
-element vector, which is
transformed using matrix M
×N
matrix transmat
and shift vector shiftvec
into an element of M
-channel array dst
.
There is an option to embedd shiftvec
into transmat
. In this case transmat
should be
M
×N+1
matrix and the right-most column is treated as the shift vector.
Both source and destination arrays should have the same depth and the same size or selected ROI
size. transmat
and shiftvec
should be real floating-point matrices.
The function may be used for geometrical transformation of N
D point set,
arbitrary linear color space transformation, shuffling the channels etc.
Performs perspective matrix transform of vector array
void cvPerspectiveTransform( const CvArr* src, CvArr* dst, const CvMat* mat );
The function cvPerspectiveTransform
transforms every element of src
(by treating it as 2D or 3D vector) in the following way:
(x, y, z) -> (x’/w, y’/w, z’/w) or (x, y) -> (x’/w, y’/w), where (x’, y’, z’, w’) = mat4x4*(x, y, z, 1) or (x’, y’, w’) = mat3x3*(x, y, 1) and w = w’ if w’!=0, inf otherwise
Calculates product of array and transposed array
void cvMulTransposed( const CvArr* src, CvArr* dst, int order, const CvArr* delta=NULL );
src
before multiplication.
The function cvMulTransposed
calculates the product of src and its transposition.
The function evaluates
dst=(src-delta)*(src-delta)^{T}
if order=0, and
dst=(src-delta)^{T}*(src-delta)
otherwise.
Returns trace of matrix
CvScalar cvTrace( const CvArr* mat );
The function cvTrace
returns sum of diagonal elements of the matrix src1
.
tr(src1)=sum_{i}mat(i,i)
Transposes matrix
void cvTranspose( const CvArr* src, CvArr* dst ); #define cvT cvTranspose
The function cvTranspose
transposes matrix src1
:
dst(i,j)=src(j,i)
Note that no complex conjugation is done in case of complex matrix. Conjugation should be done separately: look at the sample code in cvXorS for example
Returns determinant of matrix
double cvDet( const CvArr* mat );
The function cvDet
returns determinant of the square matrix mat
.
The direct method is used for small matrices and Gaussian elimination is used for larger matrices.
For symmetric positive-determined matrices it is also possible to run SVD
with U=V=NULL
and then calculate determinant as a product of the diagonal elements of W
Finds inverse or pseudo-inverse of matrix
double cvInvert( const CvArr* src, CvArr* dst, int method=CV_LU ); #define cvInv cvInvert
The function cvInvert
inverts matrix src1
and stores the result in src2
In case of LU
method the function returns src1
determinant (src1 must be square).
If it is 0, the matrix is not inverted and src2
is filled with zeros.
In case of SVD
methods the function returns the inversed condition number of src1
(ratio of the smallest singular value to the largest singular value) and 0 if src1
is all zeros.
The SVD methods calculate a pseudo-inverse matrix if src1
is singular
Solves linear system or least-squares problem
int cvSolve( const CvArr* A, const CvArr* B, CvArr* X, int method=CV_LU );
The function cvSolve
solves linear system or least-squares problem (the latter
is possible with SVD methods):
dst = arg min_{X}||A*X-B||
If CV_LU
method is used, the function returns 1 if src1
is non-singular and
0 otherwise, in the latter case dst
is not valid
Performs singular value decomposition of real floating-point matrix
void cvSVD( CvArr* A, CvArr* W, CvArr* U=NULL, CvArr* V=NULL, int flags=0 );
M
×N
matrix.
M
×N
or N
×N
) or
vector (N
×1
).
M
×M
or M
×N
).
If CV_SVD_U_T is specified, the number of rows and columns in the sentence above should be swapped.
N
×N
)
CV_SVD_MODIFY_A
enables modification of matrix src1
during the operation. It
speeds up the processing.
CV_SVD_U_T
means that the tranposed matrix U
is returned.
Specifying the flag speeds up the processing.
CV_SVD_V_T
means that the tranposed matrix V
is returned.
Specifying the flag speeds up the processing.
The function cvSVD
decomposes matrix A
into a product of a diagonal matrix and two
orthogonal matrices:
A=U*W*V^{T}
Where W
is diagonal matrix of singular values that can be coded as a 1D
vector of singular values and U
and V
. All the singular values are non-negative and sorted (together with U
and
and V
columns) in descenting order.
SVD algorithm is numerically robust and its typical applications include:
A
is square, symmetric and positively
defined matrix, for example, when it is a covariation matrix.
W
in this case will be a vector of eigen values, and U
=V
is matrix of
eigen vectors (thus, only one of U
or V
needs to be calculated if
the eigen vectors are required)CV_SVD
methodU
and V
matrices.Performs singular value back substitution
void cvSVBkSb( const CvArr* W, const CvArr* U, const CvArr* V, const CvArr* B, CvArr* X, int flags );
A
by.
This is the optional parameter. If it is omitted then it is assumed to be
an identity matrix of an appropriate size (So X
will be the reconstructed
pseudo-inverse of A
).
flags
passed to cvSVD.
The function cvSVBkSb
calculates back substitution for decomposed matrix A
(see
cvSVD description) and matrix B
:
X=V*W^{-1}*U^{T}*B
Where
W^{-1}(i,i)=1/W(i,i) if W(i,i) > epsilon•sum_{i}W(i,i), 0 otherwise
And epsilon
is a small number that depends on the matrix data type.
Computes eigenvalues and eigenvectors of symmetric matrix
void cvEigenVV( CvArr* mat, CvArr* evects, CvArr* evals, double eps=0 );
The function cvEigenVV
computes the eigenvalues and eigenvectors of the matrix A
:
mat*evects(i,:)' = evals(i)*evects(i,:)' (in MATLAB notation)
The contents of matrix A
is destroyed by the function.
Currently the function is slower than cvSVD yet less accurate,
so if A
is known to be positively-defined (for example, it is a covariation matrix),
it is recommended to use cvSVD to find eigenvalues and eigenvectors of A
,
especially if eigenvectors are not required. That is, instead of
cvEigenVV(mat, eigenvals, eigenvects);call
cvSVD(mat, eigenvals, eigenvects, 0, CV_SVD_U_T + CV_SVD_MODIFY_A);
Calculates covariation matrix of the set of vectors
void cvCalcCovarMatrix( const CvArr** vects, int count, CvArr* cov_mat, CvArr* avg, int flags );
CV_COVAR_SCRAMBLED
- the output covaration matrix is calculated as:scale*[vects[0]-avg,vects[1]-avg,...]^{T}*[vects[0]-avg,vects[1]-avg,...]
,count
×count
. Such an unusual
covariation matrix is used for fast PCA of a set of very large vectors
(see, for example, EigenFaces technique for face recognition). Eigenvalues of this
"scrambled" matrix will match to the eigenvalues of the true covariation matrix and
the "true" eigenvectors can be easily calculated from the eigenvectors of the "scrambled" covariation
matrix.CV_COVAR_NORMAL
- the output covaration matrix is calculated as:scale*[vects[0]-avg,vects[1]-avg,...]*[vects[0]-avg,vects[1]-avg,...]^{T}
,cov_mat
will be a usual covariation matrix with the same linear size as the total number of
elements in every input vector. One and only one of CV_COVAR_SCRAMBLED
and CV_COVAR_NORMAL
must be specifiedCV_COVAR_USE_AVG
- if the flag is specified, the function does not calculate avg
from
the input vectors, but, instead, uses the passed avg
vector. This is useful if avg
has been already calculated somehow, or if the covariation matrix is calculated by parts - in this case,
avg
is not a mean vector of the input sub-set of vectors, but rather the mean vector of
the whole set.CV_COVAR_SCALE
- if the flag is specified, the covariation matrix is scaled by
the number of input vectors.
CV_COVAR_ROWS
- Means that all the input vectors are stored as rows of a single matrix, vects[0]
.
count
is ignored in this case, and avg
should be a single-row vector of an appropriate size.
CV_COVAR_COLS
- Means that all the input vectors are stored as columns of a single matrix, vects[0]
.
count
is ignored in this case, and avg
should be a single-column vector of an appropriate size.
The function cvCalcCovarMatrix
calculates the covariation matrix and, optionally,
mean vector of the set of input vectors. The function can be used for PCA, for comparing vectors using Mahalanobis distance etc.
Calculates Mahalonobis distance between two vectors
double cvMahalanobis( const CvArr* vec1, const CvArr* vec2, CvArr* mat );
The function cvMahalonobis
calculates the weighted distance between two vectors
and returns it:
d(vec1,vec2)=sqrt( sum_{i,j} {mat(i,j)*(vec1(i)-vec2(i))*(vec1(j)-vec2(j))} )
The covariation matrix may be calculated using cvCalcCovarMatrix function and further inverted using cvInvert function (CV_SVD method is the preffered one, because the matrix might be singular).
Performs Principal Component Analysis of a vector set
void cvCalcPCA( const CvArr* data, CvArr* avg, CvArr* eigenvalues, CvArr* eigenvectors, int flags );
CV_PCA_DATA_AS_ROW
)
or a single column (CV_PCA_DATA_AS_COL
).
CV_PCA_DATA_AS_ROW
- the vectors are stored as rows
(i.e. all the components of a certain vector are stored continously)CV_PCA_DATA_AS_COL
- the vectors are stored as columns
(i.e. values of a certain vector component are stored continuously)CV_PCA_USE_AVG
- use pre-computed average vector
The function cvCalcPCA
performs PCA analysis of the vector set.
First, it uses cvCalcCovarMatrix to compute covariation matrix
and then it finds its eigenvalues and eigenvectors. The output number of eigenvalues/eigenvectors
should be less than or equal to MIN(rows(data),cols(data))
.
Projects vectors to the specified subspace
void cvProjectPCA( const CvArr* data, const CvArr* avg, const CvArr* eigenvectors, CvArr* result )
data
;
otherwise, it should be a single-column vector,
then the vectors are stored as columns of data
.
eigenvectors
.
That it is less, the input vectors are projected into subspace
of the first cols(result)
principal components.
The function cvProjectPCA
projects input vectors to the subspace represented by the
orthonormal basis (eigenvectors
). Before computing the dot products, avg
vector is subtracted from the input vectors:
result(i,:)=(data(i,:)-avg)*eigenvectors' // for CV_PCA_DATA_AS_ROW layout.
Reconstructs the original vectors from the projection coefficients
void cvBackProjectPCA( const CvArr* proj, const CvArr* avg, const CvArr* eigenvects, CvArr* result );
result
in
cvProjectPCA.
result
;
otherwise, it should be a single-column vector,
then the vectors are stored as columns of result
.
The function cvBackProjectPCA
reconstructs the vectors from the projection coefficients:
result(i,:)=proj(i,:)*eigenvectors + avg // for CV_PCA_DATA_AS_ROW layout.
Converts floating-point number to integer
int cvRound( double value ); int cvFloor( double value ); int cvCeil( double value );
The functions cvRound, cvFloor
and cvCeil
convert input floating-point number to
integer using one of the rounding modes. cvRound
returns the nearest integer value to
the argument.
cvFloor
returns the maximum integer value that is not larger than the argument.
cvCeil
returns the minimum integer value that is not smaller than the argument.
On some architectures the functions work much faster than the standard cast operations in C.
If absolute value of the argument is greater than 2^{31}, the result is not determined.
Special values (±Inf, NaN) are not handled.
Calculates square root
float cvSqrt( float value );
The function cvSqrt
calculates square root of the argument.
If the argument is negative, the result is not determined.
Calculates inverse square root
float cvInvSqrt( float value );
The function cvInvSqrt
calculates inverse square root of the argument, and
normally it is faster than 1./sqrt(value)
. If the argument is zero or negative, the result is
not determined. Special values (±Inf, NaN) are not handled.
Calculates cubic root
float cvCbrt( float value );
The function cvCbrt
calculates cubic root of the argument, and
normally it is faster than pow(value,1./3)
. Besides, negative arguments are handled properly.
Special values (±Inf, NaN) are not handled.
Calculates angle of 2D vector
float cvFastArctan( float y, float x );
The function cvFastArctan
calculates full-range angle of input 2D vector.
The angle is measured in degrees and varies from 0° to 360°. The accuracy is ~0.1°
Determines if the argument is Not A Number
int cvIsNaN( double value );
The function cvIsNaN
returns 1 if the argument is Not A Number (as defined
by IEEE754 standard), 0 otherwise.
Determines if the argument is Infinity
int cvIsInf( double value );
The function cvIsInf
returns 1 if the argument is ±Infinity (as defined
by IEEE754 standard), 0 otherwise.
Calculates magnitude and/or angle of 2d vectors
void cvCartToPolar( const CvArr* x, const CvArr* y, CvArr* magnitude, CvArr* angle=NULL, int angle_in_degrees=0 );
The function cvCartToPolar
calculates either magnitude, angle,
or both of every 2d vector (x(I),y(I))
:
magnitude(I)=sqrt( x(I)^{2}+y(I)^{2} ), angle(I)=atan( y(I)/x(I) )
The angles are calculated with ≈0.1° accuracy. For (0,0) point the angle is set to 0.
Calculates cartesian coordinates of 2d vectors represented in polar form
void cvPolarToCart( const CvArr* magnitude, const CvArr* angle, CvArr* x, CvArr* y, int angle_in_degrees=0 );
The function cvPolarToCart
calculates either x-coodinate, y-coordinate
or both of every vector magnitude(I)*exp(angle(I)*j), j=sqrt(-1)
:
x(I)=magnitude(I)*cos(angle(I)), y(I)=magnitude(I)*sin(angle(I))
Raises every array element to power
void cvPow( const CvArr* src, CvArr* dst, double power );
The function cvPow
raises every element of input array to p
:
dst(I)=src(I)^{p}, if p
is integer
dst(I)=abs(src(I))^{p}, otherwise
That is, for non-integer power exponent the absolute values of input array elements are used. However, it is possible to get true values for negative values using some extra operations, as the following sample, computing cube root of array elements, shows:
CvSize size = cvGetSize(src); CvMat* mask = cvCreateMat( size.height, size.width, CV_8UC1 ); cvCmpS( src, 0, mask, CV_CMP_LT ); /* find negative elements */ cvPow( src, dst, 1./3 ); cvSubRS( dst, cvScalarAll(0), dst, mask ); /* negate the results of negative inputs */ cvReleaseMat( &mask );
For some values of power
, such as integer values, 0.5 and -0.5,
specialized faster algorithms are used.
Calculates exponent of every array element
void cvExp( const CvArr* src, CvArr* dst );
double
type or
the same type as the source.
The function cvExp
calculates exponent of every element of input array:
dst(I)=exp(src(I))
Maximum relative error is ≈7e-6. Currently, the function converts denormalized values to zeros on output.
Calculates natural logarithm of every array element absolute value
void cvLog( const CvArr* src, CvArr* dst );
double
type or
the same type as the source.
The function cvLog
calculates natural logarithm
of absolute value of every element of input array:
dst(I)=log(abs(src(I))), src(I)!=0 dst(I)=C, src(I)=0Where
C
is large negative number (≈-700 in the current implementation)
Finds real roots of a cubic equation
int cvSolveCubic( const CvMat* coeffs, CvMat* roots );
The function cvSolveCubic
finds real roots of a cubic equation:
coeffs[0]*x^{3} + coeffs[1]*x^{2} + coeffs[2]*x + coeffs[3] = 0 (if coeffs is 4-element vector) or x^{3} + coeffs[0]*x^{2} + coeffs[1]*x + coeffs[2] = 0 (if coeffs is 3-element vector)
The function returns the number of real roots found. The roots are stored
to root
array, which is padded with zeros if there is only one root.
Initializes random number generator state
CvRNG cvRNG( int64 seed=-1 );
The function cvRNG
initializes random number generator
and returns the state. Pointer to the state can be then passed to cvRandInt,
cvRandReal and cvRandArr functions.
In the current implementation a multiply-with-carry generator is used.
Fills array with random numbers and updates the RNG state
void cvRandArr( CvRNG* rng, CvArr* arr, int dist_type, CvScalar param1, CvScalar param2 );
The function cvRandArr
fills the destination array with
uniformly or normally distributed random numbers. In the sample below
the function is used to add a few normally distributed
floating-point numbers to random locations within a 2d array
/* let noisy_screen be the floating-point 2d array that is to be "crapped" */ CvRNG rng_state = cvRNG(0xffffffff); int i, pointCount = 1000; /* allocate the array of coordinates of points */ CvMat* locations = cvCreateMat( pointCount, 1, CV_32SC2 ); /* arr of random point values */ CvMat* values = cvCreateMat( pointCount, 1, CV_32FC1 ); CvSize size = cvGetSize( noisy_screen ); cvRandInit( &rng_state, 0, 1, /* use dummy parameters now and adjust them further */ 0xffffffff /* just use a fixed seed here */, CV_RAND_UNI /* specify uniform type */ ); /* initialize the locations */ cvRandArr( &rng_state, locations, CV_RAND_UNI, cvScalar(0,0,0,0), cvScalar(size.width,size.height,0,0) ); /* modify RNG to make it produce normally distributed values */ rng_state.disttype = CV_RAND_NORMAL; cvRandSetRange( &rng_state, 30 /* deviation */, 100 /* average point brightness */, -1 /* initialize all the dimensions */ ); /* generate values */ cvRandArr( &rng_state, values, CV_RAND_NORMAL, cvRealScalar(100), // average intensity cvRealScalar(30) // deviation of the intensity ); /* set the points */ for( i = 0; i < pointCount; i++ ) { CvPoint pt = *(CvPoint*)cvPtr1D( locations, i, 0 ); float value = *(float*)cvPtr1D( values, i, 0 ); *((float*)cvPtr2D( noisy_screen, pt.y, pt.x, 0 )) += value; } /* not to forget to release the temporary arrays */ cvReleaseMat( &locations ); cvReleaseMat( &values ); /* RNG state does not need to be deallocated */
Returns 32-bit unsigned integer and updates RNG
unsigned cvRandInt( CvRNG* rng );
RandInit
and, optionally,
customized by RandSetRange
(though, the latter function does not
affect on the discussed function outcome).
The function cvRandInt
returns uniformly-distributed random
32-bit unsigned integer and updates RNG state. It is similar to rand() function from C runtime library,
but it always generates 32-bit number whereas rand() returns a number in between 0
and RAND_MAX
which is 2**16 or 2**32, depending on the platform.
The function is useful for generating scalar random numbers, such as points, patch sizes, table indices etc, where integer numbers of a certain range can be generated using modulo operation and floating-point numbers can be generated by scaling to 0..1 of any other specific range. Here is the example from the previous function discussion rewritten using cvRandInt:
/* the input and the task is the same as in the previous sample. */ CvRNG rng_state = cvRNG(0xffffffff); int i, pointCount = 1000; /* ... - no arrays are allocated here */ CvSize size = cvGetSize( noisy_screen ); /* make a buffer for normally distributed numbers to reduce call overhead */ #define bufferSize 16 float normalValueBuffer[bufferSize]; CvMat normalValueMat = cvMat( bufferSize, 1, CV_32F, normalValueBuffer ); int valuesLeft = 0; for( i = 0; i < pointCount; i++ ) { CvPoint pt; /* generate random point */ pt.x = cvRandInt( &rng_state ) % size.width; pt.y = cvRandInt( &rng_state ) % size.height; if( valuesLeft <= 0 ) { /* fulfill the buffer with normally distributed numbers if the buffer is empty */ cvRandArr( &rng_state, &normalValueMat, CV_RAND_NORMAL, cvRealScalar(100), cvRealScalar(30) ); valuesLeft = bufferSize; } *((float*)cvPtr2D( noisy_screen, pt.y, pt.x, 0 ) = normalValueBuffer[--valuesLeft]; } /* there is no need to deallocate normalValueMat because we have both the matrix header and the data on stack. It is a common and efficient practice of working with small, fixed-size matrices */
Returns floating-point random number and updates RNG
double cvRandReal( CvRNG* rng );
The function cvRandReal
returns uniformly-distributed random
floating-point number from 0..1 range (1 is not included).
Performs forward or inverse Discrete Fourier transform of 1D or 2D floating-point array
#define CV_DXT_FORWARD 0 #define CV_DXT_INVERSE 1 #define CV_DXT_SCALE 2 #define CV_DXT_ROWS 4 #define CV_DXT_INV_SCALE (CV_DXT_SCALE|CV_DXT_INVERSE) #define CV_DXT_INVERSE_SCALE CV_DXT_INV_SCALE void cvDFT( const CvArr* src, CvArr* dst, int flags, int nonzero_rows=0 );
CV_DXT_FORWARD
- do forward 1D or 2D transform. The result is not scaled.CV_DXT_INVERSE
- do inverse 1D or 2D transform. The result is not scaled.
CV_DXT_FORWARD
and CV_DXT_INVERSE
are mutually exclusive,
of course.CV_DXT_SCALE
- scale the result: divide it by the number of array elements.
Usually, it is combined with CV_DXT_INVERSE
, and one
may use a shortcut CV_DXT_INV_SCALE
.CV_DXT_ROWS
- do forward or inverse transform of every individual row of the input
matrix. This flag allows user to transform multiple vectors simultaneously and
can be used to decrease the overhead (which is sometimes several times
larger than the processing itself), to do 3D and higher-dimensional
transforms etc.
The function cvDFT
performs forward or inverse transform of
1D or 2D floating-point array:
Forward Fourier transform of 1D vector of N elements: y = F^{(N)}•x, where F^{(N)}_{jk}=exp(-i•2Pi•j•k/N), i=sqrt(-1) Inverse Fourier transform of 1D vector of N elements: x'= (F^{(N)})^{-1}•y = conj(F^{(N)})•y x = (1/N)•x Forward Fourier transform of 2D vector of M×N elements: Y = F^{(M)}•X•F^{(N)} Inverse Fourier transform of 2D vector of M×N elements: X'= conj(F^{(M)})•Y•conj(F^{(N)}) X = (1/(M•N))•X'
In case of real (single-channel) data, the packed format, borrowed from IPL, is used to to represent a result of forward Fourier transform or input for inverse Fourier transform:
Re Y_{0,0} Re Y_{0,1} Im Y_{0,1} Re Y_{0,2} Im Y_{0,2} ... Re Y_{0,N/2-1} Im Y_{0,N/2-1} Re Y_{0,N/2} Re Y_{1,0} Re Y_{1,1} Im Y_{1,1} Re Y_{1,2} Im Y_{1,2} ... Re Y_{1,N/2-1} Im Y_{1,N/2-1} Re Y_{1,N/2} Im Y_{1,0} Re Y_{2,1} Im Y_{2,1} Re Y_{2,2} Im Y_{2,2} ... Re Y_{2,N/2-1} Im Y_{2,N/2-1} Im Y_{2,N/2} ............................................................................................ Re Y_{M/2-1,0} Re Y_{M-3,1} Im Y_{M-3,1} Re Y_{M-3,2} Im Y_{M-3,2} ... Re Y_{M-3,N/2-1} Im Y_{M-3,N/2-1} Re Y_{M-3,N/2} Im Y_{M/2-1,0} Re Y_{M-2,1} Im Y_{M-2,1} Re Y_{M-2,2} Im Y_{M-2,2} ... Re Y_{M-2,N/2-1} Im Y_{M-2,N/2-1} Im Y_{M-2,N/2} Re Y_{M/2,0} Re Y_{M-1,1} Im Y_{M-1,1} Re Y_{M-1,2} Im Y_{M-1,2} ... Re Y_{M-1,N/2-1} Im Y_{M-1,N/2-1} Im Y_{M-1,N/2}
Note: the last column is present if N
is even, the last row is present if M
is even.
In case of 1D real transform the result looks like the first row of the above matrix
Computing 2D Convolution using DFTCvMat* A = cvCreateMat( M1, N1, CV_32F ); CvMat* B = cvCreateMat( M2, N2, A->type ); // it is also possible to have only abs(M2-M1)+1×abs(N2-N1)+1 // part of the full convolution result CvMat* conv = cvCreateMat( A->rows + B->rows - 1, A->cols + B->cols - 1, A->type ); // initialize A and B ... int dft_M = cvGetOptimalDFTSize( A->rows + B->rows - 1 ); int dft_N = cvGetOptimalDFTSize( A->cols + B->cols - 1 ); CvMat* dft_A = cvCreateMat( dft_M, dft_N, A->type ); CvMat* dft_B = cvCreateMat( dft_M, dft_N, B->type ); CvMat tmp; // copy A to dft_A and pad dft_A with zeros cvGetSubRect( dft_A, &tmp, cvRect(0,0,A->cols,A->rows)); cvCopy( A, &tmp ); cvGetSubRect( dft_A, &tmp, cvRect(A->cols,0,dft_A->cols - A->cols,A->rows)); cvZero( &tmp ); // no need to pad bottom part of dft_A with zeros because of // use nonzero_rows parameter in cvDFT() call below cvDFT( dft_A, dft_A, CV_DXT_FORWARD, A->rows ); // repeat the same with the second array cvGetSubRect( dft_B, &tmp, cvRect(0,0,B->cols,B->rows)); cvCopy( B, &tmp ); cvGetSubRect( dft_B, &tmp, cvRect(B->cols,0,dft_B->cols - B->cols,B->rows)); cvZero( &tmp ); // no need to pad bottom part of dft_B with zeros because of // use nonzero_rows parameter in cvDFT() call below cvDFT( dft_B, dft_B, CV_DXT_FORWBRD, B->rows ); cvMulSpectrums( dft_A, dft_B, dft_A, 0 /* or CV_DXT_MUL_CONJ to get correlation rather than convolution */ ); cvDFT( dft_A, dft_A, CV_DXT_INV_SCALE, conv->rows ); // calculate only the top part cvGetSubRect( dft_A, &tmp, cvRect(0,0,conv->cols,conv->rows) ); cvCopy( &tmp, conv );
Returns optimal DFT size for given vector size
int cvGetOptimalDFTSize( int size0 );
The function cvGetOptimalDFTSize
returns the minimum
number N
that is greater to equal to size0
, such that DFT of a vector
of size N
can be computed fast. In the current implementation
N=2^{p}×3^{q}×5^{r}
for some p, q, r
.
The function returns a negative number if size0
is too large (very close to INT_MAX
)
Performs per-element multiplication of two Fourier spectrums
void cvMulSpectrums( const CvArr* src1, const CvArr* src2, CvArr* dst, int flags );
CV_DXT_ROWS
- treat each row of the arrays as a separate spectrum
(see cvDFT parameters description).CV_DXT_MUL_CONJ
- conjugate the second source array before the multiplication.
The function cvMulSpectrums
performs per-element multiplication
of the two CCS-packed or complex matrices that are results of real or complex Fourier transform.
The function, together with cvDFT, may be used to calculate convolution of two arrays fast.
Performs forward or inverse Discrete Cosine transform of 1D or 2D floating-point array
#define CV_DXT_FORWARD 0 #define CV_DXT_INVERSE 1 #define CV_DXT_ROWS 4 void cvDCT( const CvArr* src, CvArr* dst, int flags );
CV_DXT_FORWARD
- do forward 1D or 2D transform.CV_DXT_INVERSE
- do inverse 1D or 2D transform.CV_DXT_ROWS
- do forward or inverse transform of every individual row of the input
matrix. This flag allows user to transform multiple vectors simultaneously and
can be used to decrease the overhead (which is sometimes several times
larger than the processing itself), to do 3D and higher-dimensional
transforms etc.
The function cvDCT
performs forward or inverse transform of
1D or 2D floating-point array:
Forward Cosine transform of 1D vector of N elements: y = C^{(N)}•x, where C^{(N)}_{jk}=sqrt((j==0?1:2)/N)•cos(Pi•(2k+1)•j/N) Inverse Cosine transform of 1D vector of N elements: x = (C^{(N)})^{-1}•y = (C^{(N)})^{T}•y Forward Cosine transform of 2D vector of M×N elements: Y = (C^{(M)})•X•(C^{(N)})^{T} Inverse Cosine transform of 2D vector of M×N elements: X = (C^{(M)})^{T}•Y•C^{(N)}
Growing memory storage
typedef struct CvMemStorage
{
struct CvMemBlock* bottom;/* first allocated block */
struct CvMemBlock* top; /* the current memory block - top of the stack */
struct CvMemStorage* parent; /* borrows new blocks from */
int block_size; /* block size */
int free_space; /* free space in the top
block (in bytes) */
} CvMemStorage;
Memory storage is a low-level structure used to store dynamically growing data structures such as
sequences, contours, graphs, subdivisions etc. It is organized as a list of memory blocks of
equal size - bottom
field is the beginning of the list of blocks
and top
is the currently used block, but not necessarily the last block of the list. All blocks
between bottom
and top
, not including the latter, are considered fully ocupied;
and all blocks between top
and the last block, not including top
,
are considered free and top
block itself is partly ocupied - free_space
contains the number of free bytes left in the end of top
.
New memory buffer that may be allocated explicitly by cvMemStorageAlloc function
or implicitly by
higher-level functions, such as cvSeqPush, cvGraphAddEdge etc., always
starts in the end of the current block if it fits there. After allocation free_space
is decremented by the size of the allocated buffer plus some padding to keep the proper alignment.
When the allocated buffer does not fit into the available part of top
, the next storage
block from the list is taken as top
and free_space
is reset to the
whole block size prior to the allocation.
If there is no more free blocks, a new block is allocated (or borrowed from parent, see
cvCreateChildMemStorage) and added to the end of list. Thus, the storage behaves as a stack
with bottom
indicating bottom of the stack and the pair (top
, free_space
)
indicating top of the stack. The stack top may be saved via cvSaveMemStoragePos,
restored via cvRestoreMemStoragePos or reset via cvClearStorage.
Memory storage block
typedef struct CvMemBlock { struct CvMemBlock* prev; struct CvMemBlock* next; } CvMemBlock;
The structure CvMemBlock represents a single block of memory storage.
Actual data of the memory blocks follows the header, that is, the i-th
byte of
the memory block can be retrieved with the expression ((char*)(mem_block_ptr+1))[i]
.
However, normally there is no need to access the storage structure fields directly.
Memory storage position
typedef struct CvMemStoragePos { CvMemBlock* top; int free_space; } CvMemStoragePos;
The structure described below stores the position of the stack top that can be saved via cvSaveMemStoragePos and restored via cvRestoreMemStoragePos.
Creates memory storage
CvMemStorage* cvCreateMemStorage( int block_size=0 );
The function cvCreateMemStorage
creates a memory storage and returns pointer
to it. Initially the storage is empty. All fields of the header, except the block_size
,
are set to 0.
Creates child memory storage
CvMemStorage* cvCreateChildMemStorage( CvMemStorage* parent );
The function cvCreateChildMemStorage
creates a child memory storage that is similar
to simple memory storage except for the differences in the memory
allocation/deallocation mechanism. When a child storage needs a new block to
add to the block list, it tries to get this block from the parent. The first
unoccupied parent block available is taken and excluded from the parent block
list. If no blocks are available, the parent either allocates a block or borrows
one from its own parent, if any. In other words, the chain, or a more complex
structure, of memory storages where every storage is a child/parent of another
is possible. When a child storage is released or even cleared, it returns all
blocks to the parent. In other aspects, the child storage is the same as the simple storage.
The children storages are useful in the following situation. Imagine that user needs to process dynamical data resided in some storage and put the result back to the same storage. With the simplest approach, when temporary data is resided in the same storage as the input and output data, the storage will look as following after processing:
Dynamic data processing without using child storage
That is, garbage appears in the middle of the storage. However, if one creates a child memory storage in the beginning of the processing, writes temporary data there and releases the child storage in the end, no garbage will appear in the source/destination storage:
Dynamic data processing using a child storage
Releases memory storage
void cvReleaseMemStorage( CvMemStorage** storage );
The function cvReleaseMemStorage
deallocates all storage memory blocks or returns
them to the parent, if any. Then it deallocates the storage header and clears
the pointer to the storage. All children of the storage must be released before
the parent is released.
Clears memory storage
void cvClearMemStorage( CvMemStorage* storage );
The function cvClearMemStorage
resets the top (free space boundary) of the storage
to the very beginning. This function does not deallocate any memory. If the
storage has a parent, the function returns all blocks to the parent.
Allocates memory buffer in the storage
void* cvMemStorageAlloc( CvMemStorage* storage, size_t size );
The function cvMemStorageAlloc
allocates memory buffer in the storage. The buffer size
must not exceed the storage block size, otherwise runtime error is raised. The buffer address is
aligned by CV_STRUCT_ALIGN
(=sizeof(double)
for the moment) bytes.
Allocates text string in the storage
typedef struct CvString { int len; char* ptr; } CvString; CvString cvMemStorageAllocString( CvMemStorage* storage, const char* ptr, int len=-1 );
The function cvMemStorageAllocString
creates copy of the
string in the memory storage. It returns the structure that contains user-passed or computed length
of the string and pointer to the copied string.
Saves memory storage position
void cvSaveMemStoragePos( const CvMemStorage* storage, CvMemStoragePos* pos );
The function cvSaveMemStoragePos
saves the current position of the storage top to
the parameter pos
. The function cvRestoreMemStoragePos
can further retrieve
this position.
Restores memory storage position
void cvRestoreMemStoragePos( CvMemStorage* storage, CvMemStoragePos* pos );
The function cvRestoreMemStoragePos
restores the position of the storage top from
the parameter pos
. This function and The function cvClearMemStorage
are the
only methods to release memory occupied in memory blocks.
Note again that there is no way to free memory in the middle of the occupied part of the storage.
Growable sequence of elements
#define CV_SEQUENCE_FIELDS() \ int flags; /* micsellaneous flags */ \ int header_size; /* size of sequence header */ \ struct CvSeq* h_prev; /* previous sequence */ \ struct CvSeq* h_next; /* next sequence */ \ struct CvSeq* v_prev; /* 2nd previous sequence */ \ struct CvSeq* v_next; /* 2nd next sequence */ \ int total; /* total number of elements */ \ int elem_size;/* size of sequence element in bytes */ \ char* block_max;/* maximal bound of the last block */ \ char* ptr; /* current write pointer */ \ int delta_elems; /* how many elements allocated when the sequence grows (sequence granularity) */ \ CvMemStorage* storage; /* where the seq is stored */ \ CvSeqBlock* free_blocks; /* free blocks list */ \ CvSeqBlock* first; /* pointer to the first sequence block */ typedef struct CvSeq { CV_SEQUENCE_FIELDS() } CvSeq;
The structure CvSeq is a base for all of OpenCV dynamic data structures.
Such an unusual definition via a helper macro simplifies the extension of the structure
CvSeq with additional parameters.
To extend CvSeq the user may define a new structure and
put user-defined fields after all CvSeq fields that are included via the macro
CV_SEQUENCE_FIELDS()
.
There are two types of sequences - dense and sparse. Base type for dense sequences is CvSeq and such sequences are used to represent growable 1d arrays - vectors, stacks, queues, deques. They have no gaps in the middle - if an element is removed from the middle or inserted into the middle of the sequence the elements from the closer end are shifted. Sparse sequences have CvSet base class and they are discussed later in more details. They are sequences of nodes each of those may be either occupied or free as indicated by the node flag. Such sequences are used for unordered data structures such as sets of elements, graphs, hash tables etc.
The field header_size
contains the actual size of the
sequence header and should be greater or equal to sizeof(CvSeq)
.
The fields
h_prev, h_next, v_prev, v_next
can be used to create hierarchical structures
from separate sequences. The fields h_prev
and h_next
point to the previous and
the next sequences on the same hierarchical level while the fields v_prev
and
v_next
point to the previous and the next sequence in the vertical direction,
that is, parent and its first child. But these are just names and the pointers
can be used in a different way.
The field first
points to the first sequence
block, whose structure is described below.
The field total
contains the actual number of dense sequence elements and
number of allocated nodes in sparse sequence.
The field flags
contain the particular dynamic type
signature (CV_SEQ_MAGIC_VAL
for dense sequences and CV_SET_MAGIC_VAL
for sparse sequences)
in the highest 16 bits and miscellaneous information about the sequence.
The lowest CV_SEQ_ELTYPE_BITS
bits contain the ID of the
element type. Most of sequence processing functions do not use element type
but element size stored in elem_size
.
If sequence contains the numeric data of one of CvMat type
then the element type matches to the corresponding CvMat element type, e.g.
CV_32SC2 may be used for sequence of 2D points, CV_32FC1 for sequences of floating-point values etc.
CV_SEQ_ELTYPE(seq_header_ptr)
macro retrieves the type of sequence elements.
Processing function that work with numerical sequences check that elem_size
is equal
to the calculated from the type element size.
Besides CvMat compatible types, there are few extra element types defined
in cvtypes.h header:
Standard Types of Sequence Elements
#define CV_SEQ_ELTYPE_POINT CV_32SC2 /* (x,y) */ #define CV_SEQ_ELTYPE_CODE CV_8UC1 /* freeman code: 0..7 */ #define CV_SEQ_ELTYPE_GENERIC 0 /* unspecified type of sequence elements */ #define CV_SEQ_ELTYPE_PTR CV_USRTYPE1 /* =6 */ #define CV_SEQ_ELTYPE_PPOINT CV_SEQ_ELTYPE_PTR /* &elem: pointer to element of other sequence */ #define CV_SEQ_ELTYPE_INDEX CV_32SC1 /* #elem: index of element of some other sequence */ #define CV_SEQ_ELTYPE_GRAPH_EDGE CV_SEQ_ELTYPE_GENERIC /* &next_o, &next_d, &vtx_o, &vtx_d */ #define CV_SEQ_ELTYPE_GRAPH_VERTEX CV_SEQ_ELTYPE_GENERIC /* first_edge, &(x,y) */ #define CV_SEQ_ELTYPE_TRIAN_ATR CV_SEQ_ELTYPE_GENERIC /* vertex of the binary tree */ #define CV_SEQ_ELTYPE_CONNECTED_COMP CV_SEQ_ELTYPE_GENERIC /* connected component */ #define CV_SEQ_ELTYPE_POINT3D CV_32FC3 /* (x,y,z) */
The next CV_SEQ_KIND_BITS
bits specify the kind of the sequence:
Standard Kinds of Sequences
/* generic (unspecified) kind of sequence */ #define CV_SEQ_KIND_GENERIC (0 << CV_SEQ_ELTYPE_BITS) /* dense sequence suntypes */ #define CV_SEQ_KIND_CURVE (1 << CV_SEQ_ELTYPE_BITS) #define CV_SEQ_KIND_BIN_TREE (2 << CV_SEQ_ELTYPE_BITS) /* sparse sequence (or set) subtypes */ #define CV_SEQ_KIND_GRAPH (3 << CV_SEQ_ELTYPE_BITS) #define CV_SEQ_KIND_SUBDIV2D (4 << CV_SEQ_ELTYPE_BITS)
The remaining bits are used to identify different features specific to certain
sequence kinds and element types. For example, curves made of points (
CV_SEQ_KIND_CURVE|CV_SEQ_ELTYPE_POINT
), together with the flag
CV_SEQ_FLAG_CLOSED
belong to the type CV_SEQ_POLYGON
or, if other flags are
used, to its subtype. Many contour processing functions check the type of the input
sequence and report an error if they do not support this type. The file
cvtypes.h stores the complete list of all supported predefined sequence types
and helper macros designed to get the sequence type of other properties.
Below follows the definition of the building block of sequences.
Continuous sequence block
typedef struct CvSeqBlock { struct CvSeqBlock* prev; /* previous sequence block */ struct CvSeqBlock* next; /* next sequence block */ int start_index; /* index of the first element in the block + sequence->first->start_index */ int count; /* number of elements in the block */ char* data; /* pointer to the first element of the block */ } CvSeqBlock;
Sequence blocks make up a circular double-linked list, so the pointers prev
and
next
are never NULL
and point to the previous and the next sequence blocks
within the sequence. It means that next
of the last block is the first block and
prev
of the first block is the last block. The fields start_index
and count
help
to track the block location within the sequence. For example, if the sequence
consists of 10 elements and splits into three blocks of 3, 5, and 2 elements,
and the first block has the parameter start_index = 2
, then pairs (start_index, count)
for the sequence blocks are (2,3), (5, 5)
, and (10, 2)
correspondingly. The parameter start_index
of the first block is usually 0
unless some elements have been inserted at the beginning of the sequence.
A sequence slice
typedef struct CvSlice { int start_index; int end_index; } CvSlice; inline CvSlice cvSlice( int start, int end ); #define CV_WHOLE_SEQ_END_INDEX 0x3fffffff #define CV_WHOLE_SEQ cvSlice(0, CV_WHOLE_SEQ_END_INDEX) /* calculates the sequence slice length */ int cvSliceLength( CvSlice slice, const CvSeq* seq );
Some of functions that operate on sequences take CvSlice slice
parameter that is
often set to the whole sequence (CV_WHOLE_SEQ) by default. Either of the start_index
and end_index
may be negative or exceed the sequence length, start_index
is inclusive, end_index
is exclusive boundary. If they are equal, the slice is considered
empty (i.e. contains no elements). Because sequences are treated as circular structures,
the slice may select a few elements in the end of a sequence followed by a few elements in the beginning
of the sequence, for example, cvSlice(-2, 3)
in case of 10-element sequence will select 5-element slice,
containing pre-last (8th), last (9th), the very first (0th), second (1th) and third (2nd) elements.
The functions normalize the slice argument in the following way: first, cvSliceLength
is called to determine the length of the slice, then, start_index
of the slice is
normalized similarly to the argument of cvGetSeqElem
(i.e. negative indices are allowed).
The actual slice to process starts at the normalized start_index
and lasts cvSliceLength elements
(again, assuming the sequence is a circular structure).
If a function does not take slice argument, but you want to process only a part of the sequence, the sub-sequence may be extracted using cvSeqSlice function, or stored as into a continuous buffer with cvCvtSeqToArray (optionally, followed by cvMakeSeqHeaderForArray.
Creates sequence
CvSeq* cvCreateSeq( int seq_flags, int header_size, int elem_size, CvMemStorage* storage );
sizeof(CvSeq)
. If a specific type or its extension is indicated, this type must
fit the base type header.
CV_SEQ_ELTYPE_POINT
should be specified and the parameter elem_size
must be equal to sizeof(CvPoint)
.
The function cvCreateSeq
creates a sequence and returns the pointer to it. The
function allocates the sequence header in the storage block as one continuous
chunk and sets the structure fields flags
, elem_size
, header_size
and storage
to
passed values, sets delta_elems
to the default value (that may be reassigned using
cvSetSeqBlockSize function), and clears other header fields,
including the space after the first sizeof(CvSeq)
bytes.
Sets up sequence block size
void cvSetSeqBlockSize( CvSeq* seq, int delta_elems );
The function cvSetSeqBlockSize
affects memory allocation granularity.
When the free space in the sequence buffers has run out, the function allocates the space
for delta_elems
sequence elements. If this block immediately follows the one
previously allocated, the two blocks are concatenated, otherwise, a new sequence
block is created. Therefore, the bigger the parameter is, the lower the possible sequence
fragmentation, but the more space in the storage is wasted. When the
sequence is created, the parameter delta_elems
is set to the default value ≈1K.
The function can be called any time after the sequence is created and affects
future allocations. The function can modify the passed value of the parameter to
meet the memory storage constraints.
Adds element to sequence end
char* cvSeqPush( CvSeq* seq, void* element=NULL );
The function cvSeqPush
adds an element to the end of sequence and retuns pointer
to the allocated element. If the input element
is NULL,
the function simply allocates a space for one more element.
The following code demonstrates how to create a new sequence using this function:
CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* seq = cvCreateSeq( CV_32SC1, /* sequence of integer elements */ sizeof(CvSeq), /* header size - no extra fields */ sizeof(int), /* element size */ storage /* the container storage */ ); int i; for( i = 0; i < 100; i++ ) { int* added = (int*)cvSeqPush( seq, &i ); printf( "%d is added\n", *added ); } ... /* release memory storage in the end */ cvReleaseMemStorage( &storage );
The function cvSeqPush
has O(1) complexity, but there is a faster method for
writing large sequences (see cvStartWriteSeq and related functions).
Removes element from sequence end
void cvSeqPop( CvSeq* seq, void* element=NULL );
The function cvSeqPop
removes an element from the sequence. The function reports
an error if the sequence is already empty. The function has O(1) complexity.
Adds element to sequence beginning
char* cvSeqPushFront( CvSeq* seq, void* element=NULL );
The function cvSeqPushFront
is similar to cvSeqPush but it adds the new element
to the beginning of the sequence. The function has O(1) complexity.
Removes element from sequence beginning
void cvSeqPopFront( CvSeq* seq, void* element=NULL );
The function cvSeqPopFront
removes an element from the beginning of the sequence.
The function reports an error if the sequence is already empty. The function has O(1) complexity.
Pushes several elements to the either end of sequence
void cvSeqPushMulti( CvSeq* seq, void* elements, int count, int in_front=0 );
The function cvSeqPushMulti
adds several elements to either end of the sequence.
The elements are added to the sequence in the same order as they are arranged in the
input array but they can fall into different sequence blocks.
Removes several elements from the either end of sequence
void cvSeqPopMulti( CvSeq* seq, void* elements, int count, int in_front=0 );
The function cvSeqPopMulti
removes several elements from either end of the sequence.
If the number of the elements to be removed exceeds the total number of elements
in the sequence, the function removes as many elements as possible.
Inserts element in sequence middle
char* cvSeqInsert( CvSeq* seq, int before_index, void* element=NULL );
seq->total
(the maximal
allowed value of the parameter) is equal to cvSeqPush.
The function cvSeqInsert
shifts the sequence elements from the inserted position
to the nearest end of the sequence and copies the element
content there if
the pointer is not NULL. The function returns pointer to the inserted element.
Removes element from sequence middle
void cvSeqRemove( CvSeq* seq, int index );
The function cvSeqRemove
removes elements with the given index. If the index is
out of range the function reports an error.
An attempt to remove an element from an empty sequence is a
partitial case of this situation. The function removes an element by shifting the
sequence elements between the nearest end of the sequence and the index
-th position, not
counting the latter.
Clears sequence
void cvClearSeq( CvSeq* seq );
The function cvClearSeq
removes all elements from the sequence. The function does not return the
memory to the storage, but this memory is reused later when new elements are added
to the sequence. This function time complexity is O(1)
.
Returns pointer to sequence element by its index
char* cvGetSeqElem( const CvSeq* seq, int index ); #define CV_GET_SEQ_ELEM( TYPE, seq, index ) (TYPE*)cvGetSeqElem( (CvSeq*)(seq), (index) )
The function cvGetSeqElem
finds the element with the given index in the sequence
and returns the pointer to it. If the element is not found,
the function returns 0. The function supports negative indices, where -1 stands
for the last sequence element, -2 stands for the one before last, etc. If the
sequence is most likely to consist of a single sequence block or the desired
element is likely to be located in the first block, then the macro
CV_GET_SEQ_ELEM( elemType, seq, index )
should be used, where the parameter
elemType
is the type of sequence elements ( CvPoint for example), the parameter
seq
is a sequence, and the parameter index
is the index of the desired element.
The macro checks first whether the desired element belongs to the first block of
the sequence and returns it if it does, otherwise the macro calls the main
function GetSeqElem
. Negative indices always cause the cvGetSeqElem call.
The function has O(1) time complexity assuming that number of blocks is much smaller than the
number of elements.
Returns index of concrete sequence element
int cvSeqElemIdx( const CvSeq* seq, const void* element, CvSeqBlock** block=NULL );
NULL
, the address of the
sequence block that contains the element is stored in this location.
The function cvSeqElemIdx
returns the index of a sequence element or a negative
number if the element is not found.
Copies sequence to one continuous block of memory
void* cvCvtSeqToArray( const CvSeq* seq, void* elements, CvSlice slice=CV_WHOLE_SEQ );
The function cvCvtSeqToArray
copies the entire sequence or subsequence to the
specified buffer and returns the pointer to the buffer.
Constructs sequence from array
CvSeq* cvMakeSeqHeaderForArray( int seq_type, int header_size, int elem_size, void* elements, int total, CvSeq* seq, CvSeqBlock* block );
The function cvMakeSeqHeaderForArray
initializes sequence header for array.
The sequence header as well as the sequence block are allocated by the user (for example, on stack).
No data is copied by the function. The resultant sequence will consists of a single block and have
NULL storage pointer, thus, it is possible to read its elements, but the attempts to
add elements to the sequence will raise an error in most cases.
Makes separate header for the sequence slice
CvSeq* cvSeqSlice( const CvSeq* seq, CvSlice slice, CvMemStorage* storage=NULL, int copy_data=0 );
copy_data
!=0) or not (copy_data
=0)
The function cvSeqSlice
creates a sequence
that represents the specified slice of the input sequence. The new sequence either shares the elements
with the original sequence or has own copy of the elements.
So if one needs to process a part of sequence but the processing function does not have a slice parameter,
the required sub-sequence may be extracted using this function.
Creates a copy of sequence
CvSeq* cvCloneSeq( const CvSeq* seq, CvMemStorage* storage=NULL );
The function cvCloneSeq
makes a complete copy of the input sequence and returns it.
The call cvCloneSeq( seq, storage )
is equivalent to
cvSeqSlice( seq, CV_WHOLE_SEQ, storage, 1 )
Removes sequence slice
void cvSeqRemoveSlice( CvSeq* seq, CvSlice slice );
The function cvSeqRemoveSlice
removes slice from the sequence.
Inserts array in the middle of sequence
void cvSeqInsertSlice( CvSeq* seq, int before_index, const CvArr* from_arr );
The function cvSeqInsertSlice
inserts all from_arr
array elements at the specified position of the sequence. The array from_arr
can be a matrix or another sequence.
Reverses the order of sequence elements
void cvSeqInvert( CvSeq* seq );
The function cvSeqInvert
reverses the sequence in-place - makes the first element go last,
the last element go first etc.
Sorts sequence element using the specified comparison function
/* a < b ? -1 : a > b ? 1 : 0 */ typedef int (CV_CDECL* CvCmpFunc)(const void* a, const void* b, void* userdata); void cvSeqSort( CvSeq* seq, CvCmpFunc func, void* userdata=NULL );
qsort
from C runline except that in the latter
userdata
is not used
The function cvSeqSort
sorts the sequence in-place using the specified criteria.
Below is the example of the function use:
/* Sort 2d points in top-to-bottom left-to-right order */ static int cmp_func( const void* _a, const void* _b, void* userdata ) { CvPoint* a = (CvPoint*)_a; CvPoint* b = (CvPoint*)_b; int y_diff = a->y - b->y; int x_diff = a->x - b->x; return y_diff ? y_diff : x_diff; } ... CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* seq = cvCreateSeq( CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), storage ); int i; for( i = 0; i < 10; i++ ) { CvPoint pt; pt.x = rand() % 1000; pt.y = rand() % 1000; cvSeqPush( seq, &pt ); } cvSeqSort( seq, cmp_func, 0 /* userdata is not used here */ ); /* print out the sorted sequence */ for( i = 0; i < seq->total; i++ ) { CvPoint* pt = (CvPoint*)cvSeqElem( seq, i ); printf( "(%d,%d)\n", pt->x, pt->y ); } cvReleaseMemStorage( &storage );
Searches element in sequence
/* a < b ? -1 : a > b ? 1 : 0 */ typedef int (CV_CDECL* CvCmpFunc)(const void* a, const void* b, void* userdata); char* cvSeqSearch( CvSeq* seq, const void* elem, CvCmpFunc func, int is_sorted, int* elem_idx, void* userdata=NULL );
The function cvSeqSearch
searches the element in the sequence.
If the sequence is sorted, binary O(log(N)) search is used, otherwise, a simple linear search is used.
If the element is not found, the function returns NULL pointer and the index is set to the number of
sequence elements if the linear search is used, and to the smallest index i, seq(i)>elem
.
Initializes process of writing data to sequence
void cvStartAppendToSeq( CvSeq* seq, CvSeqWriter* writer );
The function cvStartAppendToSeq
initializes the process of writing data to the sequence.
Written elements are added to the end of the sequence by CV_WRITE_SEQ_ELEM( written_elem, writer )
macro.
Note that during the writing process other operations on the sequence may yield incorrect result or
even corrupt the sequence (see description of cvFlushSeqWriter that helps to avoid
some of these problems).
Creates new sequence and initializes writer for it
void cvStartWriteSeq( int seq_flags, int header_size, int elem_size, CvMemStorage* storage, CvSeqWriter* writer );
sizeof(CvSeq)
. If a certain type or extension is specified, it must fit the
base type header.
CV_SEQ_ELTYPE_POINT
), then the parameter elem_size must be equal to
sizeof(CvPoint)
.
The function cvStartWriteSeq
is a composition of cvCreateSeq and cvStartAppendToSeq.
The pointer to the created sequence is stored at writer->seq
and is also returned
by cvEndWriteSeq function that should be called in the end.
Finishes process of writing sequence
CvSeq* cvEndWriteSeq( CvSeqWriter* writer );
The function cvEndWriteSeq
finishes the writing process and returns the pointer to
the written sequence. The function also truncates the last incomplete sequence block to
return the remaining part of the block to the memory storage. After that the sequence
can be read and modified safely.
Updates sequence headers from the writer state
void cvFlushSeqWriter( CvSeqWriter* writer );
The function cvFlushSeqWriter
is intended to enable the user to read sequence
elements, whenever required, during the writing process, e.g., in order to check
specific conditions. The function updates the sequence headers to make reading
from the sequence possible. The writer is not closed, however, so that the
writing process can be continued any time. In some algorithm requires often flush'es,
consider using cvSeqPush instead.
Initializes process of sequential reading from sequence
void cvStartReadSeq( const CvSeq* seq, CvSeqReader* reader, int reverse=0 );
reverse
is 0,
the reader is positioned at the first sequence element, otherwise it is positioned at the last
element.
The function cvStartReadSeq
initializes the reader state. After that all the
sequence elements from the first down to the last one can be read by subsequent
calls of the macro CV_READ_SEQ_ELEM( read_elem, reader )
in case of forward reading
and by using CV_REV_READ_SEQ_ELEM( read_elem, reader )
in case of reversed reading.
Both macros put the sequence element to read_elem
and move the
reading pointer toward the next element.
A circular structure of sequence blocks is used for the reading process, that
is, after the last element has been read by the macro CV_READ_SEQ_ELEM
, the
first element is read when the macro is called again. The same applies to
CV_REV_READ_SEQ_ELEM
. There is no function to finish the reading process,
since it neither changes the sequence nor creates any temporary buffers. The reader
field ptr
points to the current element of the sequence that is to be read
next. The code below demonstrates how to use sequence writer and reader.
CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* seq = cvCreateSeq( CV_32SC1, sizeof(CvSeq), sizeof(int), storage ); CvSeqWriter writer; CvSeqReader reader; int i; cvStartAppendToSeq( seq, &writer ); for( i = 0; i < 10; i++ ) { int val = rand()%100; CV_WRITE_SEQ_ELEM( val, writer ); printf("%d is written\n", val ); } cvEndWriteSeq( &writer ); cvStartReadSeq( seq, &reader, 0 ); for( i = 0; i < seq->total; i++ ) { int val; #if 1 CV_READ_SEQ_ELEM( val, reader ); printf("%d is read\n", val ); #else /* alternative way, that is prefferable if sequence elements are large, or their size/type is unknown at compile time */ printf("%d is read\n", *(int*)reader.ptr ); CV_NEXT_SEQ_ELEM( seq->elem_size, reader ); #endif } ... cvReleaseStorage( &storage );
Returns the current reader position
int cvGetSeqReaderPos( CvSeqReader* reader );
The function cvGetSeqReaderPos
returns the current reader position
(within 0 ... reader->seq->total
- 1).
Moves the reader to specified position
void cvSetSeqReaderPos( CvSeqReader* reader, int index, int is_relative=0 );
index
mod reader->seq->total
.
index
is a relative to the current position.
The function cvSetSeqReaderPos
moves the read position to the absolute position or
relative to the current position.
Collection of nodes
typedef struct CvSetElem { int flags; /* it is negative if the node is free and zero or positive otherwise */ struct CvSetElem* next_free; /* if the node is free, the field is a pointer to next free node */ } CvSetElem; #define CV_SET_FIELDS() \ CV_SEQUENCE_FIELDS() /* inherits from CvSeq */ \ struct CvSetElem* free_elems; /* list of free nodes */ typedef struct CvSet { CV_SET_FIELDS() } CvSet;
The structure CvSet is a base for OpenCV sparse data structures.
As follows from the above declaration CvSet inherits from CvSeq
and it adds free_elems
field it to, which is a list of free nodes.
Every set node, whether free or not, is the element of the underlying sequence.
While there is no restrictions on elements of dense sequences, the set (and derived structures)
elements must start with integer field and be able to fit CvSetElem structure, because
these two fields (integer followed by the pointer) are required for organization of node set with
the list of free nodes. If a node is free, flags
field is negative (the most-significant
bit, or MSB, of the field is set), and next_free
points to the next free node (the first free node is referenced by free_elems
field of
CvSet). And if a node is occupied, flags
field is positive and contains the node index
that may be retrieved using (set_elem->flags & CV_SET_ELEM_IDX_MASK) expression,
the rest of the node content is determined by the user. In particular, the occupied nodes
are not linked as the free nodes are, so the second field can be used for such a link as well as
for some different purpose. The macro CV_IS_SET_ELEM(set_elem_ptr)
can be used to determined whether the specified node is occupied or not.
Initially the set and the list are empty. When a new node is requiested from the set,
it is taken from the list of free nodes, which is updated then. If the list appears to be empty,
a new sequence block is allocated and all the nodes within the block are joined in the list of free
nodes. Thus, total
field of the set is the total number of nodes both occupied and free.
When an occupied node is released, it is added to the list of free nodes. The node released last
will be occupied first.
In OpenCV CvSet is used for representing graphs (CvGraph), sparse multi-dimensional arrays (CvSparseMat), planar subdivisions (CvSubdiv2D) etc.
Creates empty set
CvSet* cvCreateSet( int set_flags, int header_size, int elem_size, CvMemStorage* storage );
sizeof(CvSet)
.
The function cvCreateSet
creates an empty set with a specified header size and element size, and
returns the pointer to the set. The function is just a thin layer on top of cvCreateSeq.
Occupies a node in the set
int cvSetAdd( CvSet* set_header, CvSetElem* elem=NULL, CvSetElem** inserted_elem=NULL );
The function cvSetAdd
allocates a new node, optionally copies input element data
to it, and returns the pointer and the index to the node. The index value is
taken from the lower bits of flags
field of the node. The function has O(1) complexity,
however there exists a faster function for allocating set nodes (see cvSetNew).
Removes element from set
void cvSetRemove( CvSet* set_header, int index );
The function cvSetRemove
removes an element with a specified index from the set.
If the node at the specified location is not occupied the function does nothing.
The function has O(1) complexity, however, cvSetRemoveByPtr provides yet
faster way to remove a set element if it is located already.
Adds element to set (fast variant)
CvSetElem* cvSetNew( CvSet* set_header );
The function cvSetNew
is inline light-weight variant of cvSetAdd.
It occupies a new node and returns pointer to it rather than index.
Removes set element given its pointer
void cvSetRemoveByPtr( CvSet* set_header, void* elem );
The function cvSetRemoveByPtr
is inline light-weight variant of cvSetRemove
that takes element pointer.
The function does not check whether the node is occupied or not - the user should take care of it.
Finds set element by its index
CvSetElem* cvGetSetElem( const CvSet* set_header, int index );
The function cvGetSetElem
finds a set element by index. The function returns the
pointer to it or 0 if the index is invalid or the corresponding node is free.
The function supports negative indices as it uses cvGetSeqElem to locate the node.
Clears set
void cvClearSet( CvSet* set_header );
The function cvClearSet
removes all elements from set. It has O(1) time complexity.
Oriented or unoriented weigted graph
#define CV_GRAPH_VERTEX_FIELDS() \ int flags; /* vertex flags */ \ struct CvGraphEdge* first; /* the first incident edge */ typedef struct CvGraphVtx { CV_GRAPH_VERTEX_FIELDS() } CvGraphVtx; #define CV_GRAPH_EDGE_FIELDS() \ int flags; /* edge flags */ \ float weight; /* edge weight */ \ struct CvGraphEdge* next[2]; /* the next edges in the incidence lists for staring (0) */ \ /* and ending (1) vertices */ \ struct CvGraphVtx* vtx[2]; /* the starting (0) and ending (1) vertices */ typedef struct CvGraphEdge { CV_GRAPH_EDGE_FIELDS() } CvGraphEdge; #define CV_GRAPH_FIELDS() \ CV_SET_FIELDS() /* set of vertices */ \ CvSet* edges; /* set of edges */ typedef struct CvGraph { CV_GRAPH_FIELDS() } CvGraph;
The structure CvGraph is a base for graphs used in OpenCV.
Graph structure inherits from CvSet - this part describes common graph properties and the graph vertices, and contains another set as a member - this part describes the graph edges.
The vertex, edge and the graph header structures are declared using the same technique as other
extendible OpenCV structures - via macros, that simplifies extension and customization of the structures.
While the vertex and edge structures do not inherit from CvSetElem explicitly, they satisfy
both conditions on the set elements - have an integer field in the beginning and fit CvSetElem structure.
The flags
fields are used as for indicating occupied vertices and edges as well as
for other purposes, for example, for graph traversal (see cvCreateGraphScanner et al.), so
it is better not to use them directly.
The graph is represented as a set of edges each of whose has the list of incident edges. The incidence lists for different vertices are interleaved to avoid information duplication as much as posssible.
The graph may be oriented or unoriented. In the latter case there is no distiction between edge connecting vertex A with vertex B and the edge connecting vertex B with vertex A - only one of them can exist in the graph at the same moment and it represents both <A, B> and <B, A> edges..
Creates empty graph
CvGraph* cvCreateGraph( int graph_flags, int header_size, int vtx_size, int edge_size, CvMemStorage* storage );
CV_SEQ_KIND_GRAPH
for generic unoriented graphs and CV_SEQ_KIND_GRAPH | CV_GRAPH_FLAG_ORIENTED
for generic oriented graphs.
sizeof(CvGraph).
CV_GRAPH_VERTEX_FIELDS()
)
CV_GRAPH_EDGE_FIELDS()
)
The function cvCreateGraph
creates an empty graph and returns pointer to it.
Adds vertex to graph
int cvGraphAddVtx( CvGraph* graph, const CvGraphVtx* vtx=NULL, CvGraphVtx** inserted_vtx=NULL );
sizeof(CvGraphVtx)
are copied).
NULL
, the address of the new
vertex is written there.
The function cvGraphAddVtx
adds a vertex to the graph and returns the vertex
index.
Removes vertex from graph
int cvGraphRemoveVtx( CvGraph* graph, int index );
The function cvGraphRemoveAddVtx
removes a vertex from the graph together with all
the edges incident to it. The function reports an error, if the input vertex does
not belong to the graph. The return value is number of edges deleted,
or -1 if the vertex does not belong to the graph.
Removes vertex from graph
int cvGraphRemoveVtxByPtr( CvGraph* graph, CvGraphVtx* vtx );
The function cvGraphRemoveVtxByPtr
removes a vertex from the graph together with
all the edges incident to it. The function reports an error, if the vertex does not belong to the graph.
The return value is number of edges deleted, or -1 if the vertex does not belong to the graph.
Finds graph vertex by index
CvGraphVtx* cvGetGraphVtx( CvGraph* graph, int vtx_idx );
The function cvGetGraphVtx
finds the graph vertex by index and returns the pointer
to it or NULL if the vertex does not belong to the graph.
Returns index of graph vertex
int cvGraphVtxIdx( CvGraph* graph, CvGraphVtx* vtx );
The function cvGraphVtxIdx
returns index of the graph vertex.
Adds edge to graph
int cvGraphAddEdge( CvGraph* graph, int start_idx, int end_idx, const CvGraphEdge* edge=NULL, CvGraphEdge** inserted_edge=NULL );
The function cvGraphAddEdge
connects two specified vertices.
The function returns 1 if the edge has been added successfully, 0 if the edge connecting
the two vertices exists already and -1 if either of the vertices was not found, the starting and
the ending vertex are the same or there is some other critical situation. In the latter case
(i.e. when the result is negative) the function also reports an error by default.
Adds edge to graph
int cvGraphAddEdgeByPtr( CvGraph* graph, CvGraphVtx* start_vtx, CvGraphVtx* end_vtx, const CvGraphEdge* edge=NULL, CvGraphEdge** inserted_edge=NULL );
The function cvGraphAddEdge
connects two specified vertices.
The function returns 1 if the edge has been added successfully, 0 if the edge connecting
the two vertices exists already and -1 if either of the vertices was not found, the starting and
the ending vertex are the same or there is some other critical situation. In the latter case
(i.e. when the result is negative) the function also reports an error by default.
Removes edge from graph
void cvGraphRemoveEdge( CvGraph* graph, int start_idx, int end_idx );
The function cvGraphRemoveEdge
removes the edge connecting two specified vertices.
If the vertices are not connected [in that order], the function does nothing.
Removes edge from graph
void cvGraphRemoveEdgeByPtr( CvGraph* graph, CvGraphVtx* start_vtx, CvGraphVtx* end_vtx );
The function cvGraphRemoveEdgeByPtr
removes the edge connecting two specified vertices.
If the vertices are not connected [in that order], the function does nothing.
Finds edge in graph
CvGraphEdge* cvFindGraphEdge( const CvGraph* graph, int start_idx, int end_idx ); #define cvGraphFindEdge cvFindGraphEdge
The function cvFindGraphEdge
finds the graph edge connecting two specified vertices
and returns pointer to it or NULL if the edge does not exists.
Finds edge in graph
CvGraphEdge* cvFindGraphEdgeByPtr( const CvGraph* graph, const CvGraphVtx* start_vtx, const CvGraphVtx* end_vtx ); #define cvGraphFindEdgeByPtr cvFindGraphEdgeByPtr
The function cvFindGraphEdge
finds the graph edge connecting two specified vertices
and returns pointer to it or NULL if the edge does not exists.
Returns index of graph edge
int cvGraphEdgeIdx( CvGraph* graph, CvGraphEdge* edge );
The function cvGraphEdgeIdx
returns index of the graph edge.
Counts edges indicent to the vertex
int cvGraphVtxDegree( const CvGraph* graph, int vtx_idx );
The function cvGraphVtxDegree
returns the number of edges
incident to the specified vertex, both incoming and outcoming.
To count the edges, the following code is used:
CvGraphEdge* edge = vertex->first; int count = 0; while( edge ) { edge = CV_NEXT_GRAPH_EDGE( edge, vertex ); count++; }
The macro CV_NEXT_GRAPH_EDGE( edge, vertex )
returns the edge incident to vertex
that follows after edge
.
Finds edge in graph
int cvGraphVtxDegreeByPtr( const CvGraph* graph, const CvGraphVtx* vtx );
The function cvGraphVtxDegree
returns the number of edges
incident to the specified vertex, both incoming and outcoming.
Clears graph
void cvClearGraph( CvGraph* graph );
The function cvClearGraph
removes all vertices and edges from the graph.
The function has O(1) time complexity.
Clone graph
CvGraph* cvCloneGraph( const CvGraph* graph, CvMemStorage* storage );
The function cvCloneGraph
creates full copy of the graph. If the graph vertices
or edges have pointers to some external data, it still be shared between the copies.
The vertex and edge indices in the new graph may be different from the original, because
the function defragments the vertex and edge sets.
Graph traversal state
typedef struct CvGraphScanner { CvGraphVtx* vtx; /* current graph vertex (or current edge origin) */ CvGraphVtx* dst; /* current graph edge destination vertex */ CvGraphEdge* edge; /* current edge */ CvGraph* graph; /* the graph */ CvSeq* stack; /* the graph vertex stack */ int index; /* the lower bound of certainly visited vertices */ int mask; /* event mask */ } CvGraphScanner;
The structure CvGraphScanner is used for depth-first graph traversal. See discussion of the functions below.
Creates structure for depth-first graph traversal
CvGraphScanner* cvCreateGraphScanner( CvGraph* graph, CvGraphVtx* vtx=NULL, int mask=CV_GRAPH_ALL_ITEMS );
CV_GRAPH_ALL_ITEMS
(all events are interesting)
or combination of the following flags:tree edge
is the edge connecting the last visited vertex and
the vertex to be visited next)back edge
is an edge connecting
the last visited vertex with some of its ancestors in the search tree)forward edge
is an edge conecting
the last visited vertex with some of its descendants in the search tree).
The forward edges
are only possible during oriented graph traversal)cross edge
is an edge connecting different search trees or
branches of the same tree.
The cross edges
are only possible during oriented graphs traversal)tree, back, forward
and cross edges
)cvNextGraphItem
is called for the first time)
it generates CV_GRAPH_NEW_TREE
event.
The function cvCreateGraphScanner
creates structure for
depth-first graph traversal/search.
The initialized structure is used in cvNextGraphItem function
- the incremental traversal procedure.
Makes one or more steps of the graph traversal procedure
int cvNextGraphItem( CvGraphScanner* scanner );
The function cvNextGraphItem
traverses through the graph until an event interesting to the user
(that is, an event, specified in the mask
in cvCreateGraphScanner call)
is met or the traversal is over. In the first case it returns one of the events,
listed in the description of mask
parameter above and with the next call
it resumes the traversal. In the latter case it returns CV_GRAPH_OVER (-1).
When the event is CV_GRAPH_VERTEX
, or CV_GRAPH_BACKTRACKING
or CV_GRAPH_NEW_TREE
,
the currently observed vertex is stored in scanner->vtx
. And if the event is edge-related,
the edge itself is stored at scanner->edge
,
the previously visited vertex - at scanner->vtx
and the other ending vertex of the edge -
at scanner->dst
.
Finishes graph traversal procedure
void cvReleaseGraphScanner( CvGraphScanner** scanner );
The function cvGraphScanner
finishes graph traversal procedure
and releases the traverser state.
Helper macro for a tree node type declaration
#define CV_TREE_NODE_FIELDS(node_type) \ int flags; /* micsellaneous flags */ \ int header_size; /* size of sequence header */ \ struct node_type* h_prev; /* previous sequence */ \ struct node_type* h_next; /* next sequence */ \ struct node_type* v_prev; /* 2nd previous sequence */ \ struct node_type* v_next; /* 2nd next sequence */
The macro CV_TREE_NODE_FIELDS()
is used to declare structures
that can be organized into hierarchical strucutures (trees), such as CvSeq -
the basic type for all dynamical structures.
The trees made of nodes declared using this macro can be processed using
the functions described below in this section.
Opens existing or creates new file storage
typedef struct CvTreeNodeIterator { const void* node; int level; int max_level; } CvTreeNodeIterator;
The structure CvTreeNodeIterator is used to traverse trees.
The tree node declaration should start with CV_TREE_NODE_FIELDS(...)
macro.
Initializes tree node iterator
void cvInitTreeNodeIterator( CvTreeNodeIterator* tree_iterator, const void* first, int max_level );
first
node assumed to be at the first level) to
traverse up to. For example, 1 means that only nodes at the same level as first
should be visited, 2 means that the nodes on the same level as first
and
their direct children should be visited etc.
The function cvInitTreeNodeIterator
initializes tree iterator.
The tree is traversed in depth-first order.
Returns the currently observed node and moves iterator toward the next node
void* cvNextTreeNode( CvTreeNodeIterator* tree_iterator );
The function cvNextTreeNode
returns the currently observed node and then
updates the iterator - moves it toward the next node. In other words, the function behavior
is similar to *p++ expression on usual C pointer or C++ collection iterator.
The function returns NULL if there is no more nodes.
Returns the currently observed node and moves iterator toward the previous node
void* cvPrevTreeNode( CvTreeNodeIterator* tree_iterator );
The function cvPrevTreeNode
returns the currently observed node and then
updates the iterator - moves it toward the previous node. In other words, the function behavior
is similar to *p-- expression on usual C pointer or C++ collection iterator.
The function returns NULL if there is no more nodes.
Gathers all node pointers to the single sequence
CvSeq* cvTreeToNodeSeq( const void* first, int header_size, CvMemStorage* storage );
The function cvTreeToNodeSeq
puts pointers of all nodes reacheable from first
to the single sequence. The pointers are written subsequently in the depth-first order.
Adds new node to the tree
void cvInsertNodeIntoTree( void* node, void* parent, void* frame );
parent
and frame
are the same, v_prev
field of node
is set to NULL rather than parent
.
The function cvInsertNodeIntoTree
adds another node into tree. The function does not
allocate any memory, it can only modify links of the tree nodes.
Removes node from tree
void cvRemoveNodeFromTree( void* node, void* frame );
node->v_prev = NULL
and
node->h_prev
is NULL (i.e. if node
is the first child of frame
),
frame->v_next
is set to node->h_next
(i.e. the first child or frame is changed).
The function cvRemoveNodeFromTree
removes node from tree. The function does not
deallocate any memory, it can only modify links of the tree nodes.
Drawing functions work with matrices/images or arbitrary depth.
Antialiasing is implemented only for 8-bit images.
All the functions include parameter color that means rgb value (that may be
constructed with CV_RGB
macro or cvScalar
function)
for color images and brightness for grayscale images.
If a drawn figure is partially or completely outside the image, it is clipped.
For color images the order channel is: Blue Green Red ...
If one needs a different channel order, it is possible to construct color
via cvScalar
with the particular channel order, or
convert the image before and/or after drawing in it with
cvCvtColor or
cvTransform.
Constructs a color value
#define CV_RGB( r, g, b ) cvScalar( (b), (g), (r) )
Draws a line segment connecting two points
void cvLine( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness=1, int line_type=8, int shift=0 );
8
(or 0
) - 8-connected line.4
- 4-connected line.CV_AA
- antialiased line.
The function cvLine
draws the line segment between pt1
and pt2
points
in the image. The line is clipped by the image or ROI rectangle. For non-antialiased lines
with integer coordinates the 8-connected or 4-connected Bresenham algorithm is used.
Thick lines are drawn with rounding endings. Antialiased lines are drawn using Gaussian filtering.
To specify the line color, the user may use the macro CV_RGB( r, g, b )
.
Draws simple, thick or filled rectangle
void cvRectangle( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color, int thickness=1, int line_type=8, int shift=0 );
The function cvRectangle
draws a rectangle with
two opposite corners pt1
and pt2
.
Draws a circle
void cvCircle( CvArr* img, CvPoint center, int radius, CvScalar color, int thickness=1, int line_type=8, int shift=0 );
The function cvCircle
draws a simple or filled circle with given center and
radius. The circle is clipped by ROI rectangle. To specify the circle color, the user may
use the macro CV_RGB ( r, g, b )
.
Draws simple or thick elliptic arc or fills ellipse sector
void cvEllipse( CvArr* img, CvPoint center, CvSize axes, double angle, double start_angle, double end_angle, CvScalar color, int thickness=1, int line_type=8, int shift=0 );
The function cvEllipse
draws a simple or thick elliptic arc or fills an ellipse
sector. The arc is clipped by ROI rectangle. A piecewise-linear
approximation is used for antialiased arcs and thick arcs. All the angles are
given in degrees. The picture below explains the meaning of the parameters.
Parameters of Elliptic Arc
Draws simple or thick elliptic arc or fills ellipse sector
void cvEllipseBox( CvArr* img, CvBox2D box, CvScalar color, int thickness=1, int line_type=8, int shift=0 );
The function cvEllipseBox
draws a simple or thick ellipse outline,
or fills an ellipse. The functions provides a convenient way to draw an ellipse
approximating some shape; that is what cvCamShift
and cvFitEllipse do.
The ellipse drawn is clipped by ROI rectangle. A piecewise-linear
approximation is used for antialiased arcs and thick arcs.
Fills polygons interior
void cvFillPoly( CvArr* img, CvPoint** pts, int* npts, int contours, CvScalar color, int line_type=8, int shift=0 );
The function cvFillPoly
fills an area bounded by several polygonal contours.
The function fills complex areas, for example, areas with holes, contour self-intersection, etc.
Fills convex polygon
void cvFillConvexPoly( CvArr* img, CvPoint* pts, int npts, CvScalar color, int line_type=8, int shift=0 );
The function cvFillConvexPoly
fills convex polygon interior.
This function is much faster than The function cvFillPoly
and can fill
not only the convex polygons but any monotonic polygon, i.e. a polygon whose contour intersects every
horizontal line (scan line) twice at the most.
Draws simple or thick polygons
void cvPolyLine( CvArr* img, CvPoint** pts, int* npts, int contours, int is_closed, CvScalar color, int thickness=1, int line_type=8, int shift=0 );
The function cvPolyLine
draws a single or multiple polygonal curves.
Initializes font structure
void cvInitFont( CvFont* font, int font_face, double hscale, double vscale, double shear=0, int thickness=1, int line_type=8 );
CV_FONT_HERSHEY_SIMPLEX
- normal size sans-serif fontCV_FONT_HERSHEY_PLAIN
- small size sans-serif fontCV_FONT_HERSHEY_DUPLEX
- normal size sans-serif font (more complex than CV_FONT_HERSHEY_SIMPLEX
)CV_FONT_HERSHEY_COMPLEX
- normal size serif fontCV_FONT_HERSHEY_TRIPLEX
- normal size serif font (more complex than CV_FONT_HERSHEY_COMPLEX
)CV_FONT_HERSHEY_COMPLEX_SMALL
- smaller version of CV_FONT_HERSHEY_COMPLEX
CV_FONT_HERSHEY_SCRIPT_SIMPLEX
- hand-writing style fontCV_FONT_HERSHEY_SCRIPT_COMPLEX
- more complex variant of CV_FONT_HERSHEY_SCRIPT_SIMPLEX
CV_FONT_ITALIC
flag,
that means italic or oblique font.
1.0f
, the characters have the original
width depending on the font type. If equal to 0.5f
, the characters are of half
the original width.
1.0f
, the characters have the original
height depending on the font type. If equal to 0.5f
, the characters are of half
the original height.
1.0f
means ≈45°
slope, etc.
thickness Thickness of lines composing letters outlines. The function cvLine
is
used for drawing letters.
The function cvInitFont
initializes the font structure that can be passed to
text rendering functions.
Draws text string
void cvPutText( CvArr* img, const char* text, CvPoint org, const CvFont* font, CvScalar color );
The function cvPutText
renders the text in the image with the specified font and
color. The printed text is clipped by ROI rectangle. Symbols that do not belong
to the specified font are replaced with the rectangle symbol.
Retrieves width and height of text string
void cvGetTextSize( const char* text_string, const CvFont* font, CvSize* text_size, int* baseline );
The function cvGetTextSize
calculates the binding rectangle for the given text
string when a specified font is used.
Draws contour outlines or interiors in the image
void cvDrawContours( CvArr *img, CvSeq* contour, CvScalar external_color, CvScalar hole_color, int max_level, int thickness=1, int line_type=8, CvPoint offset=cvPoint(0,0) );
contour
is drawn. If
1, the contour and all contours after it on the same level are drawn. If 2, all
contours after and all contours one level below the contours are drawn, etc.
If the value is negative, the function does not draw the contours following after contour
but draws child contours of contour
up to abs(max_level
)-1 level.
The function cvDrawContours
draws contour outlines in the image if thickness
>=0
or fills area bounded by the contours if thickness
<0.
#include "cv.h" #include "highgui.h" int main( int argc, char** argv ) { IplImage* src; // the first command line parameter must be file name of binary (black-n-white) image if( argc == 2 && (src=cvLoadImage(argv[1], 0))!= 0) { IplImage* dst = cvCreateImage( cvGetSize(src), 8, 3 ); CvMemStorage* storage = cvCreateMemStorage(0); CvSeq* contour = 0; cvThreshold( src, src, 1, 255, CV_THRESH_BINARY ); cvNamedWindow( "Source", 1 ); cvShowImage( "Source", src ); cvFindContours( src, storage, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE ); cvZero( dst ); for( ; contour != 0; contour = contour->h_next ) { CvScalar color = CV_RGB( rand()&255, rand()&255, rand()&255 ); /* replace CV_FILLED with 1 to see the outlines */ cvDrawContours( dst, contour, color, color, -1, CV_FILLED, 8 ); } cvNamedWindow( "Components", 1 ); cvShowImage( "Components", dst ); cvWaitKey(0); } }
Replace CV_FILLED with 1 in the sample below to see the contour outlines
Initializes line iterator
int cvInitLineIterator( const CvArr* image, CvPoint pt1, CvPoint pt2, CvLineIterator* line_iterator, int connectivity=8, int left_to_right=0 );
pt1
and pt2
(left_to_right≠0
),
or it is scanned in the specified order, from pt1
to pt2
(left_to_right=0
).
The function cvInitLineIterator
initializes the line iterator and returns the
number of pixels between two end points. Both points must be inside the image.
After the iterator has been initialized, all the points on the raster line that
connects the two ending points may be retrieved by successive calls of
CV_NEXT_LINE_POINT
point. The points on the line are calculated one by one using
4-connected or 8-connected Bresenham algorithm.
CvScalar sum_line_pixels( IplImage* image, CvPoint pt1, CvPoint pt2 ) { CvLineIterator iterator; int blue_sum = 0, green_sum = 0, red_sum = 0; int count = cvInitLineIterator( image, pt1, pt2, &iterator, 8, 0 ); for( int i = 0; i < count; i++ ){ blue_sum += iterator.ptr[0]; green_sum += iterator.ptr[1]; red_sum += iterator.ptr[2]; CV_NEXT_LINE_POINT(iterator); /* print the pixel coordinates: demonstrates how to calculate the coordinates */ { int offset, x, y; /* assume that ROI is not set, otherwise need to take it into account. */ offset = iterator.ptr - (uchar*)(image->imageData); y = offset/image->widthStep; x = (offset - y*image->widthStep)/(3*sizeof(uchar) /* size of pixel */); printf("(%d,%d)\n", x, y ); } } return cvScalar( blue_sum, green_sum, red_sum ); }
Clips the line against the image rectangle
int cvClipLine( CvSize img_size, CvPoint* pt1, CvPoint* pt2 );
The function cvClipLine
calculates a part of the line segment which is entirely in the image.
It returns 0 if the line segment is completely outside the image and 1 otherwise.
Approximates elliptic arc with polyline
int cvEllipse2Poly( CvPoint center, CvSize axes, int angle, int arc_start, int arc_end, CvPoint* pts, int delta );
The function cvEllipse2Poly
computes vertices of the polyline that approximates the specified elliptic arc.
It is used by cvEllipse.
File Storage
typedef struct CvFileStorage { ... // hidden fields } CvFileStorage;
The structure CvFileStorage is "black box" representation of
file storage that is associated with a file on disk. Several functions that are described below
take CvFileStorage
on input and allow user to save or to load hierarchical collections
that consist of scalar values, standard CXCore objects (such as matrices, sequences, graphs) and
user-defined objects.
CXCore can read and write data in XML (http://www.w3c.org/XML)
or YAML (http://www.yaml.org) formats. Below is the example of
3×3 floating-point identity matrix A
, stored in XML and YAML files using CXCore functions:
<?xml version="1.0"> <opencv_storage> <A type_id="opencv-matrix"> <rows>3</rows> <cols>3</cols> <dt>f</dt> <data>1. 0. 0. 0. 1. 0. 0. 0. 1.</data> </A> </opencv_storage>
%YAML:1.0 A: !!opencv-matrix rows: 3 cols: 3 dt: f data: [ 1., 0., 0., 0., 1., 0., 0., 0., 1.]
As it can be seen from the examples, XML uses nested tags to represent hierarchy, while YAML uses indentation for that purpose (similarly to Python programming language).
The same CXCore functions can read and write data in both formats, the particular format is determined by the extension of the opened file, .xml for XML files and .yml or .yaml for YAML.
File Storage Node
/* file node type */ #define CV_NODE_NONE 0 #define CV_NODE_INT 1 #define CV_NODE_INTEGER CV_NODE_INT #define CV_NODE_REAL 2 #define CV_NODE_FLOAT CV_NODE_REAL #define CV_NODE_STR 3 #define CV_NODE_STRING CV_NODE_STR #define CV_NODE_REF 4 /* not used */ #define CV_NODE_SEQ 5 #define CV_NODE_MAP 6 #define CV_NODE_TYPE_MASK 7 /* optional flags */ #define CV_NODE_USER 16 #define CV_NODE_EMPTY 32 #define CV_NODE_NAMED 64 #define CV_NODE_TYPE(tag) ((tag) & CV_NODE_TYPE_MASK) #define CV_NODE_IS_INT(tag) (CV_NODE_TYPE(tag) == CV_NODE_INT) #define CV_NODE_IS_REAL(tag) (CV_NODE_TYPE(tag) == CV_NODE_REAL) #define CV_NODE_IS_STRING(tag) (CV_NODE_TYPE(tag) == CV_NODE_STRING) #define CV_NODE_IS_SEQ(tag) (CV_NODE_TYPE(tag) == CV_NODE_SEQ) #define CV_NODE_IS_MAP(tag) (CV_NODE_TYPE(tag) == CV_NODE_MAP) #define CV_NODE_IS_COLLECTION(tag) (CV_NODE_TYPE(tag) >= CV_NODE_SEQ) #define CV_NODE_IS_FLOW(tag) (((tag) & CV_NODE_FLOW) != 0) #define CV_NODE_IS_EMPTY(tag) (((tag) & CV_NODE_EMPTY) != 0) #define CV_NODE_IS_USER(tag) (((tag) & CV_NODE_USER) != 0) #define CV_NODE_HAS_NAME(tag) (((tag) & CV_NODE_NAMED) != 0) #define CV_NODE_SEQ_SIMPLE 256 #define CV_NODE_SEQ_IS_SIMPLE(seq) (((seq)->flags & CV_NODE_SEQ_SIMPLE) != 0) typedef struct CvString { int len; char* ptr; } CvString; /* all the keys (names) of elements in the readed file storage are stored in the hash to speed up the lookup operations */ typedef struct CvStringHashNode { unsigned hashval; CvString str; struct CvStringHashNode* next; } CvStringHashNode; /* basic element of the file storage - scalar or collection */ typedef struct CvFileNode { int tag; struct CvTypeInfo* info; /* type information (only for user-defined object, for others it is 0) */ union { double f; /* scalar floating-point number */ int i; /* scalar integer number */ CvString str; /* text string */ CvSeq* seq; /* sequence (ordered collection of file nodes) */ struct CvMap* map; /* map (collection of named file nodes) */ } data; } CvFileNode;
The structure is used only for retrieving data from file storage (i.e. for loading data from file). When data is written to file, it is done sequentially, with minimal buffering. No data is stored in the file storage.
In opposite, when data is read from file, the whole file is parsed and represented in memory
as a tree. Every node of the tree is represented by CvFileNode. Type of the file node
N
can be retrieved as CV_NODE_TYPE(N->tag)
. Some file nodes (leaves) are scalars:
text strings, integer or floating-point numbers. Other file nodes are collections of file nodes, which can
be scalars or collections in their turn. There are two types of collections: sequences and maps
(we use YAML notation, however, the same is true for XML streams). Sequences (do not mix them with
CvSeq) are ordered collections of unnamed file nodes,
maps are unordered collections of named file nodes. Thus, elements of sequences are
accessed by index (cvGetSeqElem),
while elements of maps are accessed by name
(cvGetFileNodeByName).
The table below describes the different types of a file node:
Type | CV_NODE_TYPE(node->tag) | Value |
Integer | CV_NODE_INT | node->data.i |
Floating-point | CV_NODE_REAL | node->data.f |
Text string | CV_NODE_STR | node->data.str.ptr |
Sequence | CV_NODE_SEQ | node->data.seq |
Map | CV_NODE_MAP | node->data.map* |
map
field directly (BTW, CvMap
is a hidden structure).
The elements of the map can be retrieved with cvGetFileNodeByName
function that takes pointer to the "map" file node.
A user (custom) object is instance of either one of standard CxCore types, such as CvMat, CvSeq etc., or any type registered with cvRegisterTypeInfo. Such an object is initially represented in file as a map (as shown in XML and YAML sample files above), after file storage has been opened and parsed. Then the object can be decoded (coverted to the native representation) by request - when user calls cvRead or cvReadByName function.
List of attributes
typedef struct CvAttrList { const char** attr; /* NULL-terminated array of (attribute_name,attribute_value) pairs */ struct CvAttrList* next; /* pointer to next chunk of the attributes list */ } CvAttrList; /* initializes CvAttrList structure */ inline CvAttrList cvAttrList( const char** attr=NULL, CvAttrList* next=NULL ); /* returns attribute value or 0 (NULL) if there is no such attribute */ const char* cvAttrValue( const CvAttrList* attr, const char* attr_name );
In the current implementation attributes are used to pass extra parameters when writing user objects
(see cvWrite).
XML attributes inside tags are not supported, besides the object type specification
(type_id
attribute).
Opens file storage for reading or writing data
CvFileStorage* cvOpenFileStorage( const char* filename, CvMemStorage* memstorage, int flags );
CV_STORAGE_READ
- the storage is open for readingCV_STORAGE_WRITE
- the storage is open for writing
The function cvOpenFileStorage
opens file storage for
reading or writing data. In the latter case a new file is created or existing file is
rewritten. Type of the read of written file is determined by the filename extension: .xml
for XML, and .yml
or .yaml
for YAML.
The function returns pointer to CvFileStorage structure.
Releases file storage
void cvReleaseFileStorage( CvFileStorage** fs );
The function cvReleaseFileStorage
closes the file
associated with the storage and releases all the temporary structures.
It must be called after all I/O operations with the storage are finished.
Starts writing a new structure
void cvStartWriteStruct( CvFileStorage* fs, const char* name, int struct_flags, const char* type_name=NULL, CvAttrList attributes=cvAttrList());
CV_NODE_SEQ
- the written structure is a sequence (see discussion of
CvFileStorage), that is,
its elements do not have a name. CV_NODE_MAP
- the written structure is a map (see discussion of
CvFileStorage), that is,
all its elements have names. CV_NODE_FLOW
- the optional flag that has sense only for YAML streams.
It means that the structure is written as a flow (not as a block), which is more
compact. It is recommended to use this flag for structures or arrays whose elements are
all scalars.
type_id
attribute of the structure opening tag. In case of YAML
it is written after a colon following the structure name (see the example in
CvFileStorage description).
Mainly it comes with user objects.
When the storage is read, the encoded type name is used to determine
the object type (see CvTypeInfo and
cvFindTypeInfo).
The function cvStartWriteStruct
starts writing
a compound structure (collection) that can be a sequence or a map. After all the structure
fields, which can be scalars or structures, are written,
cvEndWriteStruct should be called.
The function can be used to group some objects or to implement write function for a
some user object (see CvTypeInfo).
Ends writing a structure
void cvEndWriteStruct( CvFileStorage* fs );
The function cvEndWriteStruct
finishes the
currently written structure.
Writes an integer value
void cvWriteInt( CvFileStorage* fs, const char* name, int value );
The function cvWriteInt
writes a single integer value
(with or without a name) to the file storage.
Writes a floating-point value
void cvWriteReal( CvFileStorage* fs, const char* name, double value );
The function cvWriteReal
writes a single
floating-point value (with or without a name) to the file storage. The special
values are encoded: NaN (Not A Number) as .NaN, ±Infinity as +.Inf (-.Inf).
The following example shows how to use the low-level writing functions to store custom structures, such as termination criteria, without registering a new type.
void write_termcriteria( CvFileStorage* fs, const char* struct_name, CvTermCriteria* termcrit ) { cvStartWriteStruct( fs, struct_name, CV_NODE_MAP, NULL, cvAttrList(0,0)); cvWriteComment( fs, "termination criteria", 1 ); // just a description if( termcrit->type & CV_TERMCRIT_ITER ) cvWriteInteger( fs, "max_iterations", termcrit->max_iter ); if( termcrit->type & CV_TERMCRIT_EPS ) cvWriteReal( fs, "accuracy", termcrit->epsilon ); cvEndWriteStruct( fs ); }
Writes a text string
void cvWriteString( CvFileStorage* fs, const char* name, const char* str, int quote=0 );
The function cvWriteString
writes a text string
to the file storage.
Writes comment
void cvWriteComment( CvFileStorage* fs, const char* comment, int eol_comment );
The function cvWriteComment
writes a comment into the
file storage. The comments are skipped when the storage is read, so they may be
used only for debugging or descriptive purposes.
Starts the next stream
void cvStartNextStream( CvFileStorage* fs );
The function cvStartNextStream
starts the next
stream in the file storage. Both YAML and XML supports multiple "streams". This
is useful for concatenating files or for resuming the writing process.
Writes user object
void cvWrite( CvFileStorage* fs, const char* name, const void* ptr, CvAttrList attributes=cvAttrList() );
The function cvWrite
writes the object to file storage.
First, the appropriate type info is found using cvTypeOf.
Then, write
method of the type info is called.
Attributes are used to customize the writing procedure.
The standard types support the following attributes
(all the *dt
attributes have the same format as in
cvWriteRawData):
header_dt
- description
of user fields of the sequence header that follow CvSeq, or CvChain
(if the sequence is Freeman chain) or CvContour (if the sequence is a contour
or point sequence)
dt
- description of the sequence elements.
recursive
- if the attribute is present and is not equal to "0" or "false",
the whole tree of sequences (contours) is stored.
CvGraph
header_dt
- description of user fields
of the graph header that follow CvGraph;
vertex_dt
- description of
user fields of graph vertices
edge_dt
- description of user fields of graph edges (note, that
edge weight is always written, so there is no need to specify it explicitly)
Below is the code that creates the YAML file shown in CvFileStorage
description:
#include "cxcore.h" int main( int argc, char** argv ) { CvMat* mat = cvCreateMat( 3, 3, CV_32F ); CvFileStorage* fs = cvOpenFileStorage( "example.yml", 0, CV_STORAGE_WRITE ); cvSetIdentity( mat ); cvWrite( fs, "A", mat, cvAttrList(0,0) ); cvReleaseFileStorage( &fs ); cvReleaseMat( &mat ); return 0; }
Writes multiple numbers
void cvWriteRawData( CvFileStorage* fs, const void* src, int len, const char* dt );
([count]{'u'|'c'|'w'|'s'|'i'|'f'|'d'})...
, where the characters
correspond to fundamental C types:
count
is the optional counter of values of the certain type.
For example, dt='2if'
means that each array element is a structure
of 2 integers, followed by a single-precision floating-point number. The equivalent
notations of the above specification are 'iif'
, '2i1f'
etc.
Other examples: dt='u'
means that the array consists of bytes,
dt='2d'
- the array consists of pairs of double’s.
The function cvWriteRawData
writes array,
which elements consist of a single of multiple numbers. The function call can
be replaced with a loop containing a few cvWriteInt
and cvWriteReal calls,
but a single call is more efficient. Note, that because none of the elements
have a name, they should be written to a sequence rather than a map.
Writes file node to another file storage
void cvWriteFileNode( CvFileStorage* fs, const char* new_node_name, const CvFileNode* node, int embed );
cvGetFileNodeName(node)
.
node
are
written into the currently written structure. Of course, map elements may be
written only to map, and sequence elements may be written only to sequence.
The function cvWriteFileNode
writes a copy of file node to file storage. The possible application of the function are:
merging several file storages into one. Conversion between XML and YAML formats etc.
Data are retrieved from file storage in 2 steps:
first, the file node containing the requested data is found;
then, data is extracted from the node manually or using custom read
method.
Retrieves one of top-level nodes of the file storage
CvFileNode* cvGetRootFileNode( const CvFileStorage* fs, int stream_index=0 );
The function cvGetRootFileNode
returns
one of top-level file nodes. The top-level nodes do not have a name, they correspond to
the streams, that are stored one after another in the file storage.
If the index is out of range, the function returns NULL pointer, so all the top-level
nodes may be iterated by subsequent calls to the function with stream_index=0,1,...
,
until NULL pointer is returned. This function may be used as a base for recursive traversal of the
file storage.
Finds node in the map or file storage
CvFileNode* cvGetFileNodeByName( const CvFileStorage* fs, const CvFileNode* map, const char* name );
The function cvGetFileNodeByName
finds
a file node by name
. The node is searched either in map
or, if the pointer is NULL, among the top-level file nodes of the storage.
Using this function for maps and cvGetSeqElem
(or sequence reader) for sequences, it is possible to nagivate through the file storage.
To speed up multiple queries for a certain key (e.g. in case of array of structures)
one may use a pair of cvGetHashedKey and
cvGetFileNode.
Returns a unique pointer for given name
CvStringHashNode* cvGetHashedKey( CvFileStorage* fs, const char* name, int len=-1, int create_missing=0 );
The function cvGetHashedKey
returns
the unique pointer for each particular file node name. This pointer can be
then passed to cvGetFileNode function that
is faster than cvGetFileNodeByName
because it compares text strings by comparing pointers rather than the
strings' content.
Consider the following example: an array of points is encoded as a sequence of 2-entry maps, e.g.:
%YAML:1.0 points: - { x: 10, y: 10 } - { x: 20, y: 20 } - { x: 30, y: 30 } # ...Then, it is possible to get hashed "x" and "y" pointers to speed up decoding of the points.
#include "cxcore.h" int main( int argc, char** argv ) { CvFileStorage* fs = cvOpenFileStorage( "points.yml", 0, CV_STORAGE_READ ); CvStringHashNode* x_key = cvGetHashedNode( fs, "x", -1, 1 ); CvStringHashNode* y_key = cvGetHashedNode( fs, "y", -1, 1 ); CvFileNode* points = cvGetFileNodeByName( fs, 0, "points" ); if( CV_NODE_IS_SEQ(points->tag) ) { CvSeq* seq = points->data.seq; int i, total = seq->total; CvSeqReader reader; cvStartReadSeq( seq, &reader, 0 ); for( i = 0; i < total; i++ ) { CvFileNode* pt = (CvFileNode*)reader.ptr; #if 1 /* faster variant */ CvFileNode* xnode = cvGetFileNode( fs, pt, x_key, 0 ); CvFileNode* ynode = cvGetFileNode( fs, pt, y_key, 0 ); assert( xnode && CV_NODE_IS_INT(xnode->tag) && ynode && CV_NODE_IS_INT(ynode->tag)); int x = xnode->data.i; // or x = cvReadInt( xnode, 0 ); int y = ynode->data.i; // or y = cvReadInt( ynode, 0 ); #elif 1 /* slower variant; does not use x_key & y_key */ CvFileNode* xnode = cvGetFileNodeByName( fs, pt, "x" ); CvFileNode* ynode = cvGetFileNodeByName( fs, pt, "y" ); assert( xnode && CV_NODE_IS_INT(xnode->tag) && ynode && CV_NODE_IS_INT(ynode->tag)); int x = xnode->data.i; // or x = cvReadInt( xnode, 0 ); int y = ynode->data.i; // or y = cvReadInt( ynode, 0 ); #else /* the slowest yet the easiest to use variant */ int x = cvReadIntByName( fs, pt, "x", 0 /* default value */ ); int y = cvReadIntByName( fs, pt, "y", 0 /* default value */ ); #endif CV_NEXT_SEQ_ELEM( seq->elem_size, reader ); printf("%d: (%d, %d)\n", i, x, y ); } } cvReleaseFileStorage( &fs ); return 0; }
Please note that, whatever method of accessing map you are using, it is still much slower than using plain sequences, for example, in the above sample, it is more efficient to encode the points as pairs of integers in the single numeric sequence.
Finds node in the map or file storage
CvFileNode* cvGetFileNode( CvFileStorage* fs, CvFileNode* map, const CvStringHashNode* key, int create_missing=0 );
map
and key
are NULLs,
the function returns the root file node - a map
that contains top-level nodes.
The function cvGetFileNode
finds a file node. It is
a faster version cvGetFileNodeByName
(see cvGetHashedKey discussion). Also,
the function can insert a new node, if it is not in the map yet (which is used
by parsing functions).
Returns name of file node
const char* cvGetFileNodeName( const CvFileNode* node );
The function cvGetFileNodeName
returns name of the file node
or NULL, if the file node does not have a name, or if node
is NULL
.
Retrieves integer value from file node
int cvReadInt( const CvFileNode* node, int default_value=0 );
node
is NULL.
The function cvReadInt
returns integer that is
represented by the file node. If the file node is NULL, default_value
is returned (thus, it is convenient to call the function right after
cvGetFileNode without checking for NULL pointer),
otherwise if the file node has type CV_NODE_INT
,
then node->data.i
is returned, otherwise if the file node has
type CV_NODE_REAL
, then node->data.f
is converted to integer and returned, otherwise the result is not determined.
Finds file node and returns its value
int cvReadIntByName( const CvFileStorage* fs, const CvFileNode* map, const char* name, int default_value=0 );
The function cvReadIntByName
is a simple
superposition of cvGetFileNodeByName and
cvReadInt.
Retrieves floating-point value from file node
double cvReadReal( const CvFileNode* node, double default_value=0. );
node
is NULL.
The function cvReadReal
returns floating-point value that is
represented by the file node. If the file node is NULL, default_value
is returned (thus, it is convenient to call the function right after
cvGetFileNode without checking for NULL pointer),
otherwise if the file node has type CV_NODE_REAL
,
then node->data.f
is returned, otherwise if the file node has
type CV_NODE_INT
, then node->data.f
is converted to floating-point and returned, otherwise the result is not determined.
Finds file node and returns its value
double cvReadRealByName( const CvFileStorage* fs, const CvFileNode* map, const char* name, double default_value=0. );
The function cvReadRealByName
is a simple
superposition of cvGetFileNodeByName and
cvReadReal.
Retrieves text string from file node
const char* cvReadString( const CvFileNode* node, const char* default_value=NULL );
node
is NULL.
The function cvReadString
returns text string that is
represented by the file node. If the file node is NULL, default_value
is returned (thus, it is convenient to call the function right after
cvGetFileNode without checking for NULL pointer),
otherwise if the file node has type CV_NODE_STR
,
then node->data.str.ptr
is returned, otherwise the result is not determined.
Finds file node and returns its value
const char* cvReadStringByName( const CvFileStorage* fs, const CvFileNode* map, const char* name, const char* default_value=NULL );
The function cvReadStringByName
is a simple
superposition of cvGetFileNodeByName and
cvReadString.
Decodes object and returns pointer to it
void* cvRead( CvFileStorage* fs, CvFileNode* node, CvAttrList* attributes=NULL );
The function cvRead
decodes user object (creates object
in a native representation from the file storage subtree) and returns it.
The object to be decoded must be an instance of registered type that supports read
method (see CvTypeInfo). Type of the object is determined by
the type name that is encoded in the file. If the object is dynamic structure, it is
created either in memory storage, passed to cvOpenFileStorage
or, if NULL pointer was passed, in temporary memory storage, which is release when
cvReleaseFileStorage is called.
Otherwise, if the object is not a dynamic structure, it is created in heap and should be
released with a specialized function or using generic cvRelease.
Finds object and decodes it
void* cvReadByName( CvFileStorage* fs, const CvFileNode* map, const char* name, CvAttrList* attributes=NULL );
The function cvReadByName
is a simple
superposition of cvGetFileNodeByName and
cvRead.
Reads multiple numbers
void cvReadRawData( const CvFileStorage* fs, const CvFileNode* src, void* dst, const char* dt );
The function cvReadRawData
reads elements
from a file node that represents a sequence of scalars
Initializes file node sequence reader
void cvStartReadRawData( const CvFileStorage* fs, const CvFileNode* src, CvSeqReader* reader );
The function cvStartReadRawData
initializes
sequence reader to read data from file node. The initialized reader can be then
passed to cvReadRawDataSlice.
Initializes file node sequence reader
void cvReadRawDataSlice( const CvFileStorage* fs, CvSeqReader* reader, int count, void* dst, const char* dt );
The function cvReadRawDataSlice
reads one
or more elements from the file node, representing a sequence, to user-specified
array. The total number of read sequence elements is a product of total
and the number of components in each array element.
For example, if dt='2if'
, the function will read total*3
sequence elements.
As with any sequence, some parts of the file node sequence may be skipped or read repeatedly
by repositioning the reader using cvSetSeqReaderPos.
Type information
typedef int (CV_CDECL *CvIsInstanceFunc)( const void* struct_ptr ); typedef void (CV_CDECL *CvReleaseFunc)( void** struct_dblptr ); typedef void* (CV_CDECL *CvReadFunc)( CvFileStorage* storage, CvFileNode* node ); typedef void (CV_CDECL *CvWriteFunc)( CvFileStorage* storage, const char* name, const void* struct_ptr, CvAttrList attributes ); typedef void* (CV_CDECL *CvCloneFunc)( const void* struct_ptr ); typedef struct CvTypeInfo { int flags; /* not used */ int header_size; /* sizeof(CvTypeInfo) */ struct CvTypeInfo* prev; /* previous registered type in the list */ struct CvTypeInfo* next; /* next registered type in the list */ const char* type_name; /* type name, written to file storage */ /* methods */ CvIsInstanceFunc is_instance; /* checks if the passed object belongs to the type */ CvReleaseFunc release; /* releases object (memory etc.) */ CvReadFunc read; /* reads object from file storage */ CvWriteFunc write; /* writes object to file storage */ CvCloneFunc clone; /* creates a copy of the object */ } CvTypeInfo;
The structure CvTypeInfo contains information about one of standard or user-defined types. Instances of the type may or may not contain pointer to the corresponding CvTypeInfo structure. In any case there is a way to find type info structure for given object - using cvTypeOf function. Aternatively, type info can be found by the type name using cvFindType, which is used when object is read from file storage. User can register a new type with cvRegisterType that adds the type information structure into the beginning of the type list - thus, it is possible to create specialized types from generic standard types and override the basic methods.
Registers new type
void cvRegisterType( const CvTypeInfo* info );
The function cvRegisterType
registers a new type,
which is described by info
. The function creates a copy of the structure,
so user should delete it after calling the function.
Unregisters the type
void cvUnregisterType( const char* type_name );
The function cvUnregisterType
unregisters the type
with the specified name. If the name is unknown, it is possible to locate the type info
by an instance of the type using cvTypeOf or by iterating
the type list, starting from cvFirstType, and then
call cvUnregisterType(info->type_name)
.
Returns the beginning of type list
CvTypeInfo* cvFirstType( void );
The function cvFirstType
returns the first type of the list
of registered types. Navigation through the list can be done via prev
and next
fields of CvTypeInfo structure.
Finds type by its name
CvTypeInfo* cvFindType( const char* type_name );
The function cvFindType
finds a registered type by its name.
It returns NULL, if there is no type with the specified name.
Returns type of the object
CvTypeInfo* cvTypeOf( const void* struct_ptr );
The function cvTypeOf
finds the type of given object. It iterates through the list
of registered types and calls is_instance
function/method of every type info structure with
the object until one of them return non-zero or until the whole list has been traversed. In the latter
case the function returns NULL.
Releases the object
void cvRelease( void** struct_ptr );
The function cvRelease
finds the type of given object and calls
release
with the double pointer.
Makes a clone of the object
void* cvClone( const void* struct_ptr );
The function cvClone
finds the type of given object and calls
clone
with the passed object.
Saves object to file
void cvSave( const char* filename, const void* struct_ptr, const char* name=NULL, const char* comment=NULL, CvAttrList attributes=cvAttrList());
filename
.
The function cvSave
saves object to file. It provides a simple interface
to cvWrite.
Loads object from file
void* cvLoad( const char* filename, CvMemStorage* memstorage=NULL, const char* name=NULL, const char** real_name=NULL );
name=NULL
).
The function cvLoad
loads object from file.
It provides a simple interface to cvRead.
After object is loaded,
the file storage is closed and all the temporary buffers are deleted. Thus, to load a dynamic structure,
such as sequence, contour or graph, one should pass a valid destination
memory storage to the function.
Checks every element of input array for invalid values
int cvCheckArr( const CvArr* arr, int flags=0, double min_val=0, double max_val=0); #define cvCheckArray cvCheckArr
CV_CHECK_RANGE
- if set, the function checks that every value of
array is within [minVal,maxVal) range,
otherwise it just checks that every element
is neigther NaN nor ±Infinity.CV_CHECK_QUIET
- if set, the function does not raises an
error if an element is invalid or out of range
CV_CHECK_RANGE
is set.
CV_CHECK_RANGE
is set.
The function cvCheckArr
checks that every array element
is neither NaN nor ±Infinity.
If CV_CHECK_RANGE
is set, it also checks that every element is
greater than or equal to minVal
and less than maxVal
.
The function returns nonzero if the check succeeded, i.e. all elements
are valid and within the range, and zero otherwise.
In the latter case if CV_CHECK_QUIET
flag is not set, the function
raises runtime error.
Splits set of vectors by given number of clusters
void cvKMeans2( const CvArr* samples, int cluster_count, CvArr* labels, CvTermCriteria termcrit );
The function cvKMeans2
implements k-means algorithm that finds centers of cluster_count
clusters
and groups the input samples around the clusters. On output labels(i)
contains a cluster index
for sample stored in the i-th row of samples
matrix.
#include "cxcore.h" #include "highgui.h" void main( int argc, char** argv ) { #define MAX_CLUSTERS 5 CvScalar color_tab[MAX_CLUSTERS]; IplImage* img = cvCreateImage( cvSize( 500, 500 ), 8, 3 ); CvRNG rng = cvRNG(0xffffffff); color_tab[0] = CV_RGB(255,0,0); color_tab[1] = CV_RGB(0,255,0); color_tab[2] = CV_RGB(100,100,255); color_tab[3] = CV_RGB(255,0,255); color_tab[4] = CV_RGB(255,255,0); cvNamedWindow( "clusters", 1 ); for(;;) { int k, cluster_count = cvRandInt(&rng)%MAX_CLUSTERS + 1; int i, sample_count = cvRandInt(&rng)%1000 + 1; CvMat* points = cvCreateMat( sample_count, 1, CV_32FC2 ); CvMat* clusters = cvCreateMat( sample_count, 1, CV_32SC1 ); /* generate random sample from multigaussian distribution */ for( k = 0; k < cluster_count; k++ ) { CvPoint center; CvMat point_chunk; center.x = cvRandInt(&rng)%img->width; center.y = cvRandInt(&rng)%img->height; cvGetRows( points, &point_chunk, k*sample_count/cluster_count, k == cluster_count - 1 ? sample_count : (k+1)*sample_count/cluster_count ); cvRandArr( &rng, &point_chunk, CV_RAND_NORMAL, cvScalar(center.x,center.y,0,0), cvScalar(img->width/6, img->height/6,0,0) ); } /* shuffle samples */ for( i = 0; i < sample_count/2; i++ ) { CvPoint2D32f* pt1 = (CvPoint2D32f*)points->data.fl + cvRandInt(&rng)%sample_count; CvPoint2D32f* pt2 = (CvPoint2D32f*)points->data.fl + cvRandInt(&rng)%sample_count; CvPoint2D32f temp; CV_SWAP( *pt1, *pt2, temp ); } cvKMeans2( points, cluster_count, clusters, cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0 )); cvZero( img ); for( i = 0; i < sample_count; i++ ) { CvPoint2D32f pt = ((CvPoint2D32f*)points->data.fl)[i]; int cluster_idx = clusters->data.i[i]; cvCircle( img, cvPointFrom32f(pt), 2, color_tab[cluster_idx], CV_FILLED ); } cvReleaseMat( &points ); cvReleaseMat( &clusters ); cvShowImage( "clusters", img ); int key = cvWaitKey(0); if( key == 27 ) // 'ESC' break; } }
Splits sequence into equivalency classes
typedef int (CV_CDECL* CvCmpFunc)(const void* a, const void* b, void* userdata); int cvSeqPartition( const CvSeq* seq, CvMemStorage* storage, CvSeq** labels, CvCmpFunc is_equal, void* userdata );
seq->storage
for output labels.
is_equal
function.
The function cvSeqPartition
implements quadratic algorithm for splitting
a set into one or more classes of equivalency. The function returns the number of equivalency classes.
#include "cxcore.h" #include "highgui.h" #include <stdio.h> CvSeq* point_seq = 0; IplImage* canvas = 0; CvScalar* colors = 0; int pos = 10; int is_equal( const void* _a, const void* _b, void* userdata ) { CvPoint a = *(const CvPoint*)_a; CvPoint b = *(const CvPoint*)_b; double threshold = *(double*)userdata; return (double)(a.x - b.x)*(a.x - b.x) + (double)(a.y - b.y)*(a.y - b.y) <= threshold; } void on_track( int pos ) { CvSeq* labels = 0; double threshold = pos*pos; int i, class_count = cvSeqPartition( point_seq, 0, &labels, is_equal, &threshold ); printf("%4d classes\n", class_count ); cvZero( canvas ); for( i = 0; i < labels->total; i++ ) { CvPoint pt = *(CvPoint*)cvGetSeqElem( point_seq, i, 0 ); CvScalar color = colors[*(int*)cvGetSeqElem( labels, i, 0 )]; cvCircle( canvas, pt, 1, color, -1 ); } cvShowImage( "points", canvas ); } int main( int argc, char** argv ) { CvMemStorage* storage = cvCreateMemStorage(0); point_seq = cvCreateSeq( CV_32SC2, sizeof(CvSeq), sizeof(CvPoint), storage ); CvRNG rng = cvRNG(0xffffffff); int width = 500, height = 500; int i, count = 1000; canvas = cvCreateImage( cvSize(width,height), 8, 3 ); colors = (CvScalar*)cvAlloc( count*sizeof(colors[0]) ); for( i = 0; i < count; i++ ) { CvPoint pt; int icolor; pt.x = cvRandInt( &rng ) % width; pt.y = cvRandInt( &rng ) % height; cvSeqPush( point_seq, &pt ); icolor = cvRandInt( &rng ) | 0x00404040; colors[i] = CV_RGB(icolor & 255, (icolor >> 8)&255, (icolor >> 16)&255); } cvNamedWindow( "points", 1 ); cvCreateTrackbar( "threshold", "points", &pos, 50, on_track ); on_track(pos); cvWaitKey(0); return 0; }
Error handling in OpenCV is similar to IPL (Image Processing Library). In case of error functions do not return the error code. Instead, they raise an error using CV_ERROR macro that calls cvError that, in its turn, sets the error status with cvSetErrStatus and calls a standard or user-defined error handler (that can display a message box, write to log etc., see cvRedirectError, cvNulDevReport, cvStdErrReport, cvGuiBoxReport). There is global variable, one per each program thread, that contains current error status (an integer value). The status can be retrieved with cvGetErrStatus function.
There are three modes of error handling (see cvSetErrMode and cvGetErrMode):
Actually, the semantics of Leaf and Parent modes is implemented by error handlers and the above description is true for cvNulDevReport, cvStdErrReport. cvGuiBoxReport behaves slightly differently, and some custom error handler may implement quite different semantics.
Macros for raising an error, checking for errors etc.
/* special macros for enclosing processing statements within a function and separating them from prologue (resource initialization) and epilogue (guaranteed resource release) */ #define __BEGIN__ { #define __END__ goto exit; exit: ; } /* proceeds to "resource release" stage */ #define EXIT goto exit /* Declares locally the function name for CV_ERROR() use */ #define CV_FUNCNAME( Name ) \ static char cvFuncName[] = Name /* Raises an error within the current context */ #define CV_ERROR( Code, Msg ) \ { \ cvError( (Code), cvFuncName, Msg, __FILE__, __LINE__ ); \ EXIT; \ } /* Checks status after calling CXCORE function */ #define CV_CHECK() \ { \ if( cvGetErrStatus() < 0 ) \ CV_ERROR( CV_StsBackTrace, "Inner function failed." ); \ } /* Provies shorthand for CXCORE function call and CV_CHECK() */ #define CV_CALL( Statement ) \ { \ Statement; \ CV_CHECK(); \ } /* Checks some condition in both debug and release configurations */ #define CV_ASSERT( Condition ) \ { \ if( !(Condition) ) \ CV_ERROR( CV_StsInternal, "Assertion: " #Condition " failed" ); \ } /* these macros are similar to their CV_... counterparts, but they do not need exit label nor cvFuncName to be defined */ #define OPENCV_ERROR(status,func_name,err_msg) ... #define OPENCV_ERRCHK(func_name,err_msg) ... #define OPENCV_ASSERT(condition,func_name,err_msg) ... #define OPENCV_CALL(statement) ...Instead of a discussion, here are the documented example of typical CXCORE function and the example of the function use.
#include "cxcore.h" #include <stdio.h> void cvResizeDCT( CvMat* input_array, CvMat* output_array ) { CvMat* temp_array = 0; // declare pointer that should be released anyway. CV_FUNCNAME( "cvResizeDCT" ); // declare cvFuncName __BEGIN__; // start processing. There may be some declarations just after this macro, // but they couldn't be accessed from the epilogue. if( !CV_IS_MAT(input_array) || !CV_IS_MAT(output_array) ) // use CV_ERROR() to raise an error CV_ERROR( CV_StsBadArg, "input_array or output_array are not valid matrices" ); // some restrictions that are going to be removed later, may be checked with CV_ASSERT() CV_ASSERT( input_array->rows == 1 && output_array->rows == 1 ); // use CV_CALL for safe function call CV_CALL( temp_array = cvCreateMat( input_array->rows, MAX(input_array->cols,output_array->cols), input_array->type )); if( output_array->cols > input_array->cols ) CV_CALL( cvZero( temp_array )); temp_array->cols = input_array->cols; CV_CALL( cvDCT( input_array, temp_array, CV_DXT_FORWARD )); temp_array->cols = output_array->cols; CV_CALL( cvDCT( temp_array, output_array, CV_DXT_INVERSE )); CV_CALL( cvScale( output_array, output_array, 1./sqrt((double)input_array->cols*output_array->cols), 0 )); __END__; // finish processing. Epilogue follows after the macro. // release temp_array. If temp_array has not been allocated before an error occured, cvReleaseMat // takes care of it and does nothing in this case. cvReleaseMat( &temp_array ); } int main( int argc, char** argv ) { CvMat* src = cvCreateMat( 1, 512, CV_32F ); #if 1 /* no errors */ CvMat* dst = cvCreateMat( 1, 256, CV_32F ); #else CvMat* dst = 0; /* test error processing mechanism */ #endif cvSet( src, cvRealScalar(1.), 0 ); #if 0 /* change 0 to 1 to suppress error handler invocation */ cvSetErrMode( CV_ErrModeSilent ); #endif cvResizeDCT( src, dst ); // if some error occurs, the message box will popup, or a message will be // written to log, or some user-defined processing will be done if( cvGetErrStatus() < 0 ) printf("Some error occured" ); else printf("Everything is OK" ); return 0; }
Returns the current error status
int cvGetErrStatus( void );
The function cvGetErrStatus
returns the current error status -
the value set with the last cvSetErrStatus call. Note, that
in Leaf mode the program terminates immediately after error occured, so to
always get control after the function call, one should call cvSetErrMode
and set Parent or Silent error mode.
Sets the error status
void cvSetErrStatus( int status );
The function cvSetErrStatus
sets the error status to
the specified value. Mostly, the function is used to reset the error status (set to it CV_StsOk
)
to recover after error. In other cases it is more natural to call cvError or
CV_ERROR.
Returns the current error mode
int cvGetErrMode( void );
The function cvGetErrMode
returns the current error mode -
the value set with the last cvSetErrMode call.
Sets the error mode
#define CV_ErrModeLeaf 0 #define CV_ErrModeParent 1 #define CV_ErrModeSilent 2 int cvSetErrMode( int mode );
The function cvSetErrMode
sets the specified error mode.
For description of different error modes see the beginning of the section.
Raises an error
int cvError( int status, const char* func_name, const char* err_msg, const char* file_name, int line );
The function cvError
sets the error status
to the specified value (via cvSetErrStatus)
and, if the error mode is not Silent, calls the error handler.
Returns textual description of error status code
const char* cvErrorStr( int status );
The function cvErrorStr
returns the textual description
for the specified error status code. In case of unknown status the function returns NULL pointer.
Sets a new error handler
typedef int (CV_CDECL *CvErrorCallback)( int status, const char* func_name, const char* err_msg, const char* file_name, int line ); CvErrorCallback cvRedirectError( CvErrorCallback error_handler, void* userdata=NULL, void** prev_userdata=NULL );
The function cvRedirectError
sets a new error handler that
can be one of standard handlers or a custom handler that has
the certain interface. The handler takes the same parameters as cvError
function. If the handler returns non-zero value, the program is terminated, otherwise, it continues.
The error handler may check the current error mode with cvGetErrMode
to make a decision.
Provide standard error handling
int cvNulDevReport( int status, const char* func_name, const char* err_msg, const char* file_name, int line, void* userdata ); int cvStdErrReport( int status, const char* func_name, const char* err_msg, const char* file_name, int line, void* userdata ); int cvGuiBoxReport( int status, const char* func_name, const char* err_msg, const char* file_name, int line, void* userdata );
The functions cvNullDevReport, cvStdErrReport
and cvGuiBoxReport
provide standard error handling. cvGuiBoxReport
is the default
error handler on Win32 systems, cvStdErrReport
- on other systems.
cvGuiBoxReport
pops up message box with the error description and
suggest a few options. Below is the sample message box that may be recieved with the
sample code above, if one introduce an error as described
in the sample
If the error handler is set
cvStdErrReport
, the above message will
be printed to standard error output and program will be terminated or continued, depending on the
current error mode.
OpenCV ERROR: Bad argument (input_array or output_array are not valid matrices) in function cvResizeDCT, D:\User\VP\Projects\avl_proba\a.cpp(75) Terminating the application...
Allocates memory buffer
void* cvAlloc( size_t size );
The function cvAlloc
allocates size
bytes and
returns pointer to the allocated buffer. In case of error
the function reports an error and returns NULL pointer.
By default cvAlloc calls icvAlloc which itself calls malloc,
however it is possible to assign user-defined memory allocation/deallocation
functions using cvSetMemoryManager function.
Deallocates memory buffer
void cvFree( T** ptr );
The function cvFree
deallocates memory buffer allocated by cvAlloc.
It clears the pointer to buffer upon exit, that is why the double pointer is
used. If *buffer is already NULL, the function does nothing
Returns number of tics
int64 cvGetTickCount( void );
The function cvGetTickCount
returns number of tics
starting from some platform-dependent event (number of CPU ticks from the startup, number of milliseconds
from 1970th year etc.). The function is useful for accurate measurement of
a function/user-code execution time. To convert the number of tics to time units, use
cvGetTickFrequency.
Returns number of tics per microsecond
double cvGetTickFrequency( void );
The function cvGetTickFrequency
returns number of tics
per microsecond. Thus, the quotient of cvGetTickCount() and
cvGetTickFrequency() will give a number of microseconds
starting from the platform-dependent event.
Registers another module
typedef struct CvPluginFuncInfo { void** func_addr; void* default_func_addr; const char* func_names; int search_modules; int loaded_from; } CvPluginFuncInfo; typedef struct CvModuleInfo { struct CvModuleInfo* next; const char* name; const char* version; CvPluginFuncInfo* func_tab; } CvModuleInfo; int cvRegisterModule( const CvModuleInfo* module_info );
The function cvRegisterModule
adds module to the list of registered
modules. After the module is registered, information about it can be retrieved
using cvGetModuleInfo function. Also, the registered module
makes full use of optimized plugins (IPP, MKL, ...), supported by CXCORE.
CXCORE itself, CV (computer vision), CVAUX (auxilary computer vision) and HIGHGUI
(visualization & image/video acquisition) are examples of modules. Registration is usually done
then the shared library is loaded. See cxcore/src/cxswitcher.cpp and cv/src/cvswitcher.cpp
for details, how registration is done and
look at cxcore/src/cxswitcher.cpp, cxcore/src/_cxipp.h on how IPP and MKL are connected to the modules.
Retrieves information about the registered module(s) and plugins
void cvGetModuleInfo( const char* module_name, const char** version, const char** loaded_addon_plugins );
The function cvGetModuleInfo
returns information about one of
or all of the registered modules. The returned information is stored inside the libraries, so
user should not deallocate or modify the returned text strings.
Switches between optimized/non-optimized modes
int cvUseOptimized( int on_off );
The function cvUseOptimized
switches between the mode, where
only pure C implementations from cxcore, OpenCV etc. are used, and the mode, where
IPP and MKL functions are used if available. When cvUseOptimized(0)
is called,
all the optimized libraries are unloaded. The function may be useful for debugging, IPP&MKL upgrade
on the fly, online speed comparisons etc. It returns the number of optimized functions loaded.
Note that by default the optimized plugins are loaded, so it is not necessary to
call cvUseOptimized(1)
in the beginning of the program (actually, it will only
increase the startup time)
Assings custom/default memory managing functions
typedef void* (CV_CDECL *CvAllocFunc)(size_t size, void* userdata); typedef int (CV_CDECL *CvFreeFunc)(void* pptr, void* userdata); void cvSetMemoryManager( CvAllocFunc alloc_func=NULL, CvFreeFunc free_func=NULL, void* userdata=NULL );
malloc
, except that userdata
may be used to determine the context.
free
.
The function cvSetMemoryManager
sets user-defined memory managment functions (substitutors for malloc and free) that
will be called by cvAlloc, cvFree and higher-level functions (e.g. cvCreateImage).
Note, that the function should be called when there is data allocated using cvAlloc.
Also, to avoid infinite recursive calls, it is not allowed to call cvAlloc
and cvFree from the custom allocation/deallocation functions.
If alloc_func
and free_func
pointers are NULL
,
the default memory managing functions are restored.
Switches to IPL functions for image allocation/deallocation
typedef IplImage* (CV_STDCALL* Cv_iplCreateImageHeader) (int,int,int,char*,char*,int,int,int,int,int, IplROI*,IplImage*,void*,IplTileInfo*); typedef void (CV_STDCALL* Cv_iplAllocateImageData)(IplImage*,int,int); typedef void (CV_STDCALL* Cv_iplDeallocate)(IplImage*,int); typedef IplROI* (CV_STDCALL* Cv_iplCreateROI)(int,int,int,int,int); typedef IplImage* (CV_STDCALL* Cv_iplCloneImage)(const IplImage*); void cvSetIPLAllocators( Cv_iplCreateImageHeader create_header, Cv_iplAllocateImageData allocate_data, Cv_iplDeallocate deallocate, Cv_iplCreateROI create_roi, Cv_iplCloneImage clone_image ); #define CV_TURN_ON_IPL_COMPATIBILITY() \ cvSetIPLAllocators( iplCreateImageHeader, iplAllocateImage, \ iplDeallocate, iplCreateROI, iplCloneImage )
The function cvSetIPLAllocators
makes CXCORE to use IPL functions for image allocation/deallocation operations.
For convenience, there is the wrapping macro CV_TURN_ON_IPL_COMPATIBILITY
.
The function is useful for applications where IPL and CXCORE/OpenCV are used together and still
there are calls to iplCreateImageHeader
etc. The function is not necessary if
IPL is called only for data processing and all the allocation/deallocation is done by CXCORE,
or if all the allocation/deallocation is done by IPL and some of OpenCV functions are used to
process the data.
Returns the current number of threads used
int cvGetNumThreads(void);
The function cvGetNumThreads
return the current number of threads
that are used by parallelized (via OpenMP) OpenCV functions.
Sets the number of threads
void cvSetNumThreads( int threads=0 );
The function cvSetNumThreads
sets the number of threads
that are used by parallelized OpenCV functions. When the argument
is zero or negative, and at the beginning of the program,
the number of threads is set to the number of processors in the system,
as returned by the function omp_get_num_procs()
from OpenMP runtime.
Returns index of the current thread
int cvGetThreadNum( void );
The function cvGetThreadNum
returns the index, from 0 to
cvGetNumThreads()-1, of the thread that called the function.
It is a wrapper for the function omp_get_thread_num()
from OpenMP runtime.
The retrieved index may be used to access local-thread data inside the parallelized code fragments.
AbsDiff | AddWeighted | Avg |
AbsDiffS | Alloc | AvgSdv |
Add | And | |
AddS | AndS |
BackProjectPCA |
DCT | Det | DrawContours |
DFT | Div | |
DecRefData | DotProduct |
EigenVV | EllipseBox | Error |
Ellipse | EndWriteSeq | ErrorStr |
Ellipse2Poly | EndWriteStruct | Exp |
FastArctan | FindGraphEdgeByPtr | FlushSeqWriter |
FillConvexPoly | FindType | Free |
FillPoly | FirstType | |
FindGraphEdge | Flip |
InRange | InitLineIterator | InsertNodeIntoTree |
InRangeS | InitMatHeader | InvSqrt |
IncRefData | InitMatNDHeader | Invert |
InitFont | InitSparseMatIterator | IsInf |
InitImageHeader | InitTreeNodeIterator | IsNaN |
KMeans2 |
LUT | Load | |
Line | Log |
Mahalonobis | MemStorageAlloc | MinS |
MakeSeqHeaderForArray | MemStorageAllocString | MixChannels |
Mat | Merge | Mul |
Max | Min | MulSpectrums |
MaxS | MinMaxLoc | MulTransposed |
NextGraphItem | Norm | Not |
NextTreeNode | Normalize | NulDevReport |
OpenFileStorage | Or | OrS |
PerspectiveTransform | Pow | Ptr*D |
PolarToCart | PrevTreeNode | PutText |
PolyLine | ProjectPCA |
Trace | Transpose | TypeOf |
Transform | TreeToNodeSeq |
UnregisterType | UseOptimized |
Write | WriteInt | WriteString |
WriteComment | WriteRawData | |
WriteFileNode | WriteReal |
Xor | XorS |