OpenCV学习笔记之CXCORE篇



转自http://blog.csdn.net/wangjie0377/article/details/6629293

 

OpenCV学习笔记之CXCORE篇

 

   为使得OpenCV的整个库便于管理和扩充,将整个库分成若干子库,CxCore是最重要的一个子库,从“core"名字可以看出,该库提供了所有OpenCV运行时的一些最基本的数据结构,包括矩阵,数组的基本运算,包括出错处理的一些基本函数。具体分为下面若干部分。

基础结构:

CvPoint

二维坐标系下的点,类型为整型

typedef struct CvPoint { int x; int y; } CvPoint;  
 inline CvPoint cvPoint( int x, int y );  
 inline CvPoint cvPointFrom32f( CvPoint2D32f point )  

CvPoint2D32f

二维坐标下的点,类型为浮点

typedef struct CvPoint2D32f { float x; float y; } CvPoint2D32f;  
 inline CvPoint2D32f cvPoint2D32f( double x, double y );  
 inline CvPoint2D32f cvPointTo32f( CvPoint point );  

CvPoint3D32f

三维坐标下的点,类型为浮点

typedef struct CvPoint3D32f { float x; float y; float z; } CvPoint3D32f;  
 inline CvPoint3D32f cvPoint3D32f( double x, double y, double z );  

CvSize

矩形框大小,以像素为精度

typedef struct CvSize { int width; int height; } CvSize;  
 inline CvSize cvSize( int width, int height );  

注意:构造函数的cv是小写!

CvSize2D32f

以亚像素精度标量矩形框大小

typedef struct CvSize2D32f { float width; float height; } CvSize2D32f;  
 inline CvSize2D32f cvSize2D32f( double width, double height ); { CvSize2D32f s; s.width = (float)width; s.height = (float)height; return s; }  

CvRect

矩形框的偏移和大小

typedef struct CvRect { int x; int y; int width; int height; } CvRect;  
 inline CvRect cvRect( int x, int y, int width, int height ); { CvRect os; os.x = x; os.y = y; os.width = width; os.height = heigth; reture os;}  

CvScalar

可存放在1-,2-,3-,4-TUPLE类型的捆绑数据的容器

typedef struct CvScalar { double val[4] } CvScalar;  
 inline CvScalar cvScalar( double val0, double val1, double val2, double val3); { CvScalar arr; arr.val[4] = {val0,val1,val2,val3}; reture arr;}  
 inline CvScalar cvScalarAll( double val0123 ); { CvScalar arr; arr.val[4] = {val0123,val0123,val0123,val0123,}; reture arr;}  
 inline CvScalar cvRealScalar( double val0 ); { CvScalar arr; arr.val[4] = {val0}; reture arr;} 

CvTermCriteria

迭代算法的终止准则

#define CV_TERMCRIT_ITER 1 #define CV_TERMCRIT_NUMBER CV_TERMCRIT_ITER #define CV_TERMCRIT_EPS 2 typedef struct CvTermCriteria { int type; int max_iter; double epsilon; } CvTermCriteria;  
 inline CvTermCriteria cvTermCriteria( int type, int max_iter, double epsilon );  
 CvTermCriteria cvCheckTermCriteria( CvTermCriteria criteria, double default_eps, int default_max_iters );  

CvMat

多通道矩阵

typedef struct CvMat { int type; int step; int* refcount; union { uchar* ptr; short* s; int* i; float* fl; double* db; } data; #ifdef __cplusplus union { int rows; int height; }; union { int cols; int width; }; #else int rows; int cols; #endif } CvMat;  

CvMatND

多维、多通道密集数组

typedef struct CvMatND { int type; int dims; int* refcount; union { uchar* ptr; short* s; int* i; float* fl; double* db; } data; struct { int size; int step; } dim[CV_MAX_DIM]; } CvMatND;  

CvSparseMat

多维、多通道稀疏数组

typedef struct CvSparseMat { int type; int dims; int* refcount; struct CvSet* heap; void** hashtable; int hashsize; int total; int valoffset; int idxoffset; int size[CV_MAX_DIM]; } CvSparseMat;  

IplImage

IPL 图像头

typedef struct _IplImage { int nSize; int ID; int nChannels; int alphaChannel; int depth; char colorModel[4]; char channelSeq[4]; int dataOrder; int origin; int align; int width; int height; struct _IplROI *roi; struct _IplImage *maskROI; void *imageId; struct _IplTileInfo *tileInfo; int imageSize; char *imageData; int widthStep; int BorderMode[4]; int BorderConst[4]; char *imageDataOrigin; } IplImage;  

IplImage结构来自于 Intel Image Processing Library(是其本身所具有的)。OpenCV 只支持其中的一个子集:

  • alphaChannel 在OpenCV中被忽略。
  • colorModel 和channelSeq 被OpenCV忽略。OpenCV颜色转换的唯一函数 cvCvtColor把原图像的颜色空间的目标图像的颜色空间作为一个参数。
  • dataOrder 必须是IPL_DATA_ORDER_PIXEL (颜色通道是交叉存取),然而平面图像的被选择通道可以被处理,就像COI(感兴趣的通道)被设置过一样。
  • align 是被OpenCV忽略的,而用 widthStep 去访问后继的图像行。
  • 不支持maskROI 。处理MASK的函数把他当作一个分离的参数。MASK在 OpenCV 里是 8-bit,然而在 IPL他是 1-bit。
  • tileInfo 不支持。
  • BorderMode和BorderConst是不支持的。每个 OpenCV 函数处理像素的邻近的像素,通常使用单一的固定代码边际模式。

除了上述限制,OpenCV处理ROI有不同的要求。要求原图像和目标图像的尺寸或 ROI的尺寸必须(根据不同的操作,例如cvPyrDown 目标图像的宽(高)必须等于原图像的宽(高)除以2 ±1)精确匹配,而IPL处理交叉区域,如图像的大小或ROI大小可能是完全独立的。

CvArr

不确定数组

typedef void CvArr;  

CvArr* 仅仅是被用于作函数的参数,用于指示函数接收的数组类型可以不止一个,如 IplImage*, CvMat* 甚至 CvSeq*. 最终的数组类型是在运行时通过分析数组头的前4 个字节判断。

数组操作

初始化

CreateImage

创建头并分配数据

IplImage* cvCreateImage( CvSize size, int depth, int channels );

size

图像宽、高.

depth

图像元素的位深度,可以是下面的其中之一:

IPL_DEPTH_8U - 无符号8位整型

IPL_DEPTH_8S - 有符号8位整型

IPL_DEPTH_16U - 无符号16位整型

IPL_DEPTH_16S - 有符号16位整型

IPL_DEPTH_32S - 有符号32位整型

IPL_DEPTH_32F - 单精度浮点数

IPL_DEPTH_64F - 双精度浮点数

channels

每个元素(像素)的颜色通道数量.可以是 1, 2, 3 或 4.通道是交叉存取的,例如通常的彩色图像数据排列是:

b0 g0 r0 b1 g1 r1 ...

虽然通常 IPL 图象格式可以存贮非交叉存取的图像,并且一些OpenCV 也能处理他, 但是这个函数只能创建交叉存取图像.

函数 cvCreateImage 创建头并分配数据,这个函数是下列的缩写型式

header = cvCreateImageHeader(size,depth,channels);

cvCreateData(header); //只是创建空间,并不会初始化空间内的数据

CreateImageHeader

分配,初始化,并且返回 IplImage结构

IplImage* cvCreateImageHeader( CvSize size, int depth, int channels );

size

图像宽、高.

depth

像深 (见 CreateImage).

channels

通道数 (见 CreateImage).

函数 cvCreateImageHeader 分配, 初始化, 并且返回 IplImage结构. 这个函数相似于:

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);

然而IPL函数不是作为默认的 (见 CV_TURN_ON_IPL_COMPATIBILITY 宏)

ReleaseImageHeader

释放头

void cvReleaseImageHeader( IplImage** image );

image

双指针指向头内存分配单元.

函数 cvReleaseImageHeader 释放头. 相似于

if( image )

{

iplDeallocate( *image, IPL_IMAGE_HEADER | IPL_IMAGE_ROI );

*image = 0;

}

然而IPL函数不是作为默认的 (见 CV_TURN_ON_IPL_COMPATIBILITY 宏)

ReleaseImage

释放头和图像数据

void cvReleaseImage( IplImage** image );

image

双指针指向图像内存分配单元。

函数 cvReleaseImage 释放头和图像数据,相似于:

if( *image )

{

cvReleaseData( *image );

cvReleaseImageHeader( image );

}

InitImageHeader

初始化被用图分配的图像头

IplImage* cvInitImageHeader( IplImage* image, CvSize size, int depth,

int channels, int origin=0, int align=4 );

image

被初始化的图像头.

size

图像的宽高.

depth

像深(见 CreateImage).

channels

通道数(见 CreateImage).

origin

IPL_ORIGIN_TL 或 IPL_ORIGIN_BL.

align

图像行排列, 典型的 4 或 8 字节.

