enCV之CXCORE篇 (2)



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

 

变换和置换

Reshape

不拷贝数据修改矩阵/图像形状

CvMat* cvReshape( const CvArr* arr, CvMat* header, int new_cn, int new_rows=0 );

arr

输入的数组.

header

被添充的矩阵头

new_cn

新的通道数.new_cn = 0 意味着不修改通道数

new_rows

新的行数. 如果new_rows = 0保持原行数不修改否则根据 new_cn 值修改输出数组

函数 cvReshape 初始化 CvMat 头header 以便于让头指向修改后的形状(但数据保持原样)-也就是说修改通道数,修改行数或者两者者改变.

例如, 接下来的代码创建一个图像缓存、两个图像头,第一个是 320x240x3 图像第二个是 960x240x1 图像:

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

下一个例子转换3x3 矩阵成单向量 1x9

CvMat* mat = cvCreateMat( 3, 3, CV_32F );

CvMat row_header, *row;

row = cvReshape( mat, &row_header, 0, 1 );

ReshapeMatND

修改多维数组形状,拷贝/不拷贝数据

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

arr

输入数组

sizeof_header

输出头的大小,对于IplImage, CvMat 和 CvMatND 各种结构输出的头均是不同的.

header

被添充的输出头.

new_cn

新的通道数,如果new_cn = 0 则通道数保持原样

new_dims

新的维数. 如果new_dims = 0 则维数保持原样。

new_sizes

新的维大小.只有当 new_dims=1值被使用,因为要保持数组的总数一致,因此如果 new_dims = 1, new_sizes 是不被使用的

函数cvReshapeMatND 是 cvReshape 的高级版本,它可以处理多维数组(能够处理通用的图像和矩阵)并且修改维数,下面的是使用cvReshapeMatND重写 cvReshape的二个例子 :

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

 

...

 

 

int size[] = { 2, 2, 2 };

CvMatND* mat = cvCreateMatND( 3, size, CV_32F );

CvMat row_header, *row;

row = cvReshapeND( mat, &row_header, 0, 1, 0 );

Repeat

用原数组管道式添充输出数组

void cvRepeat( const CvArr* src, CvArr* dst );

src

输入数组, 图像或矩阵。

dst

输出数组,图像或矩阵

函数cvRepeat 使用被管道化的原数组添充输出数组:

dst(i,j)=src(i mod rows(src), j mod cols(src))

因此,输出数组可能小于也可能大于输入数组.

Flip

垂直,水平或即垂直又水平翻转二维数组

void cvFlip( const CvArr* src, CvArr* dst=NULL, int flip_mode=0);

#define cvMirror cvFlip

 

src

原数组.

dst

目标责任制数组. 如果 dst = NULL 翻转是在内部替换.

flip_mode

指定怎样去翻转数组。

flip_mode = 0 沿X-轴翻转, flip_mode > 0 (如 1) 沿Y-轴翻转, flip_mode < 0 (如 -1) 沿X-轴和Y-轴翻转.见下面的公式

函数cvFlip 以三种方式之一翻转数组 (行和列下标是以0为基点的):

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

函数主要使用在:

· 垂直翻转图像(flip_mode = 0)用于 顶-左和底-左图像结构的转换, 主要用于WIN32系统下的视频操作处理.

· 水平图像转换,使用连续的水平转换和绝对值差检查垂直轴对称(flip_mode > 0)

· 水平和垂直同时转换,用于连续的水平转换和绝对真理值差检查中心对称s(flip_mode < 0)

· 翻转1维指针数组的顺序(flip_mode > 0)

Split

分割多通道数组成几个单通道数组或者从数组中提取一个通道

void cvSplit( const CvArr* src, CvArr* dst0, CvArr* dst1,

CvArr* dst2, CvArr* dst3 );

#define cvCvtPixToPlane cvSplit

src

原数组.

dst0...dst3

目标通道

函数 cvSplit 分割多通道数组成分离的单通道数组d。可获得两种操作模式 . 如果原数组有N通道且前N输出数组非NULL, 所有的通道都会被从原数组中提取,如果前N个通道只有一个通道非NULL函数只提取该指定通道,否则会产生一个错误,馀下的通道(超过前N个通道的以上的)必须被设置成NULL,对于设置了COI的IplImage 结使用cvCopy 也可以从图像中提取单通道。

Merge

从几个单通道数组组合成多通道数组或插入一个单通道数组

void cvMerge( const CvArr* src0, const CvArr* src1,

const CvArr* src2, const CvArr* src3, CvArr* dst );

#define cvCvtPlaneToPix cvMerge

src0... src3

输入的通道.

dst

输出数组.

函数cvMerge 是前一个函数的反向操作。如果输出数组有N个通道并且前N个输入通道非NULL,就拷贝所有通道到输出数组,如果在前N个通道中只有一个单通道非NULL ,只拷贝这个通道到输出数组,否则 就会产生错误。除前N通道以外的馀下的通道必须置NULL。对于设置了COI的 IplImage结构使用 cvCopy也可以实现向图像中插入一个通道 。

MixChannels

拷贝输入数组的若干个通道到输出数组的某些通道上面.

void cvMixChannels( const CvArr** src, int src_count,

CvArr** dst, int dst_count,

const int* from_to, int pair_count );

src

输入数组

src_count

输入数组的个数

dst

输出数组

dst_count

输出数组的个数

from_to

对数的阵列

pair_count

from_to里面的对数的个数,或者说被拷贝的位面的个数.

RandShuffle

随机交换数组的元素

void cvRandShuffle( CvArr* mat, CvRNG* rng, double iter_factor=1.);

mat

输入的矩阵,用来被随机处理.

rng

随机数产生器用来随机交换数组元素.如果为NULL,一个当前的随机数发生器将被创建与使用.

iter_factor

相关的参数,用来刻划交换操作的密度.请看下面的说明.

这个函数在每个反复的操作中交换随机选择的矩阵里面的元素(在多通道的数组里面每个元素可能包括若干个部分),反复的次数(也就是交换的对数)等于round(iter_factor*rows(mat)*cols(mat)), 因此如果iter_factor=0,没有交换产生,如果等于1意味着随机交换了rows(mat)*cols(mat)对数.

算术,逻辑和比较

LUT

利用查找表转换数组

void cvLUT( const CvArr* src, CvArr* dst, const CvArr* lut );

src

元素为8位的原数组。

dst

与原数组有相同通道数的输出数组,深度不确定

lut

有256个元素的查找表;必须要与原输出数组有相同像深。

函数cvLUT 使用查找表中的值添充输出数组. 坐标入口来自于原数组,也就是说函数处理每个元素按如下方式:

dst(I)=lut[src(I)+DELTA]

这里当src的深度是CV_8U时DELTA=0 ,src的深度是CV_8S时 DELTA=128

ConvertScale

使用线性变换转换数组

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 )

src

输入数组.

dst

输出数组

scale

比例因子.

shift

该加数被加到输入数组元素按比例缩放后得到的元素上

