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)=lower0 <= src(I)0 < upper0
for a single-channel array,
dst(I)=lower0 <= src(I)0 < upper0 && lower1 <= src(I)1 < upper1
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 - valuec).
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 = sumI 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:
Sc = sumI arr(I)cIf the array is
IplImage
and COI is set, the function processes the selected channel only
and stores the sum to the first scalar component (S0).
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 = sumI mask(I)!=0 Mc = 1/N • sumI,mask(I)!=0 arr(I)cIf the array is
IplImage
and COI is set, the function processes the selected channel only
and stores the average to the first scalar component (S0).
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 = sumI mask(I)!=0 meanc = 1/N • sumI,mask(I)!=0 arr(I)c std_devc = sqrt(1/N • sumI,mask(I)!=0 (arr(I)c - Mc)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 (M0
and S0).
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.

The function cvNorm
calculates the absolute norm of arr1
if arr2
is NULL:
norm = ||arr1||C = maxI abs(arr1(I)), ifnormType
= CV_C norm = ||arr1||L1 = sumI abs(arr1(I)), ifnormType
= CV_L1 norm = ||arr1||L2 = sqrt( sumI arr1(I)2), ifnormType
= CV_L2
And the function calculates absolute or relative difference norm if arr2
is not NULL:
norm = ||arr1-arr2||C = maxI abs(arr1(I)-arr2(I)), ifnormType
= CV_C norm = ||arr1-arr2||L1 = sumI abs(arr1(I)-arr2(I)), ifnormType
= CV_L1 norm = ||arr1-arr2||L2 = sqrt( sumI (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 = sumI(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 L1-norm (sum of absolute values) of the array is normalized.CV_L2
- the (Euclidian) L2-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, (dst1 = src12src23 - src13src22 , dst2 = src13src21 - src11src23 , dst3 = src11src22 - src12src21).
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*src1T*src2 + beta*srcT
The function cvGEMM
performs generalized matrix multiplication:
dst = alpha*op(src1)*op(src2) + beta*op(src3), where op(X) is X or XT
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=sumj(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)=sumimat(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 minX||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*VT
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*UT*B
Where
W-1(i,i)=1/W(i,i) if W(i,i) > epsilon•sumiW(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( sumi,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 231, 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]*x3 + coeffs[1]*x2 + coeffs[2]*x + coeffs[3] = 0 (if coeffs is 4-element vector) or x3 + coeffs[0]*x2 + 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 Y0,0 Re Y0,1 Im Y0,1 Re Y0,2 Im Y0,2 ... Re Y0,N/2-1 Im Y0,N/2-1 Re Y0,N/2 Re Y1,0 Re Y1,1 Im Y1,1 Re Y1,2 Im Y1,2 ... Re Y1,N/2-1 Im Y1,N/2-1 Re Y1,N/2 Im Y1,0 Re Y2,1 Im Y2,1 Re Y2,2 Im Y2,2 ... Re Y2,N/2-1 Im Y2,N/2-1 Im Y2,N/2 ............................................................................................ Re YM/2-1,0 Re YM-3,1 Im YM-3,1 Re YM-3,2 Im YM-3,2 ... Re YM-3,N/2-1 Im YM-3,N/2-1 Re YM-3,N/2 Im YM/2-1,0 Re YM-2,1 Im YM-2,1 Re YM-2,2 Im YM-2,2 ... Re YM-2,N/2-1 Im YM-2,N/2-1 Im YM-2,N/2 Re YM/2,0 Re YM-1,1 Im YM-1,1 Re YM-1,2 Im YM-1,2 ... Re YM-1,N/2-1 Im YM-1,N/2-1 Im YM-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=2p×3q×5r
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