函数 cvInitImageHeader 初始化图像头结构, 指向用户指定的图像并且返回这个指针。

CloneImage

制作图像的完整拷贝

IplImage* cvCloneImage( const IplImage* image );

image

原图像.

函数 cvCloneImage 制作图像的完整拷贝包括头、ROI和数据

SetImageCOI

基于给定的值设置感兴趣通道

void cvSetImageCOI( IplImage* image, int coi );

image

图像头.

coi

感兴趣通道.

函数 cvSetImageCOI 基于给定的值设置感兴趣的通道。值 0 意味着所有的通道都被选定, 1 意味着第一个通道被选定等等。如果 ROI 是 NULL 并且COI!= 0, ROI 被分配. 然而大多数的 OpenCV 函数不支持 COI, 对于这种状况当处理分离图像/矩阵通道时,可以拷贝(通过 cvCopy 或cvSplit) 通道来分离图像/矩阵,处理后如果需要可再拷贝(通过cvCopy 或 cvCvtPlaneToPix)回来.

GetImageCOI

返回感兴趣通道号

int cvGetImageCOI( const IplImage* image );

image

图像头.

函数cvGetImageCOI 返回图像的感兴趣通道(当所有的通道都被选中返回值是0).

SetImageROI

基于给定的矩形设置'感兴趣'区域

void cvSetImageROI( IplImage* image, CvRect rect );

image

图像.

rect

ROI 矩形.

函数 cvSetImageROI 基于给定的矩形设置图像的 ROI(感兴趣区域) . 如果ROI是NULL 并且参数RECT的值不等于整个图像, ROI被分配. 不像 COI, 大多数的 OpenCV 函数支持 ROI 并且处理它就像它是一个分离的图像 (例如, 所有的像素坐标从ROI的左上角或左下角(基于图像的结构)计算。

ResetImageROI

释放图像的ROI

void cvResetImageROI( IplImage* image );

image

图像头.

函数 cvResetImageROI 释放图像 ROI. 释放之后整个图像被认为是全部被选中的。相似的结果可以通过下述办法

cvSetImageROI( image, cvRect( 0, 0, image->width, image->height ));

cvSetImageCOI( image, 0 );

但是后者的变量不分配 image->roi.

 

GetImageROI

返回图像的 ROI 坐标

CvRect cvGetImageROI( const IplImage* image );

image

图像头.

函数 cvGetImageROI 返回图像ROI 坐标. 如果没有ROI则返回矩形值为 cvRect(0,0,image->width,image->height)

 

CreateMat

创建矩阵

CvMat* cvCreateMat( int rows, int cols, int type );

rows

矩阵行数。

cols

矩阵列数。

type

矩阵元素类型。 通常以 CV_<比特数>(S|U|F)C<通道数>型式描述,例如:

CV_8UC1 意思是一个8-bit 无符号单通道矩阵, CV_32SC2 意思是一个32-bit 有符号二个通道的矩阵。

函数 cvCreateMat 为新的矩阵分配头和下面的数据,并且返回一个指向新创建的矩阵的指针。是下列操作的缩写型式:

CvMat* mat = cvCreateMatHeader( rows, cols, type );

cvCreateData( mat );

矩阵按行存贮。所有的行以4个字节对齐。

CreateMatHeader

创建新的矩阵头

CvMat* cvCreateMatHeader( int rows, int cols, int type );

rows

矩阵行数.

cols

矩阵列数.

type

矩阵元素类型(见 cvCreateMat).

函数 cvCreateMatHeader 分配新的矩阵头并且返回指向它的指针. 矩阵数据可被进一步的分配,使用cvCreateData 或通过 cvSetData明确的分配数据.

ReleaseMat

删除矩阵

void cvReleaseMat( CvMat** mat );

mat

双指针指向矩阵.

函数cvReleaseMat 缩减矩阵数据参考计数并且释放矩阵头 :

if( *mat )

cvDecRefData( *mat );

cvFree( (void**)mat );

InitMatHeader

初始化矩阵头

CvMat* cvInitMatHeader( CvMat* mat, int rows, int cols, int type,

void* data=NULL, int step=CV_AUTOSTEP );

mat

指针指向要被初始化的矩阵头.

rows

矩阵的行数.

cols

矩阵的列数.

type

矩阵元素类型.

data

可选的,将指向数据指针分配给矩阵头.

step

排列后的数据的整个行宽,默认状态下,使用STEP的最小可能值。也就是说默认情况下假定矩阵的行与行之间无隙.

函数 cvInitMatHeader 初始化已经分配了的 CvMat 结构. 它可以被OpenCV矩阵函数用于处理原始数据。

例如, 下面的代码计算通用数组格式存贮的数据的矩阵乘积.

计算两个矩阵的积

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 数组存贮 a(3x4) 和 b(4x3) 矩阵的积

Mat

初始化矩阵的头(轻磅变量)

CvMat cvMat( int rows, int cols, int type, void* data=NULL );

rows

矩阵行数

cols

列数.

type

元素类型(见CreateMat).

data

可选的分配给矩阵头的数据指针 .

函数 cvMat 是个一快速内连函数,替代函数 cvInitMatHeader. 也就是说它相当于:

CvMat mat;

cvInitMatHeader( &mat, rows, cols, type, data, CV_AUTOSTEP );

 

CloneMat

创建矩阵拷贝

CvMat* cvCloneMat( const CvMat* mat );

mat

输入矩阵.

函数 cvCloneMat 创建输入矩阵的一个拷贝并且返回 该矩阵的指针.

CreateMatND

创建多维密集数组

CvMatND* cvCreateMatND( int dims, const int* sizes, int type );

dims

数组维数. 但不许超过 CV_MAX_DIM (默认=32,但这个默认值可能在编译时被改变 )的定义

sizes

数组的维大小.

type

数组元素类型. 与 CvMat相同

函数cvCreateMatND 分配头给多维密集数组并且分配下面的数据,返回指向被创建数组的指针 . 是下列的缩减形式:

CvMatND* mat = cvCreateMatNDHeader( dims, sizes, type );

cvCreateData( mat );

矩阵按行存贮. 所有的行以4个字节排列。.

 

CreateMatNDHeader

创建新的数组头

CvMatND* cvCreateMatNDHeader( int dims, const int* sizes, int type );

dims

数组维数.

sizes

维大小.

type

数组元素类型. 与 CvMat相同

函数cvCreateMatND 分配头给多维密集数组。数组数据可以用 cvCreateData 进一步的被分配或利用cvSetData由用户明确指定.

ReleaseMatND

删除多维数组

void cvReleaseMatND( CvMatND** mat );

mat

指向数组的双指针.

函数 cvReleaseMatND 缩减数组参考计数并释放数组头:

if( *mat )

cvDecRefData( *mat );

cvFree( (void**)mat );

InitMatNDHeader

初始化多维数组头

CvMatND* cvInitMatNDHeader( CvMatND* mat, int dims, const int* sizes, int type, void* data=NULL );

mat

指向要被出初始化的数组头指针.

dims

数组维数.

sizes

维大小.

type

数组元素类型. 与 CvMat相同

data

可选的分配给矩阵头的数据指针.

函数 cvInitMatNDHeader 初始化 用户指派的CvMatND 结构.

CloneMatND

创建多维数组的完整拷贝

CvMatND* cvCloneMatND( const CvMatND* mat );

mat

输入数组

函数 cvCloneMatND 创建输入数组的拷贝并返回指针.

DecRefData

缩减数组数据的引用计数

void cvDecRefData( CvArr* arr );

arr

数组头.

如果引用计数指针非NULL,函数 cvDecRefData 缩减CvMat 或CvMatND 数据的引用计数,如果计数到0就删除数据。在当前的版本中只有当数据是用cvCreateData 分配的引用计数才会是非NULL。在其他的情况下比如:

· 使用cvSetData指派外部数据给矩阵头;

· 代表部分大的矩阵或图像的矩阵头;

· 是从图像头或N维矩阵头转换过来的矩阵头,

在这些情况下引用计数被设置成NULL因此不会被缩减。无论数据是否被删除,数据指针和引用计数指针都将被这个函数清空。

IncRefData

增加数组数据的引用计数

int cvIncRefData( CvArr* arr );

arr

数组头.

函数 cvIncRefData 增加 CvMat 或 CvMatND 数据引用计数,如果引用计数非空返回新的计数值 否则返回0。

CreateData

分配数组数据

void cvCreateData( CvArr* arr );

arr

数组头.

函数 cvCreateData 分配图像,矩阵或多维数组数据. 对于矩阵类型使用OpenCV的分配函数,对于 IplImage类型如果CV_TURN_ON_IPL_COMPATIBILITY没有被调用也是可以使用这种方法的反之使用 IPL 函数分配数据

ReleaseData

释放数组数据

void cvReleaseData( CvArr* arr );

arr

数组头

函数cvReleaseData 释放数组数据. 对于 CvMat 或 CvMatND 结构只需调用 cvDecRefData(), 也就是说这个函数不能删除外部数据。见 cvCreateData.

SetData

指派用户数据给数组头

void cvSetData( CvArr* arr, void* data, int step );

arr

数组头.

data

用户数据.

step

整行字节长.

函数cvSetData 指派用户数据给数组头. 头应该已经使用 cvCreate*Header, cvInit*Header 或 cvMat (对于矩阵)初始化过.

GetRawData

返回数组的底层信息

void cvGetRawData( const CvArr* arr, uchar** data,

int* step=NULL, CvSize* roi_size=NULL );

arr

数组头.

data

输出指针,指针指向整个图像的结构或ROI

step

输出行字节长

roi_size

输出ROI尺寸

函数 cvGetRawData 添充给输出变量数组的底层信息。所有的输出参数是可选的, 因此这些指针可设为NULL。如果数组是设置了ROI的 IplImage 结构, ROI参数被返回。

注意:输出指针指向数组头的对应的内存,不能释放。建议用memcpy。

接下来的例子展示怎样利用这个函数去访问数组元素。

使用 GetRawData 计算单通道浮点数组的元素绝对值。

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]);