函数 cvConvertScale 有多个不同的目的因此就有多个同义函数(如上面的#define所示)。该函数首先对输入数组的元素进行比例缩放,然后将shift加到比例缩放后得到的各元素上,即: dst(I)=src(I)*scale + (shift,shift,...),最后可选的类型转换将结果拷贝到输出数组。

多通道的数组对各个通道是独立处理的。

类型转换主要用舍入和溢出截断来完成。也就是如果缩放+转换后的结果值不能用输出数组元素类型值精确表达,就设置成在输出数组数据轴上最接近该数的值。

如果 scale=1, shift=0 就不会进行比例缩放. 这是一个特殊的优化,相当于该函数的同义函数名:cvConvert 。如果原来数组和输出数组的类型相同,这是另一种特殊情形,可以被用于比例缩放和平移矩阵或图像,此时相当于该函数的同义函数名:cvScale。

ConvertScaleAbs

使用线性变换转换输入数组元素成8位无符号整型

void cvConvertScaleAbs( const CvArr* src, CvArr* dst, double scale=1, double shift=0 );

#define cvCvtScaleAbs cvConvertScaleAbs

src

原数组

dst

输出数组 (深度为 8u).

scale

比例因子.

shift

原数组元素按比例缩放后添加的值。

函数 cvConvertScaleAbs 与前一函数是相同的,但它是存贮变换结果的绝对值:

dst(I)=abs(src(I)*scale + (shift,shift,...))

函数只支持目标数数组的深度为 8u (8-bit 无符号) , 对于别的类型函数仿效于cvConvertScale 和 cvAbs 函数的联合

Add

计算两个数组中每个元素的和

void cvAdd( const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL );

src1

第一个原数组

src2

第二个原数组

dst

输出数组

mask

操作的复盖面, 8-bit单通道数组; 只有复盖面指定的输出数组被修改。

函数 cvAdd 加一个数组到别一个数组中:

dst(I)=src1(I)+src2(I) if mask(I)!=0

除复盖面外所有的数组必须有相同的类型相同的大小(或ROI尺寸)。

AddS

计算数量和数组的和

void cvAddS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL );

src

原数组.

value

被加入数量

dst

输出数组

mask

操作的复盖面(8-bit单通道数组) ; 只有复盖面指定的输出数组被修改

函数 cvAddS 用数量值与原数组src1的每个元素想加并存贮结果到

dst(I)=src(I)+value if mask(I)!=0

除复盖面外所有数组都必须有相同的类型,相同的大小(或ROI大小)

AddWeighted

计算两数组的加权值的和

void cvAddWeighted( const CvArr* src1, double alpha,

const CvArr* src2, double beta,

double gamma, CvArr* dst );

src1

第一个原数组.

alpha

第一个数组元素的权值

src2

第二个原数组

beta

第二个数组元素的权值

dst

输出数组

gamma

添加的常数项。

函数 cvAddWeighted 计算两数组的加权值的和:

dst(I)=src1(I)*alpha+src2(I)*beta+gamma

所有的数组必须有相同的类型相同的大小(或ROI大小)

Sub

计算两个数组每个元素的差

void cvSub( const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL );

src1

第一个原数组

src2

第二个原数组.

dst

输出数组.

mask

操作复盖面( 8-bit 单通道数组); 只有复盖面指定的输出数组被修改

函数cvSub 从一个数组减去别一个数组:

dst(I)=src1(I)-src2(I) if mask(I)!=0

除复盖面外所有数组都必须有相同的类型,相同的大小(或ROI大小)

SubS

计算数组和数量之间的差

void cvSubS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL );

src

原数组.

value

被减的数量.

dst

输出数组.

mask

操作复盖面( 8-bit 单通道数组); 只有复盖面指定的输出数组被修改

函数 cvSubS 从原数组的每个元素中减去一个数量:

dst(I)=src(I)-value if mask(I)!=0

除复盖面外所有数组都必须有相同的类型,相同的大小(或ROI大小)。

SubRS

计算数量和数组之间的差

void cvSubRS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL );

src

第一个原数组。

value

被减的数量

dst

输出数组

mask

操作复盖面( 8-bit 单通道数组); 只有复盖面指定的输出数组被修改

函数 cvSubRS 从一个数量减去原数组的每个元素:

dst(I)=value-src(I) if mask(I)!=0

除复盖面外所有数组都必须有相同的类型,相同的大小(或ROI大小)。

Mul

计算两个数组中每个元素的积

void cvMul( const CvArr* src1, const CvArr* src2, CvArr* dst, double scale=1 );

src1

第一个原数组.

src2

第二个原数组.

dst

输出数组.

scale

设置的比例因子

函数 cvMul 计算两个数组中每个元素的积:

dst(I)=scale•src1(I)•src2(I)

所有的数组必须有相同的类型和相同的大小(或ROI大小)

Div

两个数组每个元素相除

void cvDiv( const CvArr* src1, const CvArr* src2, CvArr* dst, double scale=1 );

src1

第一个原数组。如该指针为NULL,假高该数组的所有元素都为1

src2

第二个原数组。

dst

输出数组

scale

设置的比例因子

函数 cvDiv 用一个数组除以另一个数组:

dst(I)=scale•src1(I)/src2(I), if src1!=NULL

dst(I)=scale/src2(I),: if src1=NULL

所有的数组必须有相同的类型和相同的大小(或ROI大小)

And

计算两个数组的每个元素的按位与

void cvAnd( const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL );

src1

第一个原数组

src2

第二个原数组.

dst

输出数组

mask

操作复盖面( 8-bit 单通道数组); 只有复盖面指定的输出数组被修改

函数 cvAnd 计算两个数组的每个元素的按位逻辑与:

dst(I)=src1(I)&src2(I) if mask(I)!=0

对浮点数组按位表示操作是很有利的。除复盖面,所有数组都必须有相同的类型,相同的大小(或ROI大小)。

AndS

计算数组每个元素与数量之间的按位与

void cvAndS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL );

src

原数组.

value

操作中用到的数量

dst

输出数组

mask

操作复盖面( 8-bit 单通道数组); 只有复盖面指定的输出数组被修改

函数 AndS 计算数组中每个元素与数量之量的按位与:

dst(I)=src(I)&value if mask(I)!=0

在实际操作之前首先把数量类型转换成与数组相同的类型。对浮点数组按位表示操作是很有利的。除复盖面,所有数组都必须有相同的类型,相同的大小(或ROI大小)。

接下来的例子描述怎样计算浮点数组元素的绝对值,通过清除最前面的符号位:

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

代码结果是:

1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0

Or

计算两个数组每个元素的按位或

void cvOr( const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL );

src1

第一个原数组

src2

第二个原数组

dst

输出数组.

mask

操作复盖面( 8-bit 单通道数组); 只有复盖面指定的输出数组被修改

函数 cvOr 计算两个数组每个元素的按位或:

dst(I)=src1(I)|src2(I)

对浮点数组按位表示操作是很有利的。除复盖面,所有数组都必须有相同的类型,相同的大小(或ROI大小)。

OrS

计算数组中每个元素与数量之间的按位或

void cvOrS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL );

src1

原数组

value

操作中用到的数量

dst

目数组.

mask

操作复盖面( 8-bit 单通道数组); 只有复盖面指定的输出数组被修改

函数 OrS 计算数组中每个元素和数量之间的按位或:

dst(I)=src(I)|value if mask(I)!=0

在实际操作之前首先把数量类型转换成与数组相同的类型。对浮点数组按位表示操作是很有利的。除复盖面,所有数组都必须有相同的类型,相同的大小(或ROI大小)。

Xor

计算两个数组中的每个元素的按位异或

void cvXor( const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=NULL );

src1

第一个原数组

src2

第二个原数组.

dst

输出数组

mask

操作复盖面( 8-bit 单通道数组); 只有复盖面指定的输出数组被修改

函数 cvXor 计算两个数组元素的按位异或:

dst(I)=src1(I) src2(I) if mask(I)!=0

对浮点数组按位表示操作是很有利的。除复盖面,所有数组都必须有相同的类型,相同的大小(或ROI大小)。

XorS

计算数组元素与数量之间的按位异或

void cvXorS( const CvArr* src, CvScalar value, CvArr* dst, const CvArr* mask=NULL );

src

原数组

value

操作中用到的数量

dst

输出数组.

mask

操作复盖面( 8-bit 单通道数组); 只有复盖面指定的输出数组被修改。

函数 XorS 计算数组元素与数量之间的按位异或:

dst(I)=src(I) value if mask(I)!=0

在实际操作之前首先把数量类型转换成与数组相同的类型。对浮点数组按位表示操作是很有利的。除复盖面,所有数组都必须有相同的类型,相同的大小(或ROI大小)。

下面例子描述怎样对共轭复数向量转换,通过转换前面的符号位:

float a[] = { 1, 0, 0, 1, -1, 0, 0, -1 };

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)

Not

计算数组元素的按位取反

void cvNot( const CvArr* src, CvArr* dst );

src1

原数组

dst

输出数组

函数不取反每个数组元素的每一位

dst(I)=~src(I)

Cmp

比较两个数组元素P

void cvCmp( const CvArr* src1, const CvArr* src2, CvArr* dst, int cmp_op );

src1

第一个原数组

src2

第二个原数组,这两个数组必须都是单通道数据。

dst

输出数组必须是 8u 或 8s 类型.

cmp_op

该标识指定要检查的元素之间的关系:

CV_CMP_EQ - src1(I) "等于" src2(I)

CV_CMP_GT - src1(I) "大于" src2(I)

CV_CMP_GE - src1(I) "大于等于" src2(I)

CV_CMP_LT - src1(I) "小于" src2(I)

CV_CMP_LE - src1(I) "小于等于" src2(I)

CV_CMP_NE - src1(I) "不等于" src2(I)

函数 cvCmp 比较两个数组的对应元素并且添充输出数组:

dst(I)=src1(I) op src2(I),

这里 op 是 '=', '>', '>=', '<', '<=' or '!='.

如果元素之间的关系为真则设置dst(I)为 0xff (也就是所有的位都为 '1') 否则为0。除了输出数组所有数组必须是相同的类型相同的大小(或ROI大小)。

CmpS

比较数组的每个元素与数量的关系

void cvCmpS( const CvArr* src, double value, CvArr* dst, int cmp_op );

src

原数,输入数组必须是单通道数据。

value

用与数组元素比较的数量值

dst

输出数组必须是 8u 或 8s 类型.

cmp_op

该标识指定要检查的元素之间的关系:

CV_CMP_EQ - src1(I) "等于" value

CV_CMP_GT - src1(I) "大于" value

CV_CMP_GE - src1(I) "大于等于" value

CV_CMP_LT - src1(I) "小于" value

CV_CMP_LE - src1(I) "小于等于" value

CV_CMP_NE - src1(I) "不等于" value

函数 cvCmpS 比较数组元素与数量并且添充目标复盖面数组:

dst(I)=src(I) op scalar,

这里 op 是 '=', '>', '>=', '<', '<=' or '!='.

如果元素之间的关系为真则设置dst(I)为 0xff (也就是所有的位都为 '1') 否则为0。所有的数组必须有相同的大小(或ROI大小)

InRange

检查数组元素是否在两个数组之间

void cvInRange( const CvArr* src, const CvArr* lower, const CvArr* upper, CvArr* dst );

src

第一个原数组

lower

包括进的下边界数组

upper

不包括进的上边界线数组

dst

输出数组必须是 8u 或 8s 类型.

函数 cvInRange 对输入的数组作范围检查,对于单通道数组:

dst(I)=lower(I)0 <= src(I)0 < upper(I)0

对二通道数组:

dst(I)=lower(I)0 <= src(I)0 < upper(I)0 &&

lower(I)1 <= src(I)1 < upper(I)1

以此类推

如果 src(I) 在范围内dst(I)被设置为 0xff (每一位都是 '1')否则置0 。除了输出数组所有数组必须是相同的类型相同的大小(或ROI大小)。

InRangeS

检查数组元素是否在两个数量之间

void cvInRangeS( const CvArr* src, CvScalar lower, CvScalar upper, CvArr* dst );

src

第一个原数组

lower

包括进的下边界.

upper

不包括进的上边界

dst

输出数组必须是 8u 或 8s 类型.

函数 cvInRangeS 检查输入数组元素范围:对于单通道数组:

dst(I)=lower0 <= src(I)0 < upper0

对于双通道数组以此类推:

dst(I)=lower0 <= src(I)0 < upper0 &&

lower1 <= src(I)1 < upper1

如果 src(I) 在范围内dst(I)被设置为 0xff (每一位都是 '1')否则置0 。所有的数组必须有相同的大小(或ROI大小)

Max

查找两个数组中每个元素的较大值

void cvMax( const CvArr* src1, const CvArr* src2, CvArr* dst );

src1

第一个原数组

src2

第二个原数组

dst

输出数组

函数 cvMax 计算两个数组中每个元素的较大值:

dst(I)=max(src1(I), src2(I))

所有的数组必须的一个单通道,相同的数据类型和相同的大小(或ROI大小)

MaxS

查找数组元素与数量之间的较大值

void cvMaxS( const CvArr* src, double value, CvArr* dst );

src

第一个原数组.

value

数量值.

dst

输出数组

函数 cvMaxS 计算数组元素和数量之间的较大值:

dst(I)=max(src(I), value)

所有数组必须有一个单一通道,相同的数据类型相同的大小(或ROI大小)

 

 

Min

查找两个数组元素之间的较小值

void cvMin( const CvArr* src1, const CvArr* src2, CvArr* dst );

src1

第一个原数组

src2

第二个原数组.

dst

输出数组.

函数cvMin计算两个数组元素的较小值

dst(I)=min(src1(I),src2(I))

所有数组必须有一个单一通道,相同的数据类型相同的大小(或ROI大小)

MinS

查找数组元素和数量之间的较小值

void cvMinS( const CvArr* src, double value, CvArr* dst );

src

第一个原数组

value

数量值.

dst

输出数组..

函数 cvMinS 计算数组元素和数量之量的较小值:

dst(I)=min(src(I), value)

所有数组必须有一个单一通道,相同的数据类型相同的大小(或ROI大小)

 

AbsDiff

计算两个数组差的绝对值

void cvAbsDiff( const CvArr* src1, const CvArr* src2, CvArr* dst );

src1

第一个原数组

src2

第二个原数组

dst

输出数组

函数 cvAbsDiff 计算两个数组差的绝对值

dst(I)c = abs(src1(I)c - src2(I)c).

所有数组必须有相同的数据类型相同的大小(或ROI大小)

 