GetMat

从不确定数组返回矩阵头

CvMat* cvGetMat( const CvArr* arr, CvMat* header, int* coi=NULL, int allowND=0 );

arr

输入数组.

header

指向 CvMat结构的指针,作为临时缓存 .

coi

可选的输出参数,用于输出COI.

allowND

如果非0,函数就接收多维密集数组 (CvMatND*)并且返回 2D (如果 CvMatND 是二维的)或 1D 矩阵(当 CvMatND 是一维或多于二维). 数组必须是连续的.

函数 cvGetMat从输入的数组生成矩阵头,输入的数组可以是 - CvMat结构, IplImage结构 或多维密集数组 CvMatND* (后者只有当 allowND != 0时才可以使用) . 如果是矩阵函数只是返回指向矩阵的指针.如果是 IplImage* 或 CvMatND* 函数用当前图像的ROI初始化头结构并且返回指向这个临时结构的指针。因为CvMat不支持COI,所以他们的返回结果是不同的.

这个函数提供了一个简单的方法,用同一代码处理 IplImage 和 CvMat二种数据类型。这个函数的反向转换可以用 cvGetImage将 CvMat 转换成 IplImage .

输入的数组必须有已分配好的底层数据或附加的数据,否则该函数将调用失败如果输入的数组是IplImage 格式,使用平面式数据编排并设置了COI,函数返回的指针指向被选定的平面并设置COI=0.利用OPENCV函数对于多通道平面编排图像可以处理每个平面。

GetImage

从不确定数组返回图像头

IplImage* cvGetImage( const CvArr* arr, IplImage* image_header );

arr

输入数组.

image_header

指向IplImage结构的指针,该结构存贮在一个临时缓存 .

函数 cvGetImage 从输出数组获得图头,该数组可以是矩阵- CvMat*, 或图像 - IplImage*。如果是图像的话函数只是返回输入参数的指针,如果是 CvMat* 的话函数用输入参数矩阵初始化图像头。因此如果我们把 IplImage 转换成 CvMat 然后再转换 CvMat 回 IplImage,如果ROI被设置过了我们可能会获得不同的头,这样一些计算图像跨度的IPL函数就会失败。

CreateSparseMat

创建稀疏数组

CvSparseMat* cvCreateSparseMat( int dims, const int* sizes, int type );

dims

数组维数。相对于密集型矩阵,稀疏数组的维数是不受限制的(最多可达 216)。

sizes

数组的维大小。

type

数组元素类型,见 CvMat。

函数 cvCreateSparseMat 分配多维稀疏数组。刚初始化的数组不含元素,因此cvGet*D 或 cvGetReal*D函数对所有索引都返回0。

ReleaseSparseMat

删除稀疏数组

void cvReleaseSparseMat( CvSparseMat** mat );

mat

双指针指向数组。

函数 cvReleaseSparseMat释放稀疏数组并清空数组指针

CloneSparseMat

创建稀疏数组的拷贝

CvSparseMat* cvCloneSparseMat( const CvSparseMat* mat );

mat

输入数组。

函数 cvCloneSparseMat 创建输入数组的拷贝并返回指向这个拷贝的指针。

获取元素和数组子集

GetSubRect

返回输入的图像或矩阵的矩形数组子集的矩阵头

CvMat* cvGetSubRect( const CvArr* arr, CvMat* submat, CvRect rect );

arr

输入数组。

submat

指向矩形数组子集矩阵头的指针。

rect

以0坐标为基准的ROI。

函数 cvGetSubRect 根据指定的数组矩形返回矩阵头,换句话说,函数允许像处理一个独立数组一样处理输入数组的一个指定子矩形。函数在处理时要考虑进输入数组的ROI,因此数组的ROI是实际上被提取的。

GetRow, GetRows

返回数组的一行或在一定跨度内的行

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 );

arr

输入数组。

submat

指向返回的子数组头的指针。

row

被选定行的索引下标,索引下标从0开始。

start_row

跨度的开始行(包括此行)索引下标,索引下标从0开始。

end_row

跨度的结束行(不包括此行)索引下标,索引下标从0开始。

delta_row

在跨度内的索引下标跨步,从开始行到结束行每隔delta_row行提取一行。

函数GetRow 和 GetRows 返回输入数组中指定的一行或在一定跨度内的行对应的数组头。 注意GetRow 实际上是以下cvGetRows调用的简写:

cvGetRow( arr, submat, row ) ~ cvGetRows( arr, submat, row, row + 1, 1 );

GetCol, GetCols

返回数组的一列或一定跨度内的列

CvMat* cvGetCol( const CvArr* arr, CvMat* submat, int col );

CvMat* cvGetCols( const CvArr* arr, CvMat* submat, int start_col, int end_col );

arr

输入数组。

submat

指向结果子数组头的指针。

col

被选定列的索引下标,索引下标从0开始。

start_col

跨度的开始列(包括该列)索引下标,索引下标从0开始。

end_col

跨度的结束列(不包括该列)索引下标,索引下标从0开始。

函数 GetCol 和 GetCols 根据指定的列/列跨度返回对应的数组头。注意GetCol 实际上是以下 cvGetCols调用的简写形式:

cvGetCol( arr, submat, col ); // ~ cvGetCols( arr, submat, col, col + 1 );

GetDiag

返回一个数组对角线

CvMat* cvGetDiag( const CvArr* arr, CvMat* submat, int diag=0 );

arr

输入数组.

submat

指向结果子集的头指针.

diag

数组对角线。0是主对角线,-1是主对角线上面对角线,1是主对角线下对角线,以此类推。

函数 cvGetDiag 根据指定的diag参数返回数组的对角线头。

GetSize

返回矩阵或图像ROI的大小

CvSize cvGetSize( const CvArr* arr );

arr

数组头。

函数 cvGetSize 返回图像或矩阵的行数和列数,如果是图像就返回ROI的大小。

InitSparseMatIterator

初始化稀疏数组元素迭代器

CvSparseNode* cvInitSparseMatIterator( const CvSparseMat* mat,

CvSparseMatIterator* mat_iterator );

mat

输入的数组.

mat_iterator

被初始化的迭代器.

函数 cvInitSparseMatIterator 初始化稀疏数组元素的迭代器并且返回指向第一个元素的指针,如果数组为空则返回NULL。

GetNextSparseNode

初始化稀疏数组元素迭代器

CvSparseNode* cvGetNextSparseNode( CvSparseMatIterator* mat_iterator );

mat_iterator

稀疏数组的迭代器

函数cvGetNextSparseNode 移动迭代器到下一个稀疏矩阵元素并返回指向他的指针。在当前的版本不存在任何元素的特殊顺序,因为元素是按HASH表存贮的下面的列子描述怎样在稀疏矩阵上迭代 :

利用cvInitSparseMatIterator 和cvGetNextSparseNode 计算浮点稀疏数组的和。

double sum;

int i, dims = cvGetDims( array );

CvSparseMatIterator mat_iterator;

CvSparseNode* node = cvInitSparseMatIterator( array, &mat_iterator );

 

for( ; node != 0; node = cvGetNextSparseNode( &mat_iterator ))