AbsDiffS

计算数组元素与数量之间差的绝对值

void cvAbsDiffS( const CvArr* src, CvArr* dst, CvScalar value );

#define cvAbs(src, dst) cvAbsDiffS(src, dst, cvScalarAll(0))

src

原数组.

dst

输出数组

value

数量.

函数 cvAbsDiffS 计算数组元素与数量之间差的绝对值

dst(I)c = abs(src(I)c - valuec).

所有数组必须有相同的数据类型相同的大小(或ROI大小)

 

统计

 

CountNonZero

计算非零数组元素个数

int cvCountNonZero( const CvArr* arr );

arr

数组, 必须是单通道数组或者设置COI(感兴趣通道)的多通道图像。

函数 cvCountNonZero 返回arr中非零元素的数目:

result = sumI arr(I)!=0

当IplImage 支持ROI和COI。

Sum

计算数组元素的和

CvScalar cvSum( const CvArr* arr );

arr

数组.

函数 cvSum 独立地为每一个通道计算数组元素的和 S :

Sc = sumI arr(I)c

如果数组是IplImage类型和设置了COI, 该函数只处理选定的通道并将和存储到第一个标量成员 (S0)。常见论坛讨论贴 cvSum的结果分析

 

Avg

计算数组元素的平均值

CvScalar cvAvg( const CvArr* arr, const CvArr* mask=NULL );

arr

数组.

mask

可选操作掩模

函数 cvAvg 独立地为每一个通道计算数组元素的平均值 M :

如果数组是 IplImage 类型和设置 COI , 该函数只处理选定的通道并将和存储到第一个标量成员 (S0)。

 

 

AvgSdv

计算数组元素的平均值和标准差

void cvAvgSdv( const CvArr* arr, CvScalar* mean, CvScalar* std_dev, const CvArr* mask=NULL );

arr

数组

mean

指向平均值的指针,如果不需要的话可以为空( NULL)。

std_dev

指向标准差的指针。

mask

可选操作掩模。

函数 cvAvgSdv 独立地为每一个通道计算数组元素的平均值和标准差:

如果数组是 IplImage 类型和设置了COI ,该函数只处理选定的通道并将平均值和标准差存储到第一个输出标量成员 (mean0 和 std-dev0)。

MinMaxLoc

查找数组和子数组的全局最小值和最大值

void cvMinMaxLoc( const CvArr* arr, double* min_val, double* max_val,

CvPoint* min_loc=NULL, CvPoint* max_loc=NULL, const CvArr* mask=NULL );

arr

输入数组, 单通道或者设置了 COI 的多通道。

min_val

指向返回的最小值的指针。

max_val

指向返回的最大值的指针。

min_loc

指向返回的最小值的位置指针。

max_loc

指向返回的最大值的位置指针。

mask

选择一个子数组的操作掩模。

函数 MinMaxLoc 查找元素中的最小值和最大值以及他们的位置。函数在整个数组、或选定的ROI区域(对IplImage)或当MASK不为NULL时指定的数组区域中,搜索极值。如果数组不止一个通道,它就必须是设置了 COI 的 IplImage 类型。 如果是多维数组 min_loc->x 和 max_loc->x 将包含极值的原始位置信息 (线性的)。

 

Norm

计算数组的绝对范数,绝对差分范数或者相对差分范数

double cvNorm( const CvArr* arr1, const CvArr* arr2=NULL, int norm_type=CV_L2, const CvArr* mask=NULL );

arr1

第一输入图像

arr2

第二输入图像 ,如果为空(NULL), 计算 arr1 的绝对范数,否则计算 arr1-arr2 的绝对范数或者相对范数。

normType

范数类型,参见“讨论”。

mask

可选操作掩模。

如果 arr2 为空(NULL),函数 cvNorm 计算 arr1 的绝对范数:

norm = ||arr1||C = maxI abs(arr1(I)), 如果 normType = CV_C

norm = ||arr1||L1 = sumI abs(arr1(I)), 如果 normType = CV_L1

norm = ||arr1||L2 = sqrt( sumI arr1(I)2), 如果 normType = CV_L2


如果 arr2 不为空(NULL), 该函数计算绝对差分范数或者相对差分范数:

norm = ||arr1-arr2||C = maxI abs(arr1(I)-arr2(I)), 如果 normType = CV_C

norm = ||arr1-arr2||L1 = sumI abs(arr1(I)-arr2(I)), 如果 normType = CV_L1

norm = ||arr1-arr2||L2 = sqrt( sumI (arr1(I)-arr2(I))2 ), 如果 normType = CV_L2

或者

norm = ||arr1-arr2||C/||arr2||C, 如果 normType = CV_RELATIVE_C

norm = ||arr1-arr2||L1/||arr2||L1, 如果 normType = CV_RELATIVE_L1

norm = ||arr1-arr2||L2/||arr2||L2, 如果 normType = CV_RELATIVE_L2

函数 Norm 返回计算所得的范数。多通道数组被视为单通道处理,因此,所有通道的结果是结合在一起的。

 

Reduce

简化一个矩阵成为一个向量

cvReduce( const CvArr* src, CvArr* dst, int dim, int op=CV_REDUCE_SUM);

src

输入矩阵

dst

输出的通过处理输入矩阵的所有行/列而得到的单行/列向量

dim

矩阵被简化后的维数索引.0意味着矩阵被处理成一行,1意味着矩阵被处理成为一列,-1时维数将根据输出向量的大小自动选择.

op

简化操作的方式,可以有以下几种取值:

CV_REDUCE_SUM-输出是矩阵的所有行/列的和.

CV_REDUCE_AVG-输出是矩阵的所有行/列的平均向量.

CV_REDUCE_MAX-输出是矩阵的所有行/列的最大值.

CV_REDUCE_MIN-输出是矩阵的所有行/列的最小值.

这个函数通过把矩阵的每行/列当作一维向量并对其做某种特殊的操作将一个矩阵简化成为一个向量.例如,这个函数可以用于计算一个光栅图象的水平或者垂直投影.在取值为CV_REDUCE_AVG与CV_REDUCE_SUM的情况下输出可能有很大的位深度用于维持准确性,这两种方式也适合于处理多通道数组.

注意,对于CV_REDUCE_SUM和CV_REDUCE_AVG方式来说,输入和输出的位数定义有如下关系

输入:CV_8U 输出:CV_32S CV_32F

输入:CV_16U 输出:CV_32F CV_64F

输入:CV_16S 输出:CV_32F CV_64F

输入:CV_32F 输出: CV_32F CV_64F

输入:CV_64F 输出: CV_64F

而对于CV_REDUCE_MAX和CV_REDUCE_MIN方式来说,输入和输出的位数必须一致

线性代数

DotProduct

用欧几里得准则计算两个数组的点积

double cvDotProduct( const CvArr* src1, const CvArr* src2 );

src1

第一输入数组。

src2

第二输入数组。

函数 cvDotProduct 计算并返回两个数组的欧几里得点积。

src1•src2 = sumI(src1(I)*src2(I))

如果是多通道数组,所有通道的结果是累加在一起的。特别地, cvDotProduct(a,a),将返回 ||a||2 ,这里 a 是一个复向量。该函数可以处理多通道数组,逐行或逐层等等。