{

int* idx = CV_NODE_IDX( array, node );

float val = *(float*)CV_NODE_VAL( array, node );

printf( "(" );

for( i = 0; i < dims; i++ )

printf( "M%s", idx[i], i < dims - 1 ? "," : "): " );

printf( "%g\n", val );

 

sum += val;

 

 

printf( "\nTotal sum = %g\n", sum );

GetElemType

返回数组元素类型

int cvGetElemType( const CvArr* arr );

arr

输入数组.

函数 GetElemType 返回数组元素类型就像在cvCreateMat 中讨论的一样:

CV_8UC1 ... CV_64FC4

GetDims, GetDimSize

返回数组维数和他们的大小或者特殊维的大小

int cvGetDims( const CvArr* arr, int* sizes=NULL );

int cvGetDimSize( const CvArr* arr, int index );

arr

输入数组.

sizes

可选的输出数组维尺寸向量,对于2D数组第一位是数组行数(高),第二位是数组列数(宽)

index

以0为基准的维索引下标(对于矩阵0意味着行数,1意味着列数,对于图象0意味着高,1意味着宽。

函数 cvGetDims 返回维数和他们的大小。如果是 IplImage 或 CvMat 总是返回2,不管图像/矩阵行数。函数 cvGetDimSize 返回特定的维大小(每维的元素数)。例如,接下来的代码使用二种方法计算数组元素总数。

// 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 );

 

Ptr*D

返回指向特殊数组元素的指针

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, int* idx, int* type=NULL, int create_node=1, unsigned* precalc_hashval=NULL );

arr

输入数组.

idx0

元素下标的第一个以0为基准的成员

idx1

元素下标的第二个以0为基准的成员

idx2

元素下标的第三个以0为基准的成员

idx

数组元素下标

type

可选的,矩阵元素类型输出参数

create_node

可选的,为稀疏矩阵输入的参数。如果这个参数非零就意味着被需要的元素如果不存在就会被创建。

precalc_hashval

可选的,为稀疏矩阵设置的输入参数。如果这个指针非NULL,函数不会重新计算节点的HASH值,而是从指定位置获取。这种方法有利于提高智能组合数据的操作(TODO: 提供了一个例子)

函数cvPtr*D 返回指向特殊数组元素的指针。数组维数应该与转递给函数物下标数相匹配,除了 cvPtr1D 函数,它可以被用于顺序存取的1D,2D或nD密集数组

函数也可以用于稀疏数组,并且如果被需要的节点不存在函数可以创建这个节点并设置为0

就像其它获取数组元素的函数 (cvGet[Real]*D, cvSet[Real]*D)如果元素的下标超出了范围就会产生错误

Get*D

返回特殊的数组元素

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, int* idx );

arr

输入数组.

idx0

元素下标第一个以0为基准的成员

idx1

元素下标第二个以0为基准的成员

idx2

元素下标第三个以0为基准的成员

idx

元素下标数组

函数cvGet*D 返回指定的数组元素。对于稀疏数组如果需要的节点不存在函数返回0 (不会创建新的节点)

GetReal*D

返回单通道数组的指定元素

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, int* idx );

arr

输入数组,必须是单通道.

idx0

元素下标的第一个成员,以0为基准

idx1

元素下标的第二个成员,以0为基准

idx2

元素下标的第三个成员,以0为基准

idx

元素下标数组

函数cvGetReal*D 返回单通道数组的指定元素,如果数组是多通道的,就会产生运行时错误,而 cvGet*D 函数可以安全的被用于单通道和多通道数组,但他们运行时会有点慢

如果指定的点不存在对于稀疏数组点会返回0(不会创建新的节点)。

mGet

返回单通道浮点矩阵指定元素

double cvmGet( const CvMat* mat, int row, int col );

mat

输入矩阵.

row

行下标,以0为基点.

col

列下标,以0为基点

函数 cvmGet 是 cvGetReal2D对于单通道浮点矩阵的快速替代函数,函数运行比较快速因为它是内连函数,这个函数对于数组类型、数组元素类型的检查作的很少,并且仅在调式模式下检查数的行和列范围。

Set*D

修改指定的数组

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, int* idx, CvScalar value );

arr

输入数组

idx0

元素下标的第一个成员,以0为基点

idx1

元素下标的第二个成员,以0为基点

idx2

元素下标的第三个成员,以0为基点

idx

元素下标数组

value

指派的值

函数 cvSet*D 指定新的值给指定的数组元素。对于稀疏矩阵如果指定节点不存在函数创建新的节点

SetReal*D

修改指定数组元素值

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, int* idx, double value );

arr

输入数组.

idx0

元素下标的第一个成员,以0为基点

idx1

元素下标的第二个成员,以0为基点

idx2

元素下标的第三个成员,以0为基点

idx

元素下标数组

value

指派的值

函数 cvSetReal*D 分配新的值给单通道数组的指定元素,如果数组是多通道就会产生运行时错误。然而cvSet*D 可以安全的被用于多通道和单通道数组,只是稍微有点慢。

对于稀疏数组如果指定的节点不存在函数会创建该节点。

mSet

为单通道浮点矩阵的指定元素赋值。

void cvmSet( CvMat* mat, int row, int col, double value );

mat

矩阵.

row

行下标,以0为基点.

col

列下标,以0为基点.

value

矩阵元素的新值

函数cvmSet 是cvSetReal2D 快速替代,对于单通道浮点矩阵因为这个函数是内连的所以比较快,函数对于数组类型、数组元素类型的检查作的很少,并且仅在调式模式下检查数的行和列范围。

 

 

ClearND

清除指定数组元素

void cvClearND( CvArr* arr, int* idx );

arr

输入数组.

idx

数组元素下标

函数cvClearND 清除指定密集型数组的元素(置0)或删除稀疏数组的元素 ,如果元素不存在函数不作任何事

拷贝和添加

Copy

拷贝一个数组给另一个数组

void cvCopy( const CvArr* src, CvArr* dst, const CvArr* mask=NULL );

src

输入数组。

dst

输出数组。

mask

操作掩码是8比特单通道的数组,它指定了输出数组中被改变的元素。

函数cvCopy从输入数组中复制选定的成分到输出数组:

如果mask(I)!=0,则dst(I)=src(I)。

如果输入输出数组中的一个是IplImage类型的话,其ROI和COI将被使用。输入输出数组必须是同样的类型、维数和大小。函数也可以用来复制散列数组(这种情况下不支持mask)。

Set

设置数组所有元素为指定值

void cvSet( CvArr* arr, CvScalar value, const CvArr* mask=NULL );

arr

输出数组。

value

填充值。

mask

操作掩码是8比特单通道的数组,它指定了输出数组中被改变的元素。

函数 cvSet 拷贝数量值到输出数组的每一个被除数选定的元素:

arr(I)=value if mask(I)!=0

如果数组 arr 是 IplImage 类型, 那么就会使用ROI,但COI不能设置。

SetZero

清空数组

void cvSetZero( CvArr* arr );

#define cvZero cvSetZero

arr

要被清空数组.

函数 cvSetZero 清空数组. 对于密集型号数组(CvMat, CvMatND or IplImage) cvZero(array) 就相当于 cvSet(array,cvScalarAll(0),0), 对于稀疏数组所有的元素都将被删除.

 

SetIdentity

初始化带尺度的单位矩阵

void cvSetIdentity( CvArr* mat, CvScalar value=cvRealScalar(1) );

mat

待初始化的矩阵 (不一定是方阵)。

value

赋值给对角线元素的值。

函数 cvSetIdentity 初始化带尺度的单位矩阵:

arr(i,j)=value 如果 i=j,

否则为 0

Range

用指定范围的数来填充矩阵.

void cvRange( CvArr* mat, double start, double end );

mat

即将被初始化的矩阵,必须是指向单通道的32位(整型或浮点型)的矩阵的指针.

start

指定范围的最小边界

end

指定范围的最大边界

该函数按以下方式初始化矩阵:

arr(i,j)=(end-start)*(i*cols(arr)+j)/(cols(arr)*rows(arr))

例如:以下的代码将按相应的整型数初始化一维向量:

CvMat* A = cvCreateMat( 1, 10, CV_32S ); cvRange( A, 0, A->cols ); //A将被初始化为[0,1,2,3,4,5,6,7,8,9]


转自 http://blog.csdn.net/wangjie0377/article/details/6629293


 


集合


 


CvSet


Collection of nodes


typedef struct CvSetElem


{


int flags;


struct CvSetElem* next_free;


}


CvSetElem;


 


#define CV_SET_FIELDS() \


CV_SEQUENCE_FIELDS() \


struct CvSetElem* free_elems;


 


typedef struct CvSet


{


CV_SET_FIELDS()


} CvSet;


在 OpenCV 的稀疏数据结构中, CvSet 是一基本结构。


从上面的声明中可知:CvSet 继承自 CvSeq, 并在此基础上增加了个 free_elems 域,该域是空节点组成的列表。集合中的每一个节点,无论空否,都是线性表中的一个元素。尽管对于稠密的表中的元素没有限制,集合(派生的结构)元素必须起始于整数域,并与结构 CvSetElem 相吻合,因为这两个域对于(由空节点组成)集合的组织是必要的。如果节点为空,flags 为负,next_free 指向下一个空节点。如果节点已被占据空间,flags 为正, flags 包含节点索引值(使用表达式 set_elem->flags & CV_SET_ELEM_IDX_MASKH 获取), flags 的剩馀内容由用户决定。宏 CV_IS_SET_ELEM(set_elem.ptr)用来识别特定的节点是否为空。


起初,集合 set 同表 list 都为空。当需要一个来自集合中的新节点时,就从表 list 中去获取,然后表进行了更新。如果表 list 碰巧为空,于是就分配一内存块,块中的所有节点与表 list 相连。结果,集合的 total 域被设置为空节点和非空节点的和。当非空节点别释放后,就将它加到空节点列表中。最先被释放的节点也就是最先被占用空间的节点


在 OpenCV 中, CvSet 用来代表图形(CvGraph), 稀疏多维数组(CvSparseMat), 平面子划分(planner subdivisions)等


 


CreateSet


创建空的数据集


CvSet* cvCreateSet( int set_flags, int header_size,


int elem_size, CvMemStorage* storage );


set_flags


集合的类型


header_size


头节点的大小;应该等于 sizeof(CvSet)


elem_size


元素的大小;不能小8


storage


相关容器


函数 CvCreateSet 创建一具有特定头部节点大小和元素类型的空集。并返回指向该集合的指针。


 


SetAdd


占用集合中的一个节点


int cvSetAdd( CvSet* set_header, CvSetElem* elem=NULL, CvSetElem** inserted_elem=NULL );


set_header


集合


elem


可选的输入参数,被插入的元素。如果不为 NULL, 函数就将数据拷贝到新分配的节点。(拷贝后,清空第一个域的 MSB)


函数 cvSetAdd 分配一新的节点,将输入数据拷贝给它(可选),并且返回指向该节点的指针和节点的索引值。索引值可通过节点的flags域的低位中获得。函数的时间复杂度为 O(1), 不过,存在着一个函数可快速的分配内存。(见 cvSetNew)


 


SetRemove


从点集中删除元素


void cvSetRemove( CvSet* set_header, int index );


set_header


集合


index


被删元素的索引值


函数 cvSetRemove 从点集中删除一具有特定索引值的元素。如果指定位置的节点为空,函数将什么都不做。函数的时间复杂度为 O(1), 不过,存在一函数可更快速的完成该操作,该函数就是 cvSetRemoveByPtr


 


SetNew


添加元素到点集中


CvSetElem* cvSetNew( CvSet* set_header );


set_header


集合


函数 cvSetNew 是 cvSetAdd 的变体,内联函数。它占用一新节点,并返回指向该节点的指针而不是索引。


 


SetRemoveByPtr


删除指针指向的集合元素


void cvSetRemoveByPtr( CvSet* set_header, void* elem );


set_header


集合


elem


被删除的元素


函数 cvSetRemoveByPtr 是一内联函数,是函数 cvSetRemove 轻微变化而来的。该函数并不会检查节点是否为空 -- 用户负责这一检查。


 


GetSetElem


通过索引值查找相应的集合元素


CvSetElem* cvGetSetElem( const CvSet* set_header, int index );


set_header


集合


index


索引值


函数 cvGetSetElem 通过索引值查找相应的元素。函数返回指向该元素的指针,如果索引值无效或相应的节点为空,则返回 0。 若函数使用 cvGetSeqElem 去查找节点,则函数支持负的索引值。


 


ClearSet


清空点集


void cvClearSet( CvSet* set_header );


set_header


待清空的点集


函数 cvClearSet 删除集合中的所有元素。时间复杂度为 O(1).


 


 



 


CvGraph


有向权图和无向权图


#define CV_GRAPH_VERTEX_FIELDS() \


int flags; \


struct CvGraphEdge* first;


 


typedef struct CvGraphVtx


{


CV_GRAPH_VERTEX_FIELDS()


}


CvGraphVtx;


 


#define CV_GRAPH_EDGE_FIELDS() \


int flags; \


float weight; \


struct CvGraphEdge* next[2]; \


\


struct CvGraphVtx* vtx[2];


 


typedef struct CvGraphEdge


{


CV_GRAPH_EDGE_FIELDS()


}


CvGraphEdge;


 


#define CV_GRAPH_FIELDS() \


CV_SET_FIELDS() \


CvSet* edges;


 


typedef struct CvGraph


{


CV_GRAPH_FIELDS()


}


CvGraph;


在 OpenCV 图形结构中,CvGraph 是一基本结构。


图形结构继承自 CvSet -- 该部分描绘了普通图的属性和图的顶点,也包含了一个点集作为其成员 -- 该点集描述了图的边缘。利用宏(可以简化结构扩展和定制)使用与其它OpenCV可扩展结构一样的方法和技巧,同样的方法和技巧,我们声明了定点,边和头部结构。虽然顶点结构和边结构无法从CvSetElem 显式地继承时,但它们满足点集元素的两个条件(在开始是有一个整数域和满足 CvSetElem 结构)。 flags 域用来标记顶点和边是否已被占用或者处于其他目的,如:遍历图时(见:cvStartScanGraph 等),因此最好不要去直接使用它们。图代表的就是边的集合。存在有向和无向的区别。对于后者(无向图),在连接顶点 A 到 顶点 B 的边同连接顶点 B 到 顶点 A的边是没什么区别的,在某一时刻,只可能存在一个,即:要么是<A, B>要么是<B, A>.


 


CreateGraph


创建一个空树


CvGraph* cvCreateGraph( int graph_flags, int header_size, int vtx_size,


int edge_size, CvMemStorage* storage );


graph_flags


被创建的图的类型。通常,无向图为 CV_SEQ_KIND_GRAPH,有向图为 CV_SEQ_KIND_GRAPH | CV_GRAPH_FLAG_ORIENTED.


header_size


头部大小;可能小于 sizeof(CvGraph)


vtx_size


顶点大小;常规的定点结构必须来自 CvGraphVtx (使用宏 CV_GRAPH_VERTEX_FIELDS())


edge_size


边的大小;常规的边结构必须来自 CvGraphEdge (使用宏 CV_GRAPH_EDGE_FIELDS())


storage


图的容器


函数 cvCreateGraph 创建一空图并且返回指向该图的指针。


 


GraphAddVtx


插入一顶点到图中


int cvGraphAddVtx( CvGraph* graph, const CvGraphVtx* vtx=NULL,


CvGraphVtx** inserted_vtx=NULL );


graph



vtx


可选输入参数,用来初始化新加入的顶点(仅大小超过 sizeof(CvGraphVtx) 的用户自定义的域才会被拷贝)


inserted_vertex


可选的输出参数。如果不为 NULL, 则传回新加入顶点的地址


函数 cvGraphAddVtx 将一顶点加入到图中,并返回定点的索引


 


GraphRemoveVtx


通过索引从图中删除一顶点


int cvGraphRemoveVtx( CvGraph* graph, int index );


graph



vtx_idx


被珊顶点的索引


函数 cvGraphRemoveAddVtx 从图中删除一顶点,连同删除含有此顶点的边。如果输入的顶点不属于该图的话,将报告删除出错(不存在而无法删除)。返回值为被删除的边数,如果顶点不属于该图的话,返回 -1。


 


GraphRemoveVtxByPtr


通过指针从图中删除一顶点


int cvGraphRemoveVtxByPtr( CvGraph* graph, CvGraphVtx* vtx );


graph



vtx


指向被删除的边的指针


函数 cvGraphRemoveVtxByPtr 从图中删除一顶点,连同删除含有此顶点的边。如果输入的顶点不属于该图的话,将报告删除出错(不存在而无法删除)。返回值为被删除的边数,如果顶点不属于该图的话,返回 -1。


 


GetGraphVtx


通过索引值查找图的相应顶点


CvGraphVtx* cvGetGraphVtx( CvGraph* graph, int vtx_idx );


graph



vtx_idx


定点的索引值


函数 cvGetGraphVtx 通过索引值查找对应的顶点,并返回指向该顶点的指针,如果不存在则返回 NULL.


 


GraphVtxIdx


返回定点相应的索引值


int cvGraphVtxIdx( CvGraph* graph, CvGraphVtx* vtx );


graph



vtx


指向顶点的指针


函数 cvGraphVtxIdx 返回与顶点相应的索引值


 


GraphAddEdge


通过索引值在图中加入一条边


int cvGraphAddEdge( CvGraph* graph, int start_idx, int end_idx,


const CvGraphEdge* edge=NULL, CvGraphEdge** inserted_edge=NULL );


graph



start_idx


边的起始顶点的索引值


end_idx


边的尾部顶点的索引值(对于无向图,参数的次序无关紧要,即:start_idx 和 end_idx 可互为起始顶点和尾部顶点)


edge


可选的输入参数,初始化边的数据


inserted_edge


可选的输出参数,包含被插入的边的地址。


函数 cvGraphAddEdge 连接两特定的顶点。如果该边成功地加入到图中,返回 1; 如果连接两顶点的边已经存在,返回 0;如果顶点没被发现(不存在)或者起始顶点和尾部顶点是同一个定点,或其他特殊情况,返回 -1。如果是后者(即:返回值为负),函数默认的报告一个错误。


 


GraphAddEdgeByPtr


通过指针在图中加入一条边


int cvGraphAddEdgeByPtr( CvGraph* graph, CvGraphVtx* start_vtx, CvGraphVtx* end_vtx,


const CvGraphEdge* edge=NULL, CvGraphEdge** inserted_edge=NULL );


graph



start_vtx


指向起始顶点的指针


end_vtx


指向尾部顶点的指针。对于无向图来说,顶点参数的次序无关紧要。


edge


可选的输入参数,初始化边的数据


inserted_edge


可选的输出参数,包含被插入的边的地址。


函数 cvGraphAddEdge 连接两特定的顶点。如果该边成功地加入到图中,返回 1; 如果连接两顶点的边已经存在,返回 0;如果顶点没被发现(不存在)或者起始顶点和尾部顶点是同一个定点,或其他特殊情况,返回 -1。如果是后者(即:返回值为负),函数默认的报告一个错误


 


GraphRemoveEdge


通过索引值从图中删除顶点


void cvGraphRemoveEdge( CvGraph* graph, int start_idx, int end_idx );


graph



start_idx


起始顶点的索引值


end_idx


尾部顶点的索引值。对于无向图来说,顶点参数的次序无关紧要。


函数 cvGraphRemoveEdge 删除连接两特定顶点的边。若两顶点并没有相连接(即:不存在由这两个顶点连接的边),函数什么都不做。


 


GraphRemoveEdgeByPtr


通过指针从图中删除边


void cvGraphRemoveEdgeByPtr( CvGraph* graph, CvGraphVtx* start_vtx, CvGraphVtx* end_vtx );


graph



start_vtx


指向起始顶点的指针


end_vtx


指向尾部顶点的指针。对于无向图来说,顶点参数的次序无关紧要。


函数 cvGraphRemoveEdgeByPtr 删除连接两特定顶点的边。若两顶点并没有相连接(即:不存在由这两个顶点连接的边),函数什么都不做。


 


FindGraphEdge


通过索引值在图中查找相应的边


CvGraphEdge* cvFindGraphEdge( const CvGraph* graph, int start_idx, int end_idx );


#define cvGraphFindEdge cvFindGraphEdge


graph



start_idx


起始顶点的索引值


end_idx


尾部顶点的索引值。对于无向图来说,顶点参数的次序无关紧要


函数 cvFindGraphEdge 查找与两特定顶点相对应的边,并返回指向该边的指针。如果该边不存在,返回 NULL.


 


FindGraphEdgeByPtr


通过指针在图中查找相应的边


CvGraphEdge* cvFindGraphEdgeByPtr( const CvGraph* graph, const CvGraphVtx* start_vtx,


const CvGraphVtx* end_vtx );


#define cvGraphFindEdgeByPtr cvFindGraphEdgeByPtr


graph



start_vtx


指向起始顶点的指针


end_vtx


指向尾部顶点的指针。对于无向图来说,顶点参数的次序无关紧要。


函数 cvFindGraphEdgeByPtr 查找与两特定顶点相对应的边,并返回指向该边的指针。如果该边不存在,返回 NULL


 


GraphEdgeIdx


返回与该边相应的索引值


int cvGraphEdgeIdx( CvGraph* graph, CvGraphEdge* edge );


graph



edge


指向该边的指针


函数 cvGraphEdgeIdx 返回与边对应的索引值。


 


GraphVtxDegree


(通过索引值)统计与顶点相关联的边数


int cvGraphVtxDegree( const CvGraph* graph, int vtx_idx );


graph



vtx_idx


顶点对应的索引值


函数 cvGraphVtxDegree 返回与特定顶点相关联的边数,包括以该顶点为起始顶点的和尾部顶点的。统计边数,可以适用下列代码:


CvGraphEdge* edge = vertex->first; int count = 0;


while( edge )


{


edge = CV_NEXT_GRAPH_EDGE( edge, vertex );


count++;


}


宏 CV_NEXT_GRAPH_EDGE(edge, vertex) 返回依附于该顶点的下一条边。 


 


GraphVtxDegreeByPtr


(通过指针)统计与顶点相关联的边数


int cvGraphVtxDegreeByPtr( const CvGraph* graph, const CvGraphVtx* vtx );


graph



vtx


顶点对应的指针


函数 cvGraphVtxDegreeByPtr 返回与特定顶点相关联的边数,包括以该顶点为起始顶点的和尾部顶点的


 


ClearGraph


删除图


void cvClearGraph( CvGraph* graph );


graph



函数 cvClearGraph 删除该图的所有顶点和边。时间复杂度为 O(1).


 


CloneGraph


克隆图


CvGraph* cvCloneGraph( const CvGraph* graph, CvMemStorage* storage );


graph


待拷贝的图


storage


容器,存放拷贝


函数 cvCloneGraph 创建图的完全拷贝。如果顶点和边含有指向外部变量的指针,那么图和它的拷贝共享这些指针。在新的图中,顶点和边可能存在不同,因为函数重新分割了顶点和边的点集。


 


CvGraphScanner


图的遍历


typedef struct CvGraphScanner


{


CvGraphVtx* vtx;


CvGraphVtx* dst;


CvGraphEdge* edge;


 


CvGraph* graph;


CvSeq* stack;


int index;


int mask;


}


CvGraphScanner;


结构 cvGraphScanner 深度遍历整个图。函数的相关讨论如下(看:StartScanGraph)  


 


StartScanGraph


创建一结构,用来对图进行深度遍历


CvGraphScanner* cvCreateGraphScanner( CvGraph* graph, CvGraphVtx* vtx=NULL,


int mask=CV_GRAPH_ALL_ITEMS );


graph



vtx


开始遍历的(起始)顶点。如果为 NULL, 便利就从第一个顶点开始(指:顶点序列中,具有最小索引值的顶点)


mask


事件掩码(event mask)代表用户感兴趣的事件(此时 函数 cvNextGraphItem 将控制返回给用户)。这个只可能是 CV_GRAPH_ALL_ITEMS (如果用户对所有的事件都感兴趣的话)或者是下列标志的组合:


CV_GRAPH_VERTEXT -- 在第一次被访问的顶点处停下


CV_GRAPH_TREE_EDGE -- 在 tree edge 处停下(tree edge 指连接最后被访问的顶点与接下来被访问的顶点的边)


CV_GRAPH_BACK_EDGE -- 在 back edge 处停下(back edge 指连接最后被访问的顶点与其在搜索树中祖先的边)


CV_GRAPH_FORWARD_EDGE -- 在 forward edge 处停下 (forward edge 指连接最后被访问的顶点与其在搜索树中后裔的边)


CV_GRAPH_CROSS_EDGE -- 在 cross edge 处停下(cross edge 指连接不同搜索树中或同一搜索树中不同分支的边.只有在有向图中,才存在着一概念)


CV_GRAPH_ANY_EDGE -- 在 any edge 处停下(any edge 指 任何边,包括 tree edge, back edge, forward edge, cross edge)


CV_GRAPH_NEW_TREE -- 在每一个新的搜索树开始处停下。首先遍历从起始顶点开始可以访问到的顶点和边,然后查找搜索图中访问不到的顶点或边并恢复遍历。在开始遍历一颗新的树时(包括第一次调用 cvNextGraphItem 时的树),产生 CV_GRAPH_NEW_TREE 事件。


函数 cvCreateGraphScanner 创建一结构用来深度遍历搜索树。函数 cvNextGraphItem 要使用该初始化了的结构 -- 层层遍历的过程。


 


NextGraphItem


逐层遍历整个图


int cvNextGraphItem( CvGraphScanner* scanner );


scanner


图的遍历状态。被此函数更新。


函数 cvNextGraphItem 遍历整个图,直到用户感兴趣的事件发生(即:调用 cvCreateGraphScanner 时, mask 对应的事件)或遍历结束。在前面一种情况下,函数返回 参数mask 相应的事件,当再次调用函数时,恢复遍历)。在后一种情况下,返回 CV_GRAPH_OVER(-1)。当 mask 相应的事件为 CV_GRAPH_BACKTRACKING 或 CV_GRAPH_NEW_TEEE 时, 当前正在被访问的顶点被存放在 scanner->vtx 中。如果事件与 边edge 相关,那幺 edge 本身被存放在 scanner->edge, 该边的起始顶点存放在 scanner->vtx 中, 尾部节点存放在 scanner->dst 中。


 


ReleaseGraphScanner


完成图地遍历过程


void cvReleaseGraphScanner( CvGraphScanner** scanner );


scanner


指向遍历器的指针.


函数 cvGraphScanner 完成图的遍历过程,并释放遍历器的状态。


 



 


CV_TREE_NODE_FIELDS


用于树结点类型声明的(助手)宏


#define CV_TREE_NODE_FIELDS(node_type) \


int flags; \


int header_size; \


struct node_type* h_prev; \


struct node_type* h_next; \


struct node_type* v_prev; \


struct node_type* v_next;


宏 CV_TREE_NODE_FIELDS() 用来声明一层次性结构,例如 CvSeq -- 所有动态结构的基本类型。如果树的节点是由该宏所声明的,那么就可以使用(该部分的)以下函数对树进行相关操作。


 


CvTreeNodeIterator


打开现存的存储结构或者创建新的文件存储结构


typedef struct CvTreeNodeIterator


{


const void* node;


int level;


int max_level;


}


CvTreeNodeIterator;


结构 CvTreeNodeIterator 用来对树进行遍历。该树的节点是由宏 CV_TREE_NODE_FIELDS 声明。


 


InitTreeNodeIterator


用来初始化树结点的迭代器


void cvInitTreeNodeIterator( CvTreeNodeIterator* tree_iterator,


const void* first, int max_level );


tree_iterator


初始化了的迭代器


first


(开始)遍历的第一个节点


max_level


限制对树进行遍历的最高层(即:第 max_level 层)(假设第一个节点所在的层为第一层)。例如:1 指的是遍历第一个节点所在层,2 指的是遍历第一层和第二层


函数 cvInitTreeNodeIterator 用来初始化树的迭代器。


 


NextTreeNode


返回当前节点,并将迭代器 iterator 移向当前节点的下一个节点


void* cvNextTreeNode( CvTreeNodeIterator* tree_iterator );


tree_iterator


初始化了的迭代器


函数 cvNextTreeNode 返回当前节点并且更新迭代器(iterator) -- 并将 iterator 移向(当前节点)下一个节点。换句话说,函数的行为类似于表达式 *p++ (通常的 C 指针 或 C++ 集合迭代器)。如果没有更多的节点(即:当前节点为最后的节点),则函数返回值为 NULL.


 


PrevTreeNode


返回当前节点,并将迭代器 iterator 移向当前节点的前一个节点


void* cvPrevTreeNode( CvTreeNodeIterator* tree_iterator );


tree_iterator


初始化了的迭代器


函数 cvPrevTreeNode 返回当前节点并且更新迭代器(iterator) -- 并将 iterator 移向(当前节点的)前一个节点。换句话说,函数的行为类似于表达式 *p-- (通常的 C 指针 或 C++ 集合迭代器)。如果没有更多的节点(即:当前节点为头节点),则函数返回值为 NULL.


 


TreeToNodeSeq


将所有的节点指针(即:指向树结点的指针)收集到线性表 sequence 中


CvSeq* cvTreeToNodeSeq( const void* first, int header_size, CvMemStorage* storage );


first


初始树结点


header_size


线性表的表头大小,大小通常为 sizeof(CvSeq)


函数 cvTreeToNodeSeq 将树的节点指针挨个的存放到线性表中。存放的顺序以深度为先。


 


InsertNodeIntoTree


将新的节点插入到树中


void cvInsertNodeIntoTree( void* node, void* parent, void* frame );


node


待插入的节点


parent


树中的父节点(即:含有子节点的节点)


frame


顶部节点。如果节点parent 等同于节点frame, 则将节点的域 v_prev 设为 NULL 而不是 parent.


函数 cvInsertNodeIntoTree 将另一个节点插入到树中。函数不分配任何内存,仅仅修改树节点的连接关系。


 


RemoveNodeFromTree


从树中删除节点


void cvRemoveNodeFromTree( void* node, void* frame );


node


待删除的节点。


frame


顶部节点。如果 node->v.prev = NULL 且 node->h.prev = NULL, 则将 frame->v.next 设为 node->h.next


函数 cvRemoveNodeFromTree 从树中删除节点。它不会释放任何内存,仅仅修改树中节点的连接关系


 


曲线与形状


CV_RGB


创建一个色彩值.


#define CV_RGB( r, g, b ) cvScalar( (b), (g), (r) )


 


Line


绘制连接两个点的线段


void cvLine( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color,


int thickness=1, int line_type=8, int shift=0 );


img


图像。


pt1


线段的第一个端点。


pt2


线段的第二个端点。


color


线段的颜色。


thickness


线段的粗细程度。


line_type


线段的类型。


8 (or 0) - 8-connected line(8邻接)连接 线。


4 - 4-connected line(4邻接)连接线。


CV_AA - antialiased 线条。


shift


坐标点的小数点位数。


函数cvLine 在图像中的点1和点2之间画一条线段。线段被图像或感兴趣的矩形(ROI rectangle)所裁剪。对于具有整数坐标的non-antialiasing 线条,使用8-连接或者4-连接Bresenham 算法。画粗线条时结尾是圆形的。画 antialiased 线条使用高斯滤波。要指定线段颜色,用户可以使用使用宏CV_RGB( r, g, b )。


 


Rectangle


绘制简单、指定粗细或者带填充的矩形


void cvRectangle( CvArr* img, CvPoint pt1, CvPoint pt2, CvScalar color,


int thickness=1, int line_type=8, int shift=0 );


img


图像.


pt1


矩形的一个顶点。


pt2


矩形对角线上的另一个顶点


color


线条颜色 (RGB) 或亮度(灰度图像)(grayscale image)。


thickness


组成矩形的线条的粗细程度。取负值时(如 CV_FILLED)函数绘制填充了色彩的矩形。


line_type


线条的类型。见cvLine的描述


shift


坐标点的小数点位数。


 


函数 cvRectangle 通过对角线上的两个顶点绘制矩形。


 


Circle


绘制圆形。


void cvCircle( CvArr* img, CvPoint center, int radius, CvScalar color,


int thickness=1, int line_type=8, int shift=0 );


img


图像。


center


圆心坐标。


radius


圆形的半径。


color


线条的颜色。


thickness


如果是正数,表示组成圆的线条的粗细程度。否则,表示圆是否被填充。


line_type


线条的类型。见 cvLine 的描述


shift


圆心坐标点和半径值的小数点位数。


函数cvCircle绘制或填充一个给定圆心和半径的圆。圆被感兴趣矩形所裁剪。若指定圆的颜色,可以使用宏 CV_RGB ( r, g, b )。


 


Ellipse


绘制椭圆圆弧和椭圆扇形。


void cvEllipse( CvArr* img, CvPoint center, CvSize axes, double angle,


double start_angle, double end_angle, CvScalar color,


int thickness=1, int line_type=8, int shift=0 );


img


图像。


center


椭圆圆心坐标。


axes


轴的长度。


angle


偏转的角度。


start_angle


圆弧起始角的角度。.


end_angle


圆弧终结角的角度。


color


线条的颜色。


thickness


线条的粗细程度。


line_type


线条的类型,见CVLINE的描述。


shift


圆心坐标点和数轴的精度。


函数cvEllipse用来绘制或者填充一个简单的椭圆弧或椭圆扇形。圆弧被ROI矩形所忽略。反走样弧线和粗弧线使用线性分段近似值。所有的角都是以角度的形式给定的。下面的图片将解释这些参数的含义。


Parameters of Elliptic Arc


EllipseBox


使用一种简单的方式来绘制椭圆圆弧和椭圆扇形。


void cvEllipseBox( CvArr* img, CvBox2D box, CvScalar color,


int thickness=1, int line_type=8, int shift=0 );


img


图像。


box


绘制椭圆圆弧所需要的外界矩形.


thickness


分界线线条的粗细程度。


line_type


分界线线条的类型,见CVLINE的描述。


shift


椭圆框顶点坐标的精度。


The function cvEllipseBox draws a simple or thick ellipse outline, or fills an ellipse. The functions provides a convenient way to draw an ellipse approximating some shape; that is what cvCamShift and cvFitEllipse do. The ellipse drawn is clipped by ROI rectangle. A piecewise-linear approximation is used for antialiased arcs and thick arcs.


 


FillPoly


填充多边形内部


void cvFillPoly( CvArr* img, CvPoint** pts, int* npts, int contours,


CvScalar color, int line_type=8, int shift=0 );


img


图像。


pts


指向多边形的数组指针。


npts


多边形的顶点个数的数组。


contours


组成填充区域的线段的数量。


color


多边形的颜色。


line_type


组成多边形的线条的类型。


shift


顶点坐标的小数点位数。


函数cvFillPoly用于一个单独被多边形轮廓所限定的区域内进行填充。函数可以填充复杂的区域,例如,有漏洞的区域和有交叉点的区域等等。


 


FillConvexPoly


填充凸多边形


void cvFillConvexPoly( CvArr* img, CvPoint* pts, int npts,


CvScalar color, int line_type=8, int shift=0 );


img


图像。


pts


指向单个多边形的指针数组。


npts


多边形的顶点个数。


color


多边形的颜色。


line_type


组成多边形的线条的类型。参见cvLine


shift


顶点坐标的小数点位数。


 


函数cvFillConvexPoly填充凸多边形内部。这个函数比函数cvFillPoly 更快。它除了可以填充凸多边形区域还可以填充任何的单调多边形。例如:一个被水平线(扫描线)至多两次截断的多边形。


 


PolyLine


绘制简单线段或折线。


void cvPolyLine( CvArr* img, CvPoint** pts, int* npts, int contours, int is_closed,


CvScalar color, int thickness=1, int line_type=8, int shift=0 );


img


图像。


pts


折线的顶点指针数组。


npts


折线的定点个数数组。也可以认为是pts指针数组的大小


contours


折线的线段数量。


is_closed


指出多边形是否封闭。如果封闭,函数将起始点和结束点连线。


color


折线的颜色。


thickness


线条的粗细程度。


line_type