Normalize

根据某种范数或者数值范围归一化数组.

void cvNormalize( const CvArr* src, CvArr* dst,

double a=1, double b=0, int norm_type=CV_L2,

const CvArr* mask=NULL );

src

输入数组

dst

输出数组,支持原地运算

a

输出数组的最小/最大值或者输出数组的范数

b

输出数组的最大/最小值

norm_type

归一化的类型,可以有以下的取值:

CV_C - 归一化数组的C-范数(绝对值的最大值)

CV_L1 - 归一化数组的L1-范数(绝对值的和)

CV_L2 - 归一化数组的(欧几里德)L2-范数

CV_MINMAX - 数组的数值被平移或缩放到一个指定的范围

mask

操作掩膜,用于指示函数是否仅仅对指定的元素进行操作

该函数归一化输入数组使它的范数或者数值范围在一定的范围内

当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) otherwise

其中b'=MAX(a,b), a'=MIN(a,b);

当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

下面是一个简单的例子: 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 );

 

CrossProduct

计算两个三维向量的叉积

void cvCrossProduct( const CvArr* src1, const CvArr* src2, CvArr* dst );

src1

第一输入向量。

src2

第二输入向量。

dst

输出向量

函数 cvCrossProduct 计算两个三维向量的差积:

dst = src1 × src2, (dst1 = src12src23 - src13src22 , dst2 = src13src21 - src11src23 , dst3 = src11src22 - src12src21).

 

ScaleAdd

计算一个数组缩放后与另一个数组的和

void cvScaleAdd( const CvArr* src1, CvScalar scale, const CvArr* src2, CvArr* dst );

#define cvMulAddS cvScaleAdd

src1

第一输入数组

scale

第一输入数组的缩放因子

src2

第二输入数组

dst

输出数组

函数 cvScaleAdd 计算一个数组缩放后与另一个数组的和:

dst(I)=src1(I)*scale + src2(I)

所有的数组参数必须有相同的类型和大小。

 

GEMM

通用矩阵乘法

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 )

src1

第一输入数组

src2

第二输入数组

src3

第三输入数组 (偏移量),如果没有偏移量,可以为空( NULL) 。

dst

输出数组

tABC

T操作标志,可以是 0 或者下面列举的值的组合:

CV_GEMM_A_T - 转置 src1

CV_GEMM_B_T - 转置 src2

CV_GEMM_C_T - 转置 src3

例如, CV_GEMM_A_T+CV_GEMM_C_T 对应

alpha*src1T*src2 + beta*src3T

函数 cvGEMM 执行通用矩阵乘法:

dst = alpha*op(src1)*op(src2) + beta*op(src3), 这里 op(X) 是 X 或者 XT

所有的矩阵应该有相同的数据类型和协调的矩阵大小。支持实数浮点矩阵或者复数浮点矩阵。

 

Transform

对数组每一个元素执行矩阵变换

void cvTransform( const CvArr* src, CvArr* dst, const CvMat* transmat, const CvMat* shiftvec=NULL );

src

输入数组

dst

输出数组

transmat

变换矩阵

shiftvec

可选偏移向量

函数 cvTransform 对数组 src 每一个元素执行矩阵变换并将结果存储到 dst:

dst(I)=transmat*src(I) + shiftvec

或者

dst(I)k=sumj(transmat(k,j)*src(I)j) + shiftvec(k)

N-通道数组 src 的每一个元素都被视为一个N元向量,使用一个 M×N 的变换矩阵 transmat 和偏移向量 shiftvec 把它变换到一个 M-通道的数组 dst 的一个元素中。 这里可以选择将偏移向量 shiftvec 嵌入到 transmat 中。这样的话 transmat 应该是 M×(N+1) 的矩阵,并且最右边的一列被看作是偏移向量 。

输入数组和输出数组应该有相同的位深(depth)和同样的大小或者 ROI 大小。 transmat 和 shiftvec 应该是实数浮点矩阵。

该函数可以用来进行 ND 点集的几何变换,任意的线性颜色空间变换,通道转换等。

 

PerspectiveTransform

向量数组的透视变换

void cvPerspectiveTransform( const CvArr* src, CvArr* dst, const CvMat* mat );

src

输入的三通道浮点数组

dst

输出三通道浮点数组

mat

4 × 4 变换矩阵

函数 cvPerspectiveTransform 用下面的方式变换 src 的每一个元素 (通过将其视为二维或者三维的向量):