线段的类型。参见cvLine。


shift


顶点的小数点位数。


函数cvPolyLine 绘制一个简单直线或折线。


 


文本


 


InitFont


初始化字体结构体。


void cvInitFont( CvFont* font, int font_face, double hscale,


double vscale, double shear=0,


int thickness=1, int line_type=8 );


font


被初始化的字体结构体。


font_face


字体名称标识符。只是Hershey 字体集( http://sources.isc.org/utils/misc/hershey-font.txt )的一个子集得到支持。


CV_FONT_HERSHEY_SIMPLEX - 正常大小无衬线字体。


CV_FONT_HERSHEY_PLAIN - 小号无衬线字体。


CV_FONT_HERSHEY_DUPLEX - 正常大小无衬线字体。( 比CV_FONT_HERSHEY_SIMPLEX更复杂)


CV_FONT_HERSHEY_COMPLEX - 正常大小有衬线字体。


CV_FONT_HERSHEY_TRIPLEX - 正常大小有衬线字体 ( 比CV_FONT_HERSHEY_COMPLEX更复杂)


CV_FONT_HERSHEY_COMPLEX_SMALL - CV_FONT_HERSHEY_COMPLEX 的小译本。


CV_FONT_HERSHEY_SCRIPT_SIMPLEX - 手写风格字体。


CV_FONT_HERSHEY_SCRIPT_COMPLEX - 比CV_FONT_HERSHEY_SCRIPT_SIMPLEX更复杂。


这个参数能够由一个值和可选择的CV_FONT_ITALIC字体标记合成,就是斜体字。


hscale


字体宽度。如果等于1.0f,字符的宽度是最初的字体宽度。如果等于0.5f,字符的宽度是最初的字体宽度的一半。


vscale


字体高度。如果等于1.0f,字符的高度是最初的字体高度。如果等于0.5f,字符的高度是最初的字体高度的一半。


shear


字体的斜度。当值为0时,字符不倾斜;当值为1.0f时,字体倾斜≈45度,等等。厚度让字母着重显示。函数cvLine用于绘制字母。


thickness


字体笔划的粗细程度。


line_type


字体笔划的类型,参见cvLine。


函数cvInitFont初始化字体结构体,字体结构体可以被传递到文字显示函数中。


 


PutText


在图像中显示文本字符串。


void cvPutText( CvArr* img, const char* text, CvPoint org, const CvFont* font, CvScalar color );


img


输入图像。


text


要显示的字符串。


org


第一个字符左下角的坐标。


font


字体结构体。


color


文本的字体颜色。


函数cvPutText将具有指定字体的和指定颜色的文本加载到图像中。加载到图像中的文本被感兴趣的矩形框(ROI rectangle)剪切。不属于指定字体库的字符用矩形字符替代显示。 


 


GetTextSize


获得字符串的宽度和高度。


void cvGetTextSize( const char* text_string, const CvFont* font, CvSize* text_size, int* baseline );


font


字体结构体


text_string


输入字符串。


text_size


合成字符串的字符的大小。文本的高度不包括基线以下的部分。


baseline


相对于文字最底部点的基线的Y坐标。


函数cvGetTextSize是用于在指定字体时计算字符串的绑定区域(binding rectangle)。


 


点集和轮廓


 


DrawContours


在图像中绘制外部和内部的轮廓。


void cvDrawContours( CvArr *img, CvSeq* contour,


CvScalar external_color, CvScalar hole_color,


int max_level, int thickness=1,


int line_type=8, CvPoint offset=cvPoint(0,0) );


img


用以绘制轮廓的图像。和其他绘图函数一样,边界图像被感兴趣区域(ROI)所剪切。


contour


指针指向第一个轮廓。


external_color


外层轮廓的颜色。


hole_color


内层轮廓的颜色。


max_level


绘制轮廓的最大等级。如果等级为0,绘制单独的轮廓。如果为1,绘制轮廓及在其后的相同的级别下轮廓。如果值为2,所有的轮廓。如果等级为2,绘制所有同级轮廓及所有低一级轮廓,诸此种种。如果值为负数,函数不绘制同级轮廓,但会升序绘制直到级别为abs(max_level)-1的子轮廓。


thickness


绘制轮廓时所使用的线条的粗细度。如果值为负(e.g. =CV_FILLED),绘制内层轮廓。


line_type


线条的类型。参考cvLine.


offset


按照给出的偏移量移动每一个轮廓点坐标.当轮廓是从某些感兴趣区域(ROI)中提取的然后需要在运算中考虑ROI偏移量时,将会用到这个参数。


当thickness>=0,函数cvDrawContours在图像中绘制轮廓,或者当thickness<0时,填充轮廓所限制的区域。


#include "cv.h"


#include "highgui.h"


 


int main( int argc, char** argv )


{


IplImage* src;


// 第一条命令行参数确定了图像的文件名。


if( argc == 2 && (src=cvLoadImage(argv[1], 0))!= 0)


{


IplImage* dst = cvCreateImage( cvGetSize(src), 8, 3 );


CvMemStorage* storage = cvCreateMemStorage(0);


CvSeq* contour = 0;


 


cvThreshold( src, src, 1, 255, CV_THRESH_BINARY );


cvNamedWindow( "Source", 1 );


cvShowImage( "Source", src );


 


cvFindContours( src, storage, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );


cvZero( dst );


 


for( ; contour != 0; contour = contour->h_next )


{


CvScalar color = CV_RGB( rand()&255, rand()&255, rand()&255 );


 


cvDrawContours( dst, contour, color, color, -1, CV_FILLED, 8 );


}


 


cvNamedWindow( "Components", 1 );


cvShowImage( "Components", dst );


cvWaitKey(0);


}


}


在样本中用1替代 CV_FILLED 以指示的得到外形。


(注意:在cvFindContours中参数为CV_CHAIN_CODE时,cvDrawContours用CV_FILLED时不会画出任何图形)


 


InitLineIterator


初始化直线迭代器


int cvInitLineIterator( const CvArr* image, CvPoint pt1, CvPoint pt2,


CvLineIterator* line_iterator, int connectivity=8,


int left_to_right=0 );


img


用以获取直线的图像。


pt1


线段的第一个端点。


pt2


线段的第二个端点。


line_iterator


指向直线迭代状态结构体的指针。


connectivity


直线的邻接方式,4邻接或者8邻接。


left_to_right


标志值,指出扫描直线是从pt1和pt2外面最左边的点扫描到最右边的点(left_to_right≠0),还是按照指定的顺序,从pt1到pt2(left_to_right=0)。


函数cvInitLineIterator初始化直线迭代器并返回两个端点间点的数目。两个端点都必须在图像内部。在迭代器初始化以后,所有的在连接两个终点的栅栏线上的点,可以通过访问CV_NEXT_LINE_POINT点的方式获得。在线上的这些点使用4-邻接或者8-邻接的Bresenham算法计算得到。


例:使用直线迭代来计算沿着彩色线上的点的像素值。


CvScalar sum_line_pixels( IplImage* image, CvPoint pt1, CvPoint pt2 )


{


CvLineIterator iterator;


int blue_sum = 0, green_sum = 0, red_sum = 0;


int count = cvInitLineIterator( image, pt1, pt2, &iterator, 8, 0 );


 


for( int i = 0; i < count; i++ ){


blue_sum += iterator.ptr[0];


green_sum += iterator.ptr[1];


red_sum += iterator.ptr[2];


CV_NEXT_LINE_POINT(iterator);


 


 


{


int offset, x, y;


 


offset = iterator.ptr - (uchar*)(image->imageData);


y = offset/image->widthStep;


x = (offset - y*image->widthStep)/(3*sizeof(uchar) );


printf("(%d,%d)\n", x, y );


}


}


return cvScalar( blue_sum, green_sum, red_sum );


}


 


 


ClipLine


剪切图像矩形区域内部的直线。


int cvClipLine( CvSize img_size, CvPoint* pt1, CvPoint* pt2 );


img_size


图像的大小。


pt1


线段的第一个端点,会被函数修改。


pt2


线段的第二个端点,会被函数修改。


函数cvClipLine计算线段完全在图像中的一部分。如果线段完全在图像中,返回0,否则返回1。


 


Ellipse2Poly


用折线逼近椭圆弧


int cvEllipse2Poly( CvPoint center, CvSize axes,


int angle, int arc_start,


int arc_end, CvPoint* pts, int delta );


center


弧线的中心。


axes


弧线的Half-sizes。参见下图。


angle


椭圆的旋转角度(Rotation angle),参见下图。


start_angle


椭圆的Starting angle,参见下图。


end_angle


椭圆的Ending angle,参见下图。


pts


坐标点矩阵数组,由本函数填充。


delta


与下一条折线定点的夹角,近似精度。故,得到的点数最大为ceil((end_angle - start_angle)/delta) + 1。


函数cvEllipse2Poly计算给定的椭圆弧的逼近折线的顶点,被cvEllipse使用。



 





你可能感兴趣的:(OpenCV学习笔记之CXCORE篇)