(x, y, z) -> (x'/w, y'/w, z'/w)

或者

(x, y) -> (x'/w, y'/w),

这里

(x', y', z', w') = mat*(x, y, z, 1)

或者

(x', y', w') = mat*(x, y, 1)

并且 w = w' 如果 w'!=0, 否则 w = inf

 

MulTransposed

计算数组和数组的转置的乘积

void cvMulTransposed( const CvArr* src, CvArr* dst, int order, const CvArr* delta=NULL );

src

输入矩阵

dst

目标矩阵

order

乘法顺序

delta

一个可选数组, 在乘法之前从 src 中减去该数组。

函数 cvMulTransposed 计算 src 和它的转置的乘积。

函数求值公式:

如果 order=0

dst=(src-delta)*(src-delta)T

否则

dst=(src-delta)T*(src-delta)

 

Trace

返回矩阵的迹

CvScalar cvTrace( const CvArr* mat );

mat

输入矩阵

函数 cvTrace 返回矩阵mat的对角线元素的和。

 

Transpose

矩阵的转置

void cvTranspose( const CvArr* src, CvArr* dst );

#define cvT cvTranspose

src

输入矩阵

dst

目标矩阵

函数 cvTranspose 对矩阵 src 求转置:

dst(i,j)=src(j,i)

注意,假设是复数矩阵不会求得复数的共轭。共轭应该是独立的:查看的 cvXorS 例子代码。

 

Det

返回矩阵的行列式值

double cvDet( const CvArr* mat );

mat

输入矩阵

函数 cvDet 返回方阵 mat 的行列式值。对小矩阵直接计算,对大矩阵用高斯(GAUSSIAN)消去法。对于对称正定(positive-determined)矩阵也可以用 SVD 函数来求,U=V=NULL ,然后用 w 的对角线元素的乘积来计算行列式。

 

Invert

查找矩阵的逆矩阵或伪逆矩阵

double cvInvert( const CvArr* src, CvArr* dst, int method=CV_LU );

#define cvInv cvInvert

src

输入矩阵

dst

目标矩阵

method

求逆方法:

CV_LU -最佳主元选取的高斯消除法

CV_SVD - 奇异值分解法 (SVD)

CV_SVD_SYM - 正定对称矩阵的 SVD 方法

函数 cvInvert 对矩阵 src 求逆并将结果存储到 dst。

如果是 LU 方法该函数返回 src 的行列式值 (src 必须是方阵)。 如果是 0, 矩阵不求逆, dst 用 0 填充。

如果 SVD 方法该函数返回 src 的条件数的倒数(最小奇异值和最大奇异值的比值) ,如果 src 全为 0 则返回0。 如果 src 是奇异的, SVD 方法计算一个伪逆矩阵。

 

Solve

求解线性系统或者最小二乘法问题

int cvSolve( const CvArr* src1, const CvArr* src2, CvArr* dst, int method=CV_LU );

src1

输入矩阵

src2

线性系统的右部

dst

输出解答

method

解决方法(矩阵求逆) :

CV_LU - 最佳主元选取的高斯消除法

CV_SVD - 奇异值分解法 (SVD)

CV_SVD_SYM - 对正定对称矩阵的 SVD 方法

函数 cvSolve 解决线性系统或者最小二乘法问题 (后者用 SVD 方法可以解决):

 

如果使用 CV_LU 方法。 如果 src1 是非奇异的,该函数则返回 1 ,否则返回 0 ,在后一种情况下 dst 是无效的。

 

SVD

对实数浮点矩阵进行奇异值分解

void cvSVD( CvArr* A, CvArr* W, CvArr* U=NULL, CvArr* V=NULL, int flags=0 );

A

M×N 的输入矩阵

W

结果奇异值矩阵 (M×N 或者 N×N) 或者 向量 (N×1).

U

可选的左部正交矩阵 (M×M or M×N). 如果 CV_SVD_U_T 被指定, 应该交换上面所说的行与列的数目。

V

可选右部正交矩阵(N×N)

flags

操作标志; 可以是 0 或者下面的值的组合:

· CV_SVD_MODIFY_A 通过操作可以修改矩阵 src1 。这样处理速度会比较快。

· CV_SVD_U_T 意味着会返回转置矩阵 U ,指定这个标志将加快处理速度。

· CV_SVD_V_T 意味着会返回转置矩阵 V ,指定这个标志将加快处理速度。

函数 cvSVD 将矩阵 A 分解成一个对角线矩阵和两个正交矩阵的乘积:

 

这里 W 是一个奇异值的对角线矩阵,它可以被编码成奇异值的一维向量,U 和 V 也是一样。 所有的奇异值都是非负的并按降序存储。(U 和 V 也相应的存储)。

SVD 算法在数值处理上已经很稳定,它的典型应用包括:

· 当 A 是一个方阵、对称阵和正矩阵时精确的求解特征值问题,例如, 当 A 时一个协方差矩阵时。在这种情况下 W 将是一个特征值的的向量,并且 U=V是矩阵的特征向量(因此,当需要计算特征向量时 U 和 V 只需要计算其中一个就可以了) 。

· 精确的求解病态线性系统。

· 超定线性系统的最小二乘求解。上一个问题和这个问题都可以用指定 CV_SVD 的 cvSolve 方法。

· 精确计算矩阵的不同特征,如秩(非零奇异值的数目), 条件数(最大奇异值和最小奇异值的比例), 行列式值(行列式的绝对值等于奇异值的乘积).上述的所有这些值都不要求计算矩阵 U 和 V 。

SVBkSb

奇异值回代算法(back substitution)

void cvSVBkSb( const CvArr* W, const CvArr* U, const CvArr* V,

const CvArr* B, CvArr* X, int flags );

W

奇异值矩阵或者向量

U

左正交矩阵 (可能是转置的)

V

右正交矩阵 (可能是转置的)

B

原始矩阵 A 的伪逆的乘法矩阵。这个是可选参数。如果它被省略则假定它是一个适当大小的单位矩阵(因此 x 将是 A 的伪逆的重建).。

X

目标矩阵: 奇异值回代算法的结果

flags

操作标志, 和刚刚讨论的 cvSVD 的标志一样。

函数 cvSVBkSb 为被分解的矩阵 A 和矩阵 B 计算回代逆(back substitution) (参见 cvSVD 说明) :

X=V*W-1*UT*B

这里

W-1(i,i)=1/W(i,i) 如果 W(i,i) > epsilon•sumiW(i,i),

否则:0.

epsilon 是一个依赖于矩阵数据类型的的很小的数。该函数和 cvSVD 函数被用来执行 cvInvert 和 cvSolve, 用这些函数 (svd & bksb)的原因是初级函数(low-level) 函数可以避免高级函数 (inv & solve) 计算中内部分配的临时矩阵。

 

 

EigenVV

计算对称矩阵的特征值和特征向量

void cvEigenVV( CvArr* mat, CvArr* evects, CvArr* evals, double eps=0 );

mat

输入对称方阵。在处理过程中将被改变。

evects

特征向量输出矩阵,连续按行存储

evals

特征值输出矩阵,按降序存储(当然特征值和特征向量的排序是同步的)。

eps

对角化的精确度 (典型地, DBL_EPSILON=≈10-15 就足够了)。

函数 cvEigenVV 计算矩阵 A 的特征值和特征向量:

mat*evects(i,:)' = evals(i)*evects(i,:)' (在 MATLAB 的记法)

矩阵 A 的数据将会被这个函数修改。

目前这个函数比函数 cvSVD 要慢,精确度要低, 如果已知 A 是正定的,(例如, 它是一个协方差矩阵), 它通常被交给函数 cvSVD 来计算其特征值和特征向量,尤其是在不需要计算特征向量的情况下

 

 

CalcCovarMatrix

计算向量集合的协方差矩阵

void cvCalcCovarMatrix( const CvArr** vects, int count, CvArr* cov_mat, CvArr* avg, int flags );

vects

输入向量。他们必须有同样的数据类型和大小。这个向量不一定非是一维的,他们也可以是二维(例如,图像)等等。

count

输入向量的数目

cov_mat

输出协方差矩阵,它是浮点型的方阵。

avg

输入或者输出数组 (依赖于标记“flags”) - 输入向量的平均向量。

flags

操作标志,下面值的组合:

CV_COVAR_SCRAMBLED - 输出协方差矩阵按下面计算:

scale * [vects[0] − avg,vects[1] − avg,...]T * [vects[0] − avg,vects[1] − avg,...], 即协方差矩阵是 count×count. 这样一个不寻常的矩阵用于一组大型向量的快速PCA方法(例如, 人脸识别的 EigenFaces 技术)。这个混杂("scrambled")矩阵的特征值将和真正的协方差矩阵的特征值匹配,真正的特征向量可以很容易的从混杂("scrambled")协方差矩阵的特征向量中计算出来。

CV_COVAR_NORMAL - 输出协方差矩阵被计算成:

scale * [vects[0] − avg,vects[1] − avg,...] * [vects[0] − avg,vects[1] − avg,...]T, 也就是说, cov_mat 将是一个和每一个输入向量的元素数目具有同样线性大小的通常协方差矩阵。 CV_COVAR_SCRAMBLED 和 CV_COVAR_NORMAL 只能同时指定其中一个。

CV_COVAR_USE_AVG - 如果这个标志被指定, 该函数将不会从输入向量中计算 avg ,而是用过去的 avg 向量,如果 avg 已经以某种方式计算出来了这样做是很有用的。或者如果协方差矩阵是部分计算出来的 - 倘若这样, avg 不是输入向量的子集的平均值,而是整个集合的平均向量。

CV_COVAR_SCALE - 如果这个标志被指定,协方差矩阵被缩放了。 the covariation matrix is scaled.在 "normal" 模式下缩放比例是 1./count, 在 "scrambled" 模式下缩放比例是每一个输入向量的元素总和的倒数。缺省地(如果没有指定标志) 协方差矩阵不被缩放 (scale=1)。

函数 cvCalcCovarMatrix 计算输入向量的协方差矩阵和平均向量。该函数可以被运用到主成分分析中(PCA),以及马氏距离(Mahalanobis distance)比较向量中等等。

 

Mahalanobis

计算两个向量之间的马氏距离(Mahalanobis distance)

double cvMahalanobis( const CvArr* vec1, const CvArr* vec2, CvArr* mat );

vec1

第一个一维输入向量

vec2

第二个一维输入向量

mat

协方差矩阵的逆矩阵

函数 cvMahalanobis 计算两个向量之间的加权距离,其返回结果是:

协方差矩阵可以用函数cvCalcCovarMatrix 计算出来,逆矩阵可以用函数 cvInvert 计算出来 (CV_SVD 方法是一个比较好的选择, 因为矩阵可能是奇异的).

 

 

CalcPCA

对一个向量集做PCA变换

void cvCalcPCA( const CvArr* data, CvArr* avg,

CvArr* eigenvalues, CvArr* eigenvectors, int flags );

data

输入数据,每个向量是单行向量(CV_PCA_DATA_AS_ROW)或者单列向量(CV_PCA_DATA_AS_COL).

avg

平均向量,在函数内部计算或者由调用者提供

eigenvalues

输出的协方差矩阵的特征值

eigenvectors

输出的协方差矩阵的特征向量(也就是主分量),每个向量一行

flags

操作标志,可以是以下几种方式的组合:

CV_PCA_DATA_AS_ROW - 向量以行的方式存放(也就是说任何一个向量都是连续存放的)

CV_PCA_DATA_AS_COL - 向量以列的方式存放(也就是说某一个向量成分的数值是连续存放的)

(上面两种标志是互相排斥的)

CV_PCA_USE_AVG - 使用预先计算好的平均值

该函数对某个向量集做PCA变换.它首先利用cvCalcCovarMatrix计算协方差矩阵然后计算协方差矩阵的特征值与特征向量.输出的特征值/特征向量的个数小于或者等于MIN(rows(data),cols(data)).

 

ProjectPCA

把向量向某个子空间投影

void cvProjectPCA( const CvArr* data, const CvArr* avg,

const CvArr* eigenvectors, CvArr* result )

data

输入数据,每个向量可以是单行或者单列

avg

平均向量.要么它是单行向量那么意味着输入数据以行数据的形式存放,要么就是单列向量,那么就意味着那么输入向量就是以列的方式存放.

eigenvectors

特征向量(主分量),每个向量一行.

result

输出的分解系数矩阵,矩阵的行数必须与输入向量的个数相等,矩阵的列数必须小于特征向量的行数.

该函数将输入向量向一个正交系(eigenvectors)投影.在计算点乘之前,输入向量要减去平均向量:

result(i,:)=(data(i,:)-avg)*eigenvectors' // for CV_PCA_DATA_AS_ROW layout.

 

BackProjectPCA

根据投影系数重构原来的向量

void cvBackProjectPCA( const CvArr* proj, const CvArr* avg,

const CvArr* eigenvects, CvArr* result );

proj

输入数据,与cvProjectPCA里面的格式一致

avg

平均向量.如果它是单行向量,那么意味着输出向量是以行的方式存放.否则就是单列向量,那么输出向量就是以列的方式存放.

eigenvectors

特征向量(主分量),每个向量一行.

result

输出的重构出来的矩阵

该函数根据投影系数重构原来的向量:

result(i,:)=proj(i,:)*eigenvectors + avg // for CV_PCA_DATA_AS_ROW layout.

 

 

数学函数

 

Round, Floor, Ceil

转换浮点数为整数

int cvRound( double value );

int cvFloor( double value );

int cvCeil( double value );

value

输入浮点值

函数 cvRound, cvFloor, cvCeil 用一种舍入方法将输入浮点数转换成整数。 cvRound 返回和参数最接近的整数值。 cvFloor 返回不大于参数的最大整数值。cvCeil 返回不小于参数的最小整数值。在某些体系结构中该函数 工作起来比标准 C 操作起来还要快。如果参数的绝对值大于 231 ,结果是不可预料的。对特殊值 (±Inf, NaN) 未进行处理。

 

Sqrt

计算平方根

float cvSqrt( float value );

value

输入浮点值

函数 cvSqrt 计算输入值的平方根。如果输入的是复数, 结果将不可预料。

 

InvSqrt

计算平方根的倒数

float cvInvSqrt( float value );

value

输入浮点值

函数 cvInvSqrt 计算输入值的平方根的倒数,大多数情况下它比 1./sqrt(value) 要快。 如果输入的是 0 或者复数,结果将不可预料。特别值 (±Inf, NaN) 是不可控制的。

 

Cbrt

计算立方根

float cvCbrt( float value );

value

输入浮点值

函数 cvCbrt 计算输入值的立方根,大多数情况下它比 pow(value,1./3) 要快。 另外, 负数也是可操作的。特别值 (±Inf, NaN) 是不可控制的。

 

FastArctan

计算二维向量的角度

float cvFastArctan( float y, float x );

x

二维向量的 x 坐标

y

二维向量的 y 坐标

函数 cvFastArctan 计算二维向量的全范围角度角度, 变化范围是 0°到 360°。 精确度为 ~0.1° 。

 

IsNaN

判断输入是否是一个数字

int cvIsNaN( double value );

value

输入浮点值

函数 cvIsNaN 发现输入是一个数字则返回 1 ( IEEE754 标准 ),否则返回 0 。

 

IsInf

判断输入是否是无穷大

int cvIsInf( double value );

value

输入浮点值

函数 cvIsInf 如果输入是 ±Infinity ( IEEE754 标准 )则返回 1 ,否则返回 0 .

 

CartToPolar

计算二维向量的长度和/或者角度

void cvCartToPolar( const CvArr* x, const CvArr* y, CvArr* magnitude,

CvArr* angle=NULL, int angle_in_degrees=0 );

x

x 坐标数组

y

y 坐标数组

magnitude

存储向量长度输出数组,如果不是必要的它可以为空(NULL)

angle

存储角度输出数组, 如果不是必要的它可以为空(NULL)。它可以被标准化为弧度 (0..2π) 或者度数(0..360°)

所有的数组只支持浮点类型的运算,也即x,y,magnitude,angle必须是浮点类型的数组。

angle_in_degrees

指示角度是用弧度或者度数表示的标志,缺省模式为弧度

函数 cvCartToPolar 计算二维向量(x(I),y(I))的长度,角度,或者两者同时计算:

magnitude(I) = sqrt(x(I)2 + y(I)2),

 

angle(I) = atan(y(I) / x(I))

角度的精确度 ≈0.1°. (0,0) 点的角度被设置为 0.

(建议:英文文档虽然是写成atan( y(I)/x(I) ),但是建议和C中的表达方式统一。atan不能识别在那个象限,只能返回0-180°,atan2(x,y)才能返回0-360°的值)

 

PolarToCart

计算极坐标形式的二维向量对应的直角坐标

void cvPolarToCart( const CvArr* magnitude, const CvArr* angle,

CvArr* x, CvArr* y, int angle_in_degrees=0 );

magnitude

长度数组.如果为空(NULL),长度被假定为全是 1's.

angle

角度数组,弧度或者角度表示.

x

输出 x 坐标数组, 如果不需要,可以为空(NULL).

y

输出 y 坐标数组, 如果不需要,可以为空(NULL).

angle_in_degrees

指示角度是用弧度或者度数表示的标志,缺省模式为弧度

函数 cvPolarToCart 计算每个向量magnitude(I)*exp(angle(I)*j), j=sqrt(-1)的 x 坐标,y 坐标或者两者都计算:

x(I)=magnitude(I)*cos(angle(I)),

y(I)=magnitude(I)*sin(angle(I))

 

Pow

对数组内每个元素求幂

void cvPow( const CvArr* src, CvArr* dst, double power );

src

输入数组

dst

输出数组, 应该和输入数组有相同的类型

power

幂指数

函数 cvPow 计算输入数组的每个元素的 p 次幂:

dst(I)=src(I)^p, 如果p是整数

否则dst(I)=abs(src(I))^p

也就是说,对于非整型的幂指数使用输入数组元素的绝对值进行计算。然而,使用一些额外的操作,负值也可以得到正确的结果,象下面的例子,计算数组元素的立方根:

CvSize size = cvGetSize(src);

CvMat* mask = cvCreateMat( size.height, size.width, CV_8UC1 );

cvCmpS( src, 0, mask, CV_CMP_LT );

cvPow( src, dst, 1./3 );

cvSubRS( dst, cvScalarAll(0), dst, mask );

cvReleaseMat( &mask );

对于一些幂值, 例如整数值, 0.5 和 -0.5, 优化算法被使用。

 

Exp

计算数组元素的指数幂

void cvExp( const CvArr* src, CvArr* dst );

src

输入数组

dst

输出数组, 它应该是 double 型的或者和输入数组有相同的类型

函数 cvExp 计算输入数组的每个元素的 e 次幂:

dst(I)=exp(src(I))

最大相对误差为 ≈7e-6. 通常, 该函数转换无法输出的值为 0 输出。

 

Log

计算每个数组元素的绝对值的自然对数

void cvLog( const CvArr* src, CvArr* dst );

src

输入数组。

dst

输出数组,它应该是 double 型的或者和输入数组有相同的类型。

函数 cvLog 计算输入数组每个元素的绝对值的自然对数:

dst(I)=log(abs(src(I))), src(I)!=0

dst(I)=C, src(I)=0

这里 C 是一个大负数 (≈-700 现在的实现中)。

 

SolveCubic

求解曲线函数的实根

void cvSolveCubic( const CvArr* coeffs, CvArr* roots );

coeffs

等式系数, 一个三到四个元素的数组.

roots

输出的矩阵等式的实根。它应该具有三个元素.

函数 cvSolveCubic 求解曲线函数的实根:

coeffs[0]*x^3 + coeffs[1]*x^2 + coeffs[2]*x + coeffs[3] = 0

(如果coeffs是四元素的矢量)

或者

x^3 + coeffs[0]*x^2 + coeffs[1]*x + coeffs[2] = 0

(如果coeffs是三元素的矢量)

函数返回求解得到的实根数目. 实根被存储在矩阵root中, 如果只有一个实根则用0来替代相关值.

随机数生成

RNG

初始化随机数生成器状态

CvRNG cvRNG( int64 seed=-1 );

seed

64-bit 的值用来初始化一个随机序列

函数 cvRNG 初始化随机数生成器并返回其状态。指向这个状态的指针可以传递给函数 cvRandInt, cvRandReal 和 cvRandArr . 在通常的实现中使用一个 multiply-with-carry generator 。

 

RandArr

用随机数填充数组并更新 RNG 状态

void cvRandArr( CvRNG* rng, CvArr* arr, int dist_type, CvScalar param1, CvScalar param2 );

rng

被 cvRNG 初始化的 RNG 状态.

arr

输出数组

dist_type

分布类型:

CV_RAND_UNI - 均匀分布

CV_RAND_NORMAL - 正态分布 或者 高斯分布

param1

分布的第一个参数。如果是均匀分布它是随机数范围的闭下边界。如果是正态分布它是随机数的平均值。

param2

分布的第二个参数。如果是均匀分布它是随机数范围的开上边界。如果是正态分布它是随机数的标准差。

函数 cvRandArr 用均匀分布的或者正态分布的随机数填充输出数组。在下面的例子中该函数被用来添加一些正态分布的浮点数到二维数组的随机位置。

 

CvRNG rng_state = cvRNG(0xffffffff);

int i, pointCount = 1000;

 

CvMat* locations = cvCreateMat( pointCount, 1, CV_32SC2 );

 

CvMat* values = cvCreateMat( pointCount, 1, CV_32FC1 );

CvSize size = cvGetSize( noisy_screen );

 

cvRandInit( &rng_state,

0, 1,

0xffffffff ,

CV_RAND_UNI );

 

 

cvRandArr( &rng_state, locations, CV_RAND_UNI, cvScalar(0,0,0,0), cvScalar(size.width,size.height,0,0) );

 

 

rng_state.disttype = CV_RAND_NORMAL;

cvRandSetRange( &rng_state,

30 ,

100 ,

-1 );

 

cvRandArr( &rng_state, values, CV_RAND_NORMAL,

cvRealScalar(100), // average intensity

cvRealScalar(30) // deviation of the intensity

);

 

 

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;

}

 

 

cvReleaseMat( &locations );

cvReleaseMat( &values );

 

 

 

RandInt

返回 32-bit 无符号整型并更新 RNG

unsigned cvRandInt( CvRNG* rng );

rng

被 cvRNG 初始化的 RNG 状态,被 RandSetRange (虽然, 后面这个函数对我们正讨论的函数的结果没有什么影响)随意地设置。

函数 cvRandInt 返回均匀分布的随机 32-bit 无符号整型值并更新 RNG 状态。它和 C 运行库里面的 rand() 函数十分相似,但是它产生的总是一个 32-bit 数而 rand() 返回一个 0 到 RAND_MAX (它是 2**16 或者 2**32, 依赖于操作平台)之间的数。

该函数用来产生一个标量随机数,例如点, patch sizes, table indices 等,用模操作可以产生一个确定边界的整数,人和其他特定的边界缩放到 0.. 1可以产生一个浮点数。下面是用 cvRandInt 重写的前一个函数讨论的例子:

 

CvRNG rng_state = cvRNG(0xffffffff);

int i, pointCount = 1000;

 

CvSize size = cvGetSize( noisy_screen );

 

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

 

pt.x = cvRandInt( &rng_state ) % size.width;

pt.y = cvRandInt( &rng_state ) % size.height;

 

if( valuesLeft <= 0 )

{

 

cvRandArr( &rng_state, &normalValueMat, CV_RAND_NORMAL, cvRealScalar(100), cvRealScalar(30) );

valuesLeft = bufferSize;

}

((float*)cvPtr2D( noisy_screen, pt.y, pt.x, 0 ) = normalValueBuffer[--valuesLeft];

}

 

 

 

RandReal

返回浮点型随机数并更新 RNG

double cvRandReal( CvRNG* rng );

rng

被 cvRNG 初始化的 RNG 状态

函数 cvRandReal 返回均匀分布的随机浮点数,范围在 0..1 之间 (不包括 1 )。

你可能感兴趣的:(enCV之CXCORE篇 (